fenghuo/packages/tus/src/utils/models/Metadata.ts

105 lines
2.9 KiB
TypeScript
Raw Normal View History

2025-05-28 22:16:02 +08:00
import type { Upload } from './Upload';
2025-05-27 16:56:50 +08:00
// 定义ASCII码中的空格和逗号字符的码点
2025-05-28 22:16:02 +08:00
const ASCII_SPACE = ' '.codePointAt(0);
const ASCII_COMMA = ','.codePointAt(0);
2025-05-27 16:56:50 +08:00
// 定义用于验证Base64字符串的正则表达式
2025-05-28 22:16:02 +08:00
const BASE64_REGEX = /^[\d+/A-Za-z]*={0,2}$/;
2025-05-27 16:56:50 +08:00
/**
*
* @param key
* @returns truefalse
*/
export function validateKey(key: string) {
2025-05-28 22:16:02 +08:00
// 如果键的长度为0则无效
if (key.length === 0) {
return false;
}
2025-05-27 16:56:50 +08:00
2025-05-28 22:16:02 +08:00
// 遍历键的每个字符,检查其码点是否在有效范围内
for (let i = 0; i < key.length; ++i) {
const charCodePoint = key.codePointAt(i) as number;
if (
charCodePoint > 127 || // 非ASCII字符
charCodePoint === ASCII_SPACE || // 空格字符
charCodePoint === ASCII_COMMA // 逗号字符
) {
return false;
}
}
2025-05-27 16:56:50 +08:00
2025-05-28 22:16:02 +08:00
return true;
2025-05-27 16:56:50 +08:00
}
/**
*
* @param value
* @returns Base64字符串则返回truefalse
*/
export function validateValue(value: string) {
2025-05-28 22:16:02 +08:00
// Base64字符串的长度必须是4的倍数
if (value.length % 4 !== 0) {
return false;
}
2025-05-27 16:56:50 +08:00
2025-05-28 22:16:02 +08:00
// 使用正则表达式验证Base64字符串的格式
return BASE64_REGEX.test(value);
2025-05-27 16:56:50 +08:00
}
/**
*
* @param str
* @returns
* @throws
*/
export function parse(str?: string) {
2025-05-28 22:16:02 +08:00
const meta: Record<string, string | null> = {};
2025-05-27 16:56:50 +08:00
2025-05-28 22:16:02 +08:00
// 如果字符串为空或仅包含空白字符,则无效
if (!str || str.trim().length === 0) {
throw new Error('Metadata string is not valid');
}
2025-05-27 16:56:50 +08:00
2025-05-28 22:16:02 +08:00
// 遍历字符串中的每个键值对
for (const pair of str.split(',')) {
const tokens = pair.split(' ');
const [key, value] = tokens;
// 验证键和值的有效性,并确保键在元数据对象中不存在
if (
key &&
((tokens.length === 1 && validateKey(key)) ||
(tokens.length === 2 && validateKey(key) && value && validateValue(value))) &&
!(key in meta)
) {
// 如果值存在则将其从Base64解码为UTF-8字符串
const decodedValue = value ? Buffer.from(value, 'base64').toString('utf8') : null;
meta[key] = decodedValue;
} else {
throw new Error('Metadata string is not valid');
}
}
2025-05-27 16:56:50 +08:00
2025-05-28 22:16:02 +08:00
return meta;
2025-05-27 16:56:50 +08:00
}
/**
*
* @param metadata
* @returns
*/
export function stringify(metadata: NonNullable<Upload['metadata']>): string {
2025-05-28 22:16:02 +08:00
return Object.entries(metadata)
.map(([key, value]) => {
// 如果值为null则仅返回键
if (value === null) {
return key;
}
2025-05-27 16:56:50 +08:00
2025-05-28 22:16:02 +08:00
// 将值编码为Base64字符串并与键组合
const encodedValue = Buffer.from(value, 'utf8').toString('base64');
return `${key} ${encodedValue}`;
})
.join(',');
}