66 lines
2.1 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

export const runtime = 'nodejs'
export function toCamelCaseKey(key: string): string {
return key.replace(/_([a-zA-Z])/g, (_, c: string) => c.toUpperCase());
}
export function toSnakeCaseKey(key: string): string {
return key.replace(/[A-Z]/g, (m) => `_${m.toLowerCase()}`);
}
/**
* 创建一个代理对象,使得读取属性时同时兼容 snake_case 与 camelCase 键名。
* 访问顺序:原名 -> camelCase -> snake_case
*/
export function createCamelCompatibleProxy<T extends object>(root: T): T {
const seen = new WeakMap<object, any>();
const wrap = (value: any): any => {
if (value === null || typeof value !== 'object') return value;
if (seen.has(value)) return seen.get(value);
const proxied = new Proxy(value, handler);
seen.set(value, proxied);
return proxied;
};
const handler: ProxyHandler<any> = {
get(target, prop, receiver) {
// 非字符串属性(如 Symbol、数字索引直接透传
if (typeof prop !== 'string') {
return wrap(Reflect.get(target, prop, receiver));
}
const primary = prop;
if (primary in target) return wrap(Reflect.get(target, primary, receiver));
const camel = toCamelCaseKey(primary);
if (camel in target) return wrap(Reflect.get(target, camel, receiver));
const snake = toSnakeCaseKey(primary);
if (snake in target) return wrap(Reflect.get(target, snake, receiver));
return wrap(Reflect.get(target, prop, receiver));
},
has(target, prop) {
if (typeof prop !== 'string') return prop in target;
const primary = prop === 'auther' ? 'autherInfo' : prop;
return (
primary in target ||
toCamelCaseKey(primary) in target ||
toSnakeCaseKey(primary) in target
);
}
};
return wrap(root);
}
/** 选择首个可用 URL */
export function pickFirstUrl(list?: string[]) {
return Array.isArray(list) && list.length ? list[0] : undefined;
}
// 别名,兼容旧命名
export const firstUrl = pickFirstUrl;