@cloudcome/utils-core 1.6.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/async.cjs +2 -2
- package/dist/async.cjs.map +1 -1
- package/dist/async.mjs +1 -1
- package/dist/async.mjs.map +1 -1
- package/dist/dict.cjs +56 -0
- package/dist/dict.cjs.map +1 -1
- package/dist/dict.d.ts +67 -0
- package/dist/dict.mjs +57 -1
- package/dist/dict.mjs.map +1 -1
- package/dist/{fn.cjs → function.cjs} +1 -1
- package/dist/function.cjs.map +1 -0
- package/dist/{fn.mjs → function.mjs} +1 -1
- package/dist/function.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/object/process.d.ts +15 -0
- package/dist/object.cjs +6 -0
- package/dist/object.cjs.map +1 -1
- package/dist/object.mjs +6 -0
- package/dist/object.mjs.map +1 -1
- package/dist/{qs.cjs → query.cjs} +1 -1
- package/dist/query.cjs.map +1 -0
- package/dist/{qs.mjs → query.mjs} +1 -1
- package/dist/query.mjs.map +1 -0
- package/dist/try/{tryCallback.d.ts → callback.d.ts} +1 -1
- package/dist/try/function.d.ts +5 -0
- package/dist/try/main.d.ts +7 -0
- package/dist/try/types.d.ts +1 -1
- package/dist/try.cjs +18 -18
- package/dist/try.cjs.map +1 -1
- package/dist/try.d.ts +2 -1
- package/dist/try.mjs +19 -19
- package/dist/try.mjs.map +1 -1
- package/dist/types.d.ts +8 -0
- package/package.json +13 -21
- package/dist/enum.cjs +0 -58
- package/dist/enum.cjs.map +0 -1
- package/dist/enum.d.ts +0 -68
- package/dist/enum.mjs +0 -58
- package/dist/enum.mjs.map +0 -1
- package/dist/fn.cjs.map +0 -1
- package/dist/fn.mjs.map +0 -1
- package/dist/qs.cjs.map +0 -1
- package/dist/qs.mjs.map +0 -1
- package/dist/try/const.d.ts +0 -2
- package/dist/try/index.d.ts +0 -7
- package/dist/try/tryFlatten.d.ts +0 -6
- package/dist/try/tryFunction.d.ts +0 -3
- /package/dist/{fn.d.ts → function.d.ts} +0 -0
- /package/dist/{qs.d.ts → query.d.ts} +0 -0
- /package/dist/try/{callbackCurry.d.ts → curry.d.ts} +0 -0
- /package/dist/try/{tryPromise.d.ts → promise.d.ts} +0 -0
package/dist/object.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object.mjs","sources":["../src/object/get-set.ts","../src/object/is.ts","../src/object/process.ts"],"sourcesContent":["import { isArray, isObject, isUndefined } from '@/type';\nimport type { AnyArray, AnyObject } from '@/types';\n\n// @ref https://stackoverflow.com/a/67609485\n\ntype Idx<T, K> = K extends keyof T\n ? T[K]\n : number extends keyof T\n ? K extends `${number}`\n ? T[number]\n : never\n : never;\n\ntype Join<K, P> = K extends string | number\n ? P extends string | number\n ? `${K}${'' extends P ? '' : '.'}${P}`\n : never\n : never;\n\ntype Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...0[]];\n\nexport type ObjectPath<O, D extends number = 4> = [D] extends [never]\n ? never\n : O extends object\n ? {\n [K in keyof O]-?: K extends string | number ? `${K}` | Join<K, ObjectPath<O[K], Prev[D]>> : never;\n }[keyof O]\n : '';\n\nexport type ObjectLeafPath<O, D extends number = 4> = [D] extends [never]\n ? never\n : O extends object\n ? {\n [K in keyof O]-?: K extends string | number\n ? O[K] extends string | number\n ? `${K}` | Join<K, ObjectLeafPath<O[K], Prev[D]>>\n : Join<K, ObjectLeafPath<O[K], Prev[D]>>\n : never;\n }[keyof O]\n : '';\n\nexport type ObjectPathValue<O, P extends ObjectPath<O, 4>> = P extends `${infer Key}.${infer Rest}`\n ? Rest extends ObjectPath<Idx<O, Key>, 4>\n ? ObjectPathValue<Idx<O, Key>, Rest>\n : never\n : Idx<O, P>;\n\nfunction pathToKeys(path: string | string[]) {\n // 下文用到该数组时会进行修改操作,因此复制一份\n if (isArray(path)) return [...path];\n\n let pathFinal = path.replace(/\\[(\\w+)\\]/g, '.$1');\n pathFinal = pathFinal.replace(/^\\./, '');\n return pathFinal.split('.');\n}\n\nfunction isObjectOrArray(v: unknown) {\n return isObject(v) || isArray(v);\n}\n\n/**\n * 表示对象节点的信息。\n *\n * @template V - 键值的类型。\n */\nexport type ObjectNode<V = unknown | undefined> = {\n /**\n * 当前节点的父级对象。\n */\n parent: unknown | undefined;\n\n /**\n * 当前节点的键名路径。\n */\n keys: string[];\n\n /**\n * 当前节点的键名。\n */\n key: string | undefined;\n\n /**\n * 当前节点的键值。\n */\n value: V;\n};\n\n/**\n * 根据属性路径获取属性值\n * @param {O} obj\n * @param {string | string[] | P} path\n * @returns {ObjectNode<O>}\n * 根据属性路径获取属性值。\n *\n * @template O - 目标对象的类型。\n * @template P - 属性路径的类型。\n * @param {O} obj - 要操作的目标对象。\n * @param {P | string | string[]} path - 属性路径,可以是字符串或字符串数组。支持点分隔符(如 \"a.b.c\")或数组形式(如 [\"a\", \"b\", \"c\"])。\n * @returns {ObjectNode<O>} 返回一个包含父级、键名路径、键名和键值的对象节点。\n *\n * @example\n * ```typescript\n * const obj = { a: { b: { c: 42 } } };\n * const result = objectGet(obj, 'a.b.c');\n * console.log(result.value); // 输出 42\n * ```\n */\nexport function objectGet<O extends AnyObject, P extends ObjectPath<O>>(\n obj: O,\n path: P | string | string[],\n): ObjectNode<O> {\n const keys = pathToKeys(path);\n const lastKey = keys.pop();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n let parent: any = obj;\n const keysFinal: string[] = [];\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n\n keysFinal.push(key);\n if (!isObjectOrArray(parent)) break;\n\n // @ts-ignore\n parent = parent[key];\n }\n\n return {\n parent: parent,\n keys: keysFinal,\n key: lastKey,\n // @ts-ignore\n value: isObjectOrArray(parent) && lastKey ? parent[lastKey] : undefined,\n };\n}\n\n// /**\n// * 根据路径获取对象叶子节点值\n// * @param {O} obj\n// * @param {P} path\n// * @returns {ObjectNode<O>}\n// */\n// export function objectLeaf<O extends AnyObject, P extends ObjectLeafPath<O>>(obj: O, path: P) {\n// return objectGet(obj, path);\n// }\n\n/**\n * 配置选项,用于控制 `objectSet` 的行为。\n *\n * @template O - 目标对象的类型。\n */\nexport type ObjectSetOptions<O extends AnyObject> = {\n /**\n * 在设置值之前调用的钩子函数。\n * 如果返回 `false`,则阻止设置值。\n *\n * @param {ObjectNode<O> & { key: string }} node - 当前节点信息。\n * @returns {boolean | undefined | void} 返回 `false` 时阻止设置值。\n */\n // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n beforeSet(node: ObjectNode<O> & { key: string }): boolean | undefined | void;\n\n /**\n * 当遇到未定义的中间节点时调用的钩子函数。\n * 返回值将用于创建中间节点。\n *\n * @param {ObjectNode<O>} node - 当前节点信息。\n * @returns {AnyObject | AnyArray | undefined | void} 返回值将用于创建中间节点。\n */\n // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n undefinedSet(node: ObjectNode<O>): AnyObject | AnyArray | undefined | void;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nconst defaultObjectSetOptions: ObjectSetOptions<any> = {\n beforeSet: () => true,\n undefinedSet: () => ({}),\n};\n\n/**\n * 根据属性路径设置属性值\n * @param {AnyObject} obj\n * @param {string} path\n * @param {V} val\n * @param {Partial<ObjectSetOptions<O>>} options\n * @returns {ObjectNode<O, V>}\n * 根据属性路径设置属性值。\n *\n * @template O - 目标对象的类型。\n * @template V - 要设置的值的类型。\n * @param {O} obj - 要操作的目标对象。\n * @param {string | string[]} path - 属性路径,可以是字符串或字符串数组。支持点分隔符(如 \"a.b.c\")或数组形式(如 [\"a\", \"b\", \"c\"])。\n * @param {V} val - 要设置的值。\n * @param {Partial<ObjectSetOptions<O>>} [options] - 可选配置项,用于控制设置行为。\n * @returns {ObjectNode<V>} 返回一个包含父级、键名路径、键名和键值的对象节点。\n *\n * @example\n * ```typescript\n * const obj = {};\n * objectSet(obj, 'a.b.c', 42);\n * console.log(obj); // 输出 { a: { b: { c: 42 } } }\n *\n * objectSet(obj, 'a.b.c', 100, {\n * beforeSet: (node) => node.key === 'c',\n * });\n * console.log(obj); // 输出 { a: { b: { c: 100 } } }\n * ```\n */\nexport function objectSet<O extends AnyObject, V>(\n obj: O,\n path: string | string[],\n val: V,\n options?: Partial<ObjectSetOptions<O>>,\n): ObjectNode<V> {\n const { beforeSet, undefinedSet } = Object.assign({}, defaultObjectSetOptions, options);\n const keys = pathToKeys(path);\n const lastKey = keys.pop();\n let parent = obj;\n let stopped = false;\n const keysFinal: string[] = [];\n\n for (const key of keys) {\n let val = parent[key];\n keysFinal.push(key);\n\n if (isUndefined(val)) {\n const seted = undefinedSet({\n parent: parent,\n keys: keysFinal,\n key: key,\n value: val,\n });\n\n if (!seted) {\n stopped = true;\n break;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n val = parent[key] = seted;\n }\n\n // @ts-ignore\n parent = val;\n }\n\n if (!stopped && !isUndefined(lastKey)) {\n keysFinal.push(lastKey);\n\n if (\n beforeSet({\n parent: parent,\n keys: keysFinal,\n key: lastKey,\n value: parent[lastKey],\n })\n ) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n parent[lastKey] = val;\n }\n }\n\n return {\n keys: keysFinal,\n parent: parent,\n key: lastKey,\n value: val,\n };\n}\n","import { isArray, isObject, isString, typeIs } from '@/type';\nimport type { AnyArray, AnyFunction, AnyObject } from '@/types';\n\n/**\n * 检查一个对象是否为空对象(不包含任何自有属性,包括符号属性)。\n *\n * @param obj - 要检查的对象\n * @returns 如果对象没有自有属性(包括符号属性)则返回 true,否则返回 false\n *\n * @example\n * ```typescript\n * isEmptyObject({}); // true\n * isEmptyObject({ a: 1 }); // false\n * isEmptyObject(Object.create(null)); // true\n * isEmptyObject({ [Symbol('key')]: 'value' }); // false\n * ```\n */\nexport function isEmptyObject(obj: AnyObject): boolean {\n return Object.getOwnPropertyNames(obj).length === 0 && Object.getOwnPropertySymbols(obj).length === 0;\n}\n\n/**\n * 检查一个对象是否为纯对象(通过对象字面量或Object构造函数创建,而非其他构造函数的实例)。\n *\n * @param obj - 要检查的对象\n * @returns 如果是纯对象则返回 true,否则返回 false\n *\n * @example\n * ```typescript\n * isPlainObject({}); // true\n * isPlainObject(Object.create(null)); // true\n * isPlainObject(new Date()); // false\n * isPlainObject([]); // false\n * isPlainObject(() => {}); // false\n * ```\n */\nexport function isPlainObject(obj: AnyObject): boolean {\n const proto: unknown = Object.getPrototypeOf(obj);\n\n // 对象无原型\n if (!proto) return true;\n\n // 是否对象直接实例\n return proto === Object.prototype;\n}\n\n// 移除,原因是,定义对象尽可能的使用 type 关键字即可避开此问题\n// /**\n// * 精确对象,常用于联合类型判断\n// * 相关 bug:https://l.ydr.me/Zp88vFKc\n// */\n// // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n// export type ExactObject<T = any> = T extends AnyFunction\n// ? never\n// : T extends AnyArray\n// ? never\n// : T extends object\n// ? T\n// : never;\n//\n// /**\n// * 检查值是否为精确接口对象\n// * @param object - 传入对象,必须是一个对象与其他类型的联合\n// * @returns 如果值为对象则返回 true,否则返回 false\n// * @example\n// * ```typescript\n// * type Id = string | string[] | (() => string);\n// *\n// * interface Cache {\n// * id?: Id;\n// * }\n// *\n// * type Share = {\n// * id?: Id;\n// * }\n// *\n// * interface Options {\n// * cache?: Id | Cache;\n// * share?: Id | Share;\n// * }\n// *\n// * function test(options: Options) {\n// * // string | string[] | (() => string) | Cache | undefined\n// * const cache = options.cache;\n// *\n// * // Cache\n// * // 需要使用\n// * if (isExactObject(cache)) {\n// * cache.id;\n// * }\n// * // string[]\n// * else if (isArray(cache)) {\n// * cache.push();\n// * }\n// * // string\n// * else if (isString(cache)) {\n// * cache.charCodeAt(0);\n// * }\n// * // (() => string) | undefined\n// * else {\n// * cache?.();\n// * }\n// *\n// * // string | string[] | (() => string) | Share | undefined\n// * const share = options.share;\n// *\n// * // Share\n// * if (isObject(share)) {\n// * share.id;\n// * }\n// * // string[]\n// * else if (isArray(share)) {\n// * share.push();\n// * }\n// * // string\n// * else if (isString(share)) {\n// * share.charCodeAt(0);\n// * }\n// * // (() => string) | undefined\n// * else {\n// * share?.();\n// * }\n// * }\n// * ```\n// */\n// export function isExactObject<T>(object: T): object is ExactObject<T> {\n// return typeIs(object) === 'object';\n// }\n","import type { AnyObject } from '@/types';\n\n/**\n * 从对象中选择指定键的属性,返回一个新的对象。\n *\n * @param object - 要从中选择属性的对象。\n * @param keys - 要选择的键数组。\n * @returns 包含指定键属性的新对象。\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: 2, c: 3 };\n * const result = objectPick(obj, ['a', 'c']);\n * console.log(result); // { a: 1, c: 3 }\n * ```\n */\nexport function objectPick<T extends AnyObject, K extends keyof T>(object: T, keys: K[]): Pick<T, K> {\n const result = {} as Pick<T, K>;\n for (const key of keys) {\n if (key in object) {\n result[key] = object[key];\n }\n }\n return result;\n}\n\n/**\n * 从对象中排除指定键的属性,返回一个新的对象。\n *\n * @param object - 要从中排除属性的对象。\n * @param keys - 要排除的键数组。\n * @returns 排除指定键属性后的新对象。\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: 2, c: 3, d: 4 };\n * const result = objectOmit(obj, ['a', 'd']);\n * console.log(result); // { b: 2, c: 3 }\n * ```\n */\nexport function objectOmit<T extends AnyObject, K extends keyof T>(object: T, keys: K[]): Omit<T, K> {\n const result = {} as Omit<T, K>;\n for (const key in object) {\n if (!keys.includes(key as unknown as K)) {\n // @ts-expect-error\n result[key] = object[key];\n }\n }\n return result;\n}\n\n/**\n * 遍历对象的每个键值对,并对每个键值对执行提供的映射函数,返回一个新的对象。\n *\n * @param object - 要遍历的对象。\n * @param mapper - 对每个键值对执行的映射函数。\n * @returns 返回一个新的对象,其中每个值都是通过映射函数处理后的结果。\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: 2, c: 3 };\n * const result = objectMap(obj, (val, key) => String(val * 2));\n * console.log(result); // { a: '2', b: '4', c: '6' }\n * ```\n */\nexport function objectMap<T extends AnyObject, V>(\n object: T,\n mapper: (value: T[keyof T], key: keyof T) => V,\n): Record<keyof T, V> {\n return Object.fromEntries(\n Object.entries(object).map(([key, value]) => [\n key,\n mapper(\n // @ts-expect-error\n value,\n key as keyof T,\n ),\n ]),\n ) as Record<keyof T, V>;\n}\n"],"names":["val"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"object.mjs","sources":["../src/object/get-set.ts","../src/object/is.ts","../src/object/process.ts"],"sourcesContent":["import { isArray, isObject, isUndefined } from '@/type';\nimport type { AnyArray, AnyObject } from '@/types';\n\n// @ref https://stackoverflow.com/a/67609485\n\ntype Idx<T, K> = K extends keyof T\n ? T[K]\n : number extends keyof T\n ? K extends `${number}`\n ? T[number]\n : never\n : never;\n\ntype Join<K, P> = K extends string | number\n ? P extends string | number\n ? `${K}${'' extends P ? '' : '.'}${P}`\n : never\n : never;\n\ntype Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...0[]];\n\nexport type ObjectPath<O, D extends number = 4> = [D] extends [never]\n ? never\n : O extends object\n ? {\n [K in keyof O]-?: K extends string | number ? `${K}` | Join<K, ObjectPath<O[K], Prev[D]>> : never;\n }[keyof O]\n : '';\n\nexport type ObjectLeafPath<O, D extends number = 4> = [D] extends [never]\n ? never\n : O extends object\n ? {\n [K in keyof O]-?: K extends string | number\n ? O[K] extends string | number\n ? `${K}` | Join<K, ObjectLeafPath<O[K], Prev[D]>>\n : Join<K, ObjectLeafPath<O[K], Prev[D]>>\n : never;\n }[keyof O]\n : '';\n\nexport type ObjectPathValue<O, P extends ObjectPath<O, 4>> = P extends `${infer Key}.${infer Rest}`\n ? Rest extends ObjectPath<Idx<O, Key>, 4>\n ? ObjectPathValue<Idx<O, Key>, Rest>\n : never\n : Idx<O, P>;\n\nfunction pathToKeys(path: string | string[]) {\n // 下文用到该数组时会进行修改操作,因此复制一份\n if (isArray(path)) return [...path];\n\n let pathFinal = path.replace(/\\[(\\w+)\\]/g, '.$1');\n pathFinal = pathFinal.replace(/^\\./, '');\n return pathFinal.split('.');\n}\n\nfunction isObjectOrArray(v: unknown) {\n return isObject(v) || isArray(v);\n}\n\n/**\n * 表示对象节点的信息。\n *\n * @template V - 键值的类型。\n */\nexport type ObjectNode<V = unknown | undefined> = {\n /**\n * 当前节点的父级对象。\n */\n parent: unknown | undefined;\n\n /**\n * 当前节点的键名路径。\n */\n keys: string[];\n\n /**\n * 当前节点的键名。\n */\n key: string | undefined;\n\n /**\n * 当前节点的键值。\n */\n value: V;\n};\n\n/**\n * 根据属性路径获取属性值\n * @param {O} obj\n * @param {string | string[] | P} path\n * @returns {ObjectNode<O>}\n * 根据属性路径获取属性值。\n *\n * @template O - 目标对象的类型。\n * @template P - 属性路径的类型。\n * @param {O} obj - 要操作的目标对象。\n * @param {P | string | string[]} path - 属性路径,可以是字符串或字符串数组。支持点分隔符(如 \"a.b.c\")或数组形式(如 [\"a\", \"b\", \"c\"])。\n * @returns {ObjectNode<O>} 返回一个包含父级、键名路径、键名和键值的对象节点。\n *\n * @example\n * ```typescript\n * const obj = { a: { b: { c: 42 } } };\n * const result = objectGet(obj, 'a.b.c');\n * console.log(result.value); // 输出 42\n * ```\n */\nexport function objectGet<O extends AnyObject, P extends ObjectPath<O>>(\n obj: O,\n path: P | string | string[],\n): ObjectNode<O> {\n const keys = pathToKeys(path);\n const lastKey = keys.pop();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n let parent: any = obj;\n const keysFinal: string[] = [];\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n\n keysFinal.push(key);\n if (!isObjectOrArray(parent)) break;\n\n // @ts-ignore\n parent = parent[key];\n }\n\n return {\n parent: parent,\n keys: keysFinal,\n key: lastKey,\n // @ts-ignore\n value: isObjectOrArray(parent) && lastKey ? parent[lastKey] : undefined,\n };\n}\n\n// /**\n// * 根据路径获取对象叶子节点值\n// * @param {O} obj\n// * @param {P} path\n// * @returns {ObjectNode<O>}\n// */\n// export function objectLeaf<O extends AnyObject, P extends ObjectLeafPath<O>>(obj: O, path: P) {\n// return objectGet(obj, path);\n// }\n\n/**\n * 配置选项,用于控制 `objectSet` 的行为。\n *\n * @template O - 目标对象的类型。\n */\nexport type ObjectSetOptions<O extends AnyObject> = {\n /**\n * 在设置值之前调用的钩子函数。\n * 如果返回 `false`,则阻止设置值。\n *\n * @param {ObjectNode<O> & { key: string }} node - 当前节点信息。\n * @returns {boolean | undefined | void} 返回 `false` 时阻止设置值。\n */\n // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n beforeSet(node: ObjectNode<O> & { key: string }): boolean | undefined | void;\n\n /**\n * 当遇到未定义的中间节点时调用的钩子函数。\n * 返回值将用于创建中间节点。\n *\n * @param {ObjectNode<O>} node - 当前节点信息。\n * @returns {AnyObject | AnyArray | undefined | void} 返回值将用于创建中间节点。\n */\n // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n undefinedSet(node: ObjectNode<O>): AnyObject | AnyArray | undefined | void;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nconst defaultObjectSetOptions: ObjectSetOptions<any> = {\n beforeSet: () => true,\n undefinedSet: () => ({}),\n};\n\n/**\n * 根据属性路径设置属性值\n * @param {AnyObject} obj\n * @param {string} path\n * @param {V} val\n * @param {Partial<ObjectSetOptions<O>>} options\n * @returns {ObjectNode<O, V>}\n * 根据属性路径设置属性值。\n *\n * @template O - 目标对象的类型。\n * @template V - 要设置的值的类型。\n * @param {O} obj - 要操作的目标对象。\n * @param {string | string[]} path - 属性路径,可以是字符串或字符串数组。支持点分隔符(如 \"a.b.c\")或数组形式(如 [\"a\", \"b\", \"c\"])。\n * @param {V} val - 要设置的值。\n * @param {Partial<ObjectSetOptions<O>>} [options] - 可选配置项,用于控制设置行为。\n * @returns {ObjectNode<V>} 返回一个包含父级、键名路径、键名和键值的对象节点。\n *\n * @example\n * ```typescript\n * const obj = {};\n * objectSet(obj, 'a.b.c', 42);\n * console.log(obj); // 输出 { a: { b: { c: 42 } } }\n *\n * objectSet(obj, 'a.b.c', 100, {\n * beforeSet: (node) => node.key === 'c',\n * });\n * console.log(obj); // 输出 { a: { b: { c: 100 } } }\n * ```\n */\nexport function objectSet<O extends AnyObject, V>(\n obj: O,\n path: string | string[],\n val: V,\n options?: Partial<ObjectSetOptions<O>>,\n): ObjectNode<V> {\n const { beforeSet, undefinedSet } = Object.assign({}, defaultObjectSetOptions, options);\n const keys = pathToKeys(path);\n const lastKey = keys.pop();\n let parent = obj;\n let stopped = false;\n const keysFinal: string[] = [];\n\n for (const key of keys) {\n let val = parent[key];\n keysFinal.push(key);\n\n if (isUndefined(val)) {\n const seted = undefinedSet({\n parent: parent,\n keys: keysFinal,\n key: key,\n value: val,\n });\n\n if (!seted) {\n stopped = true;\n break;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n val = parent[key] = seted;\n }\n\n // @ts-ignore\n parent = val;\n }\n\n if (!stopped && !isUndefined(lastKey)) {\n keysFinal.push(lastKey);\n\n if (\n beforeSet({\n parent: parent,\n keys: keysFinal,\n key: lastKey,\n value: parent[lastKey],\n })\n ) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n parent[lastKey] = val;\n }\n }\n\n return {\n keys: keysFinal,\n parent: parent,\n key: lastKey,\n value: val,\n };\n}\n","import { isArray, isObject, isString, typeIs } from '@/type';\nimport type { AnyArray, AnyFunction, AnyObject } from '@/types';\n\n/**\n * 检查一个对象是否为空对象(不包含任何自有属性,包括符号属性)。\n *\n * @param obj - 要检查的对象\n * @returns 如果对象没有自有属性(包括符号属性)则返回 true,否则返回 false\n *\n * @example\n * ```typescript\n * isEmptyObject({}); // true\n * isEmptyObject({ a: 1 }); // false\n * isEmptyObject(Object.create(null)); // true\n * isEmptyObject({ [Symbol('key')]: 'value' }); // false\n * ```\n */\nexport function isEmptyObject(obj: AnyObject): boolean {\n return Object.getOwnPropertyNames(obj).length === 0 && Object.getOwnPropertySymbols(obj).length === 0;\n}\n\n/**\n * 检查一个对象是否为纯对象(通过对象字面量或Object构造函数创建,而非其他构造函数的实例)。\n *\n * @param obj - 要检查的对象\n * @returns 如果是纯对象则返回 true,否则返回 false\n *\n * @example\n * ```typescript\n * isPlainObject({}); // true\n * isPlainObject(Object.create(null)); // true\n * isPlainObject(new Date()); // false\n * isPlainObject([]); // false\n * isPlainObject(() => {}); // false\n * ```\n */\nexport function isPlainObject(obj: AnyObject): boolean {\n const proto: unknown = Object.getPrototypeOf(obj);\n\n // 对象无原型\n if (!proto) return true;\n\n // 是否对象直接实例\n return proto === Object.prototype;\n}\n\n// 移除,原因是,定义对象尽可能的使用 type 关键字即可避开此问题\n// /**\n// * 精确对象,常用于联合类型判断\n// * 相关 bug:https://l.ydr.me/Zp88vFKc\n// */\n// // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n// export type ExactObject<T = any> = T extends AnyFunction\n// ? never\n// : T extends AnyArray\n// ? never\n// : T extends object\n// ? T\n// : never;\n//\n// /**\n// * 检查值是否为精确接口对象\n// * @param object - 传入对象,必须是一个对象与其他类型的联合\n// * @returns 如果值为对象则返回 true,否则返回 false\n// * @example\n// * ```typescript\n// * type Id = string | string[] | (() => string);\n// *\n// * interface Cache {\n// * id?: Id;\n// * }\n// *\n// * type Share = {\n// * id?: Id;\n// * }\n// *\n// * interface Options {\n// * cache?: Id | Cache;\n// * share?: Id | Share;\n// * }\n// *\n// * function test(options: Options) {\n// * // string | string[] | (() => string) | Cache | undefined\n// * const cache = options.cache;\n// *\n// * // Cache\n// * // 需要使用\n// * if (isExactObject(cache)) {\n// * cache.id;\n// * }\n// * // string[]\n// * else if (isArray(cache)) {\n// * cache.push();\n// * }\n// * // string\n// * else if (isString(cache)) {\n// * cache.charCodeAt(0);\n// * }\n// * // (() => string) | undefined\n// * else {\n// * cache?.();\n// * }\n// *\n// * // string | string[] | (() => string) | Share | undefined\n// * const share = options.share;\n// *\n// * // Share\n// * if (isObject(share)) {\n// * share.id;\n// * }\n// * // string[]\n// * else if (isArray(share)) {\n// * share.push();\n// * }\n// * // string\n// * else if (isString(share)) {\n// * share.charCodeAt(0);\n// * }\n// * // (() => string) | undefined\n// * else {\n// * share?.();\n// * }\n// * }\n// * ```\n// */\n// export function isExactObject<T>(object: T): object is ExactObject<T> {\n// return typeIs(object) === 'object';\n// }\n","import type { AnyObject } from '@/types';\n\n/**\n * 从对象中选择指定键的属性,返回一个新的对象。\n *\n * @param object - 要从中选择属性的对象。\n * @param keys - 要选择的键数组。\n * @returns 包含指定键属性的新对象。\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: 2, c: 3 };\n * const result = objectPick(obj, ['a', 'c']);\n * console.log(result); // { a: 1, c: 3 }\n * ```\n */\nexport function objectPick<T extends AnyObject, K extends keyof T>(object: T, keys: K[]): Pick<T, K> {\n const result = {} as Pick<T, K>;\n for (const key of keys) {\n if (key in object) {\n result[key] = object[key];\n }\n }\n return result;\n}\n\n/**\n * 从对象中排除指定键的属性,返回一个新的对象。\n *\n * @param object - 要从中排除属性的对象。\n * @param keys - 要排除的键数组。\n * @returns 排除指定键属性后的新对象。\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: 2, c: 3, d: 4 };\n * const result = objectOmit(obj, ['a', 'd']);\n * console.log(result); // { b: 2, c: 3 }\n * ```\n */\nexport function objectOmit<T extends AnyObject, K extends keyof T>(object: T, keys: K[]): Omit<T, K> {\n const result = {} as Omit<T, K>;\n for (const key in object) {\n if (!keys.includes(key as unknown as K)) {\n // @ts-expect-error\n result[key] = object[key];\n }\n }\n return result;\n}\n\n/**\n * 遍历对象的每个键值对,并对每个键值对执行提供的映射函数,返回一个新的对象。\n *\n * @param object - 要遍历的对象。\n * @param mapper - 对每个键值对执行的映射函数。\n * @returns 返回一个新的对象,其中每个值都是通过映射函数处理后的结果。\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: 2, c: 3 };\n * const result = objectMap(obj, (val, key) => String(val * 2));\n * console.log(result); // { a: '2', b: '4', c: '6' }\n * ```\n */\nexport function objectMap<T extends AnyObject, V>(\n object: T,\n mapper: (value: T[keyof T], key: keyof T) => V,\n): Record<keyof T, V> {\n return Object.fromEntries(\n Object.entries(object).map(([key, value]) => [\n key,\n mapper(\n // @ts-expect-error\n value,\n key as keyof T,\n ),\n ]),\n ) as Record<keyof T, V>;\n}\n\n/**\n * 根据提供的过滤函数过滤对象的属性,返回一个新对象,只包含满足条件的属性。\n *\n * @param object - 要过滤的对象。\n * @param predicate - 过滤函数,接收值和键作为参数,返回布尔值。\n * @returns 包含满足过滤条件的属性的新对象。\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: 2, c: 3, d: 4 };\n * const result = objectFilter(obj, (value, key) => value > 2);\n * console.log(result); // { c: 3, d: 4 }\n * ```\n */\nexport function objectFilter<T extends AnyObject>(\n object: T,\n predicate: (value: T[keyof T], key: keyof T) => boolean,\n): Partial<T> {\n return Object.fromEntries(\n Object.entries(object).filter(([key, value]) => predicate(value as T[keyof T], key as keyof T)),\n ) as Partial<T>;\n}\n"],"names":["val"],"mappings":";;;AA+CA,SAAS,WAAW,MAAyB;AAE3C,MAAI,QAAQ,IAAI,EAAU,QAAA,CAAC,GAAG,IAAI;AAElC,MAAI,YAAY,KAAK,QAAQ,cAAc,KAAK;AACpC,cAAA,UAAU,QAAQ,OAAO,EAAE;AAChC,SAAA,UAAU,MAAM,GAAG;AAC5B;AAEA,SAAS,gBAAgB,GAAY;AACnC,SAAO,SAAS,CAAC,KAAK,QAAQ,CAAC;AACjC;AAiDgB,SAAA,UACd,KACA,MACe;AACT,QAAA,OAAO,WAAW,IAAI;AACtB,QAAA,UAAU,KAAK,IAAI;AAGzB,MAAI,SAAc;AAClB,QAAM,YAAsB,CAAC;AAE7B,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAC9B,UAAA,MAAM,KAAK,CAAC;AAElB,cAAU,KAAK,GAAG;AACd,QAAA,CAAC,gBAAgB,MAAM,EAAG;AAG9B,aAAS,OAAO,GAAG;AAAA,EAAA;AAGd,SAAA;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,KAAK;AAAA;AAAA,IAEL,OAAO,gBAAgB,MAAM,KAAK,UAAU,OAAO,OAAO,IAAI;AAAA,EAChE;AACF;AAyCA,MAAM,0BAAiD;AAAA,EACrD,WAAW,MAAM;AAAA,EACjB,cAAc,OAAO,CAAC;AACxB;AA+BO,SAAS,UACd,KACA,MACA,KACA,SACe;AACT,QAAA,EAAE,WAAW,iBAAiB,OAAO,OAAO,CAAI,GAAA,yBAAyB,OAAO;AAChF,QAAA,OAAO,WAAW,IAAI;AACtB,QAAA,UAAU,KAAK,IAAI;AACzB,MAAI,SAAS;AACb,MAAI,UAAU;AACd,QAAM,YAAsB,CAAC;AAE7B,aAAW,OAAO,MAAM;AAClBA,QAAAA,OAAM,OAAO,GAAG;AACpB,cAAU,KAAK,GAAG;AAEd,QAAA,YAAYA,IAAG,GAAG;AACpB,YAAM,QAAQ,aAAa;AAAA,QACzB;AAAA,QACA,MAAM;AAAA,QACN;AAAA,QACA,OAAOA;AAAAA,MAAA,CACR;AAED,UAAI,CAAC,OAAO;AACA,kBAAA;AACV;AAAA,MAAA;AAKFA,aAAM,OAAO,GAAG,IAAI;AAAA,IAAA;AAIbA,aAAAA;AAAAA,EAAA;AAGX,MAAI,CAAC,WAAW,CAAC,YAAY,OAAO,GAAG;AACrC,cAAU,KAAK,OAAO;AAEtB,QACE,UAAU;AAAA,MACR;AAAA,MACA,MAAM;AAAA,MACN,KAAK;AAAA,MACL,OAAO,OAAO,OAAO;AAAA,IAAA,CACtB,GACD;AAGA,aAAO,OAAO,IAAI;AAAA,IAAA;AAAA,EACpB;AAGK,SAAA;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,KAAK;AAAA,IACL,OAAO;AAAA,EACT;AACF;AC/PO,SAAS,cAAc,KAAyB;AAC9C,SAAA,OAAO,oBAAoB,GAAG,EAAE,WAAW,KAAK,OAAO,sBAAsB,GAAG,EAAE,WAAW;AACtG;AAiBO,SAAS,cAAc,KAAyB;AAC/C,QAAA,QAAiB,OAAO,eAAe,GAAG;AAG5C,MAAA,CAAC,MAAc,QAAA;AAGnB,SAAO,UAAU,OAAO;AAC1B;AC5BgB,SAAA,WAAmD,QAAW,MAAuB;AACnG,QAAM,SAAS,CAAC;AAChB,aAAW,OAAO,MAAM;AACtB,QAAI,OAAO,QAAQ;AACV,aAAA,GAAG,IAAI,OAAO,GAAG;AAAA,IAAA;AAAA,EAC1B;AAEK,SAAA;AACT;AAgBgB,SAAA,WAAmD,QAAW,MAAuB;AACnG,QAAM,SAAS,CAAC;AAChB,aAAW,OAAO,QAAQ;AACxB,QAAI,CAAC,KAAK,SAAS,GAAmB,GAAG;AAEhC,aAAA,GAAG,IAAI,OAAO,GAAG;AAAA,IAAA;AAAA,EAC1B;AAEK,SAAA;AACT;AAgBgB,SAAA,UACd,QACA,QACoB;AACpB,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AAAA,MAC3C;AAAA,MACA;AAAA;AAAA,QAEE;AAAA,QACA;AAAA,MAAA;AAAA,IAEH,CAAA;AAAA,EACH;AACF;AAgBgB,SAAA,aACd,QACA,WACY;AACZ,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,KAAK,MAAM,UAAU,OAAqB,GAAc,CAAC;AAAA,EAChG;AACF;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.cjs","sources":["../src/query.ts"],"sourcesContent":["import { objectEach } from './object';\nimport { isArray, isBoolean, isDate, isNull, isNullish, isNumber, isString, isUndefined } from './type';\nimport type { AnyObject } from './types';\n\n/**\n * 查询字符串解析函数\n * @template T - 解析后返回的对象类型\n * @callback QSReader\n * @param {string} value - 查询字符串的值\n * @param {string} key - 查询字符串的键\n * @param {T} qsObject - 当前解析的对象\n * @returns {unknown} 解析后的值,如果返回 undefined 或 null 则不会添加到对象中\n * @example\n * const parser: QSReader<MyObject> = (value, key, obj) => {\n * if (key === 'date') return new Date(value);\n * return value;\n * };\n */\nexport type QSReader<T extends AnyObject> = (value: string, key: string, qsObject: T) => unknown;\n\n/**\n * 解析查询字符串为对象\n * @template T - 返回的对象类型\n * @param {string} queryString - 要解析的查询字符串\n * @param {QSReader<T>} [parser] - 自定义解析函数\n * @returns {T} 解析后的对象\n * @example\n * const obj = qsParse('name=John&age=30');\n * // { name: 'John', age: '30' }\n *\n * const obj2 = qsParse('date=2023-01-01', (val, key) => {\n * if (key === 'date') return new Date(val);\n * return val;\n * });\n * // { date: Date('2023-01-01') }\n */\nexport function qsParse<T extends AnyObject>(queryString: string, parser?: QSReader<T>): T {\n // 添加 globalThis 是便于对接外部环境 URL 的自行实现\n // 例如在 uni-app、微信小程序等运行环境。\n const sp = new globalThis.URLSearchParams(queryString.replace(/^.*\\?/, ''));\n const qsObject = {} as T;\n\n for (const [key, val] of sp.entries()) {\n const valFinal = parser ? parser(val, key, qsObject) : val;\n\n if (isNullish(valFinal)) continue;\n\n if (Object.hasOwn(qsObject, key)) {\n // @ts-expect-error\n if (!isArray(qsObject[key])) qsObject[key] = [qsObject[key]];\n (qsObject[key] as unknown[]).push(val);\n } else {\n // @ts-expect-error\n qsObject[key] = valFinal;\n }\n }\n\n return qsObject;\n}\n\n/**\n * 查询字符串序列化函数\n * @template T - 要序列化的对象类型\n * @callback QSWriter\n * @param {unknown} value - 要序列化的值\n * @param {string} key - 对象的键\n * @param {T} query - 当前序列化的对象\n * @returns {string | null} 序列化后的字符串,如果返回 null 则忽略该键值对\n * @example\n * const writer: QSWriter<MyObject> = (val, key) => {\n * if (val instanceof Date) return val.toISOString();\n * return String(val);\n * };\n */\nexport type QSWriter<T extends AnyObject = AnyObject> = (value: unknown, key: string, query: T) => string | null;\nconst defaultWriter: QSWriter<AnyObject> = (val: unknown) => {\n if (isString(val)) return val;\n if (isNumber(val)) return String(val);\n if (isBoolean(val)) return val ? 'true' : 'false';\n if (isDate(val)) return val.toISOString();\n return null;\n};\n\n/**\n * 将对象序列化为查询字符串\n * @template T - 要序列化的对象类型\n * @param {T} qsObject - 要序列化的对象\n * @param {QSWriter<T>} [stringify=defaultWriter] - 自定义序列化函数\n * @returns {string} 序列化后的查询字符串\n * @example\n * const str = qsStringify({ name: 'John', age: 30 });\n * // 'name=John&age=30'\n *\n * const str2 = qsStringify({ date: new Date('2023-01-01') });\n * // 'date=2023-01-01T00:00:00.000Z'\n */\nexport function qsStringify<T extends AnyObject>(qsObject: T, stringify: QSWriter<T> = defaultWriter): string {\n // 添加 globalThis 是便于对接外部环境 URL 的自行实现\n // 例如在 uni-app、微信小程序等运行环境。\n const sp = new globalThis.URLSearchParams();\n const pushPairs = (val: unknown, key: string) => {\n const valFinal = stringify(val, String(key), qsObject);\n if (isNullish(valFinal)) return;\n\n sp.append(key, valFinal);\n };\n\n objectEach(qsObject, (val, key: string) => {\n if (isArray(val)) {\n for (const it of val) {\n pushPairs(it, key);\n }\n } else {\n pushPairs(val, key);\n }\n });\n\n return sp.toString();\n}\n"],"names":["isNullish","isArray","isString","isNumber","isBoolean","isDate","objectEach"],"mappings":";;;;AAoCgB,SAAA,QAA6B,aAAqB,QAAyB;AAGnF,QAAA,KAAK,IAAI,WAAW,gBAAgB,YAAY,QAAQ,SAAS,EAAE,CAAC;AAC1E,QAAM,WAAW,CAAC;AAElB,aAAW,CAAC,KAAK,GAAG,KAAK,GAAG,WAAW;AACrC,UAAM,WAAW,SAAS,OAAO,KAAK,KAAK,QAAQ,IAAI;AAEnD,QAAAA,KAAAA,UAAU,QAAQ,EAAG;AAEzB,QAAI,OAAO,OAAO,UAAU,GAAG,GAAG;AAEhC,UAAI,CAACC,KAAA,QAAQ,SAAS,GAAG,CAAC,EAAY,UAAA,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC;AAC1D,eAAS,GAAG,EAAgB,KAAK,GAAG;AAAA,IAAA,OAChC;AAEL,eAAS,GAAG,IAAI;AAAA,IAAA;AAAA,EAClB;AAGK,SAAA;AACT;AAiBA,MAAM,gBAAqC,CAAC,QAAiB;AACvD,MAAAC,KAAA,SAAS,GAAG,EAAU,QAAA;AAC1B,MAAIC,KAAS,SAAA,GAAG,EAAG,QAAO,OAAO,GAAG;AACpC,MAAIC,KAAU,UAAA,GAAG,EAAG,QAAO,MAAM,SAAS;AAC1C,MAAIC,KAAO,OAAA,GAAG,EAAG,QAAO,IAAI,YAAY;AACjC,SAAA;AACT;AAegB,SAAA,YAAiC,UAAa,YAAyB,eAAuB;AAGtG,QAAA,KAAK,IAAI,WAAW,gBAAgB;AACpC,QAAA,YAAY,CAAC,KAAc,QAAgB;AAC/C,UAAM,WAAW,UAAU,KAAK,OAAO,GAAG,GAAG,QAAQ;AACjD,QAAAL,KAAAA,UAAU,QAAQ,EAAG;AAEtB,OAAA,OAAO,KAAK,QAAQ;AAAA,EACzB;AAEWM,OAAAA,WAAA,UAAU,CAAC,KAAK,QAAgB;AACrC,QAAAL,KAAAA,QAAQ,GAAG,GAAG;AAChB,iBAAW,MAAM,KAAK;AACpB,kBAAU,IAAI,GAAG;AAAA,MAAA;AAAA,IACnB,OACK;AACL,gBAAU,KAAK,GAAG;AAAA,IAAA;AAAA,EACpB,CACD;AAED,SAAO,GAAG,SAAS;AACrB;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.mjs","sources":["../src/query.ts"],"sourcesContent":["import { objectEach } from './object';\nimport { isArray, isBoolean, isDate, isNull, isNullish, isNumber, isString, isUndefined } from './type';\nimport type { AnyObject } from './types';\n\n/**\n * 查询字符串解析函数\n * @template T - 解析后返回的对象类型\n * @callback QSReader\n * @param {string} value - 查询字符串的值\n * @param {string} key - 查询字符串的键\n * @param {T} qsObject - 当前解析的对象\n * @returns {unknown} 解析后的值,如果返回 undefined 或 null 则不会添加到对象中\n * @example\n * const parser: QSReader<MyObject> = (value, key, obj) => {\n * if (key === 'date') return new Date(value);\n * return value;\n * };\n */\nexport type QSReader<T extends AnyObject> = (value: string, key: string, qsObject: T) => unknown;\n\n/**\n * 解析查询字符串为对象\n * @template T - 返回的对象类型\n * @param {string} queryString - 要解析的查询字符串\n * @param {QSReader<T>} [parser] - 自定义解析函数\n * @returns {T} 解析后的对象\n * @example\n * const obj = qsParse('name=John&age=30');\n * // { name: 'John', age: '30' }\n *\n * const obj2 = qsParse('date=2023-01-01', (val, key) => {\n * if (key === 'date') return new Date(val);\n * return val;\n * });\n * // { date: Date('2023-01-01') }\n */\nexport function qsParse<T extends AnyObject>(queryString: string, parser?: QSReader<T>): T {\n // 添加 globalThis 是便于对接外部环境 URL 的自行实现\n // 例如在 uni-app、微信小程序等运行环境。\n const sp = new globalThis.URLSearchParams(queryString.replace(/^.*\\?/, ''));\n const qsObject = {} as T;\n\n for (const [key, val] of sp.entries()) {\n const valFinal = parser ? parser(val, key, qsObject) : val;\n\n if (isNullish(valFinal)) continue;\n\n if (Object.hasOwn(qsObject, key)) {\n // @ts-expect-error\n if (!isArray(qsObject[key])) qsObject[key] = [qsObject[key]];\n (qsObject[key] as unknown[]).push(val);\n } else {\n // @ts-expect-error\n qsObject[key] = valFinal;\n }\n }\n\n return qsObject;\n}\n\n/**\n * 查询字符串序列化函数\n * @template T - 要序列化的对象类型\n * @callback QSWriter\n * @param {unknown} value - 要序列化的值\n * @param {string} key - 对象的键\n * @param {T} query - 当前序列化的对象\n * @returns {string | null} 序列化后的字符串,如果返回 null 则忽略该键值对\n * @example\n * const writer: QSWriter<MyObject> = (val, key) => {\n * if (val instanceof Date) return val.toISOString();\n * return String(val);\n * };\n */\nexport type QSWriter<T extends AnyObject = AnyObject> = (value: unknown, key: string, query: T) => string | null;\nconst defaultWriter: QSWriter<AnyObject> = (val: unknown) => {\n if (isString(val)) return val;\n if (isNumber(val)) return String(val);\n if (isBoolean(val)) return val ? 'true' : 'false';\n if (isDate(val)) return val.toISOString();\n return null;\n};\n\n/**\n * 将对象序列化为查询字符串\n * @template T - 要序列化的对象类型\n * @param {T} qsObject - 要序列化的对象\n * @param {QSWriter<T>} [stringify=defaultWriter] - 自定义序列化函数\n * @returns {string} 序列化后的查询字符串\n * @example\n * const str = qsStringify({ name: 'John', age: 30 });\n * // 'name=John&age=30'\n *\n * const str2 = qsStringify({ date: new Date('2023-01-01') });\n * // 'date=2023-01-01T00:00:00.000Z'\n */\nexport function qsStringify<T extends AnyObject>(qsObject: T, stringify: QSWriter<T> = defaultWriter): string {\n // 添加 globalThis 是便于对接外部环境 URL 的自行实现\n // 例如在 uni-app、微信小程序等运行环境。\n const sp = new globalThis.URLSearchParams();\n const pushPairs = (val: unknown, key: string) => {\n const valFinal = stringify(val, String(key), qsObject);\n if (isNullish(valFinal)) return;\n\n sp.append(key, valFinal);\n };\n\n objectEach(qsObject, (val, key: string) => {\n if (isArray(val)) {\n for (const it of val) {\n pushPairs(it, key);\n }\n } else {\n pushPairs(val, key);\n }\n });\n\n return sp.toString();\n}\n"],"names":[],"mappings":";;AAoCgB,SAAA,QAA6B,aAAqB,QAAyB;AAGnF,QAAA,KAAK,IAAI,WAAW,gBAAgB,YAAY,QAAQ,SAAS,EAAE,CAAC;AAC1E,QAAM,WAAW,CAAC;AAElB,aAAW,CAAC,KAAK,GAAG,KAAK,GAAG,WAAW;AACrC,UAAM,WAAW,SAAS,OAAO,KAAK,KAAK,QAAQ,IAAI;AAEnD,QAAA,UAAU,QAAQ,EAAG;AAEzB,QAAI,OAAO,OAAO,UAAU,GAAG,GAAG;AAEhC,UAAI,CAAC,QAAQ,SAAS,GAAG,CAAC,EAAY,UAAA,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC;AAC1D,eAAS,GAAG,EAAgB,KAAK,GAAG;AAAA,IAAA,OAChC;AAEL,eAAS,GAAG,IAAI;AAAA,IAAA;AAAA,EAClB;AAGK,SAAA;AACT;AAiBA,MAAM,gBAAqC,CAAC,QAAiB;AACvD,MAAA,SAAS,GAAG,EAAU,QAAA;AAC1B,MAAI,SAAS,GAAG,EAAG,QAAO,OAAO,GAAG;AACpC,MAAI,UAAU,GAAG,EAAG,QAAO,MAAM,SAAS;AAC1C,MAAI,OAAO,GAAG,EAAG,QAAO,IAAI,YAAY;AACjC,SAAA;AACT;AAegB,SAAA,YAAiC,UAAa,YAAyB,eAAuB;AAGtG,QAAA,KAAK,IAAI,WAAW,gBAAgB;AACpC,QAAA,YAAY,CAAC,KAAc,QAAgB;AAC/C,UAAM,WAAW,UAAU,KAAK,OAAO,GAAG,GAAG,QAAQ;AACjD,QAAA,UAAU,QAAQ,EAAG;AAEtB,OAAA,OAAO,KAAK,QAAQ;AAAA,EACzB;AAEW,aAAA,UAAU,CAAC,KAAK,QAAgB;AACrC,QAAA,QAAQ,GAAG,GAAG;AAChB,iBAAW,MAAM,KAAK;AACpB,kBAAU,IAAI,GAAG;AAAA,MAAA;AAAA,IACnB,OACK;AACL,gBAAU,KAAK,GAAG;AAAA,IAAA;AAAA,EACpB,CACD;AAED,SAAO,GAAG,SAAS;AACrB;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CallbackFunction0, CallbackFunction1, CallbackFunction2, CallbackFunction3, CallbackFunction4, CallbackFunction5, CallbackFunction6 } from './
|
|
1
|
+
import { CallbackFunction0, CallbackFunction1, CallbackFunction2, CallbackFunction3, CallbackFunction4, CallbackFunction5, CallbackFunction6 } from './curry';
|
|
2
2
|
import { FlattenReturn } from './types';
|
|
3
3
|
export declare function tryCallback(cf: CallbackFunction0): Promise<FlattenReturn>;
|
|
4
4
|
export declare function tryCallback<T = void>(cf: CallbackFunction0<T>): Promise<FlattenReturn<T>>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { FlattenReturn } from './types';
|
|
2
|
+
export type SyncFunction<T> = () => T;
|
|
3
|
+
export declare function trySync<T>(syncFn: SyncFunction<T>): FlattenReturn<T>;
|
|
4
|
+
export type AsyncFunction<T> = () => Promise<T>;
|
|
5
|
+
export declare function tryAsync<T>(asyncFn: AsyncFunction<T>): Promise<FlattenReturn<T>>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CallbackFunction0 } from './curry';
|
|
2
|
+
import { AsyncFunction, SyncFunction } from './function';
|
|
3
|
+
import { FlattenReturn } from './types';
|
|
4
|
+
export type FlattenAble<T> = SyncFunction<T> | AsyncFunction<T> | CallbackFunction0<T> | PromiseLike<T>;
|
|
5
|
+
export declare function tryFlatten<T>(flattenAble: AsyncFunction<T>): Promise<FlattenReturn<T>>;
|
|
6
|
+
export declare function tryFlatten<T>(flattenAble: SyncFunction<T>): FlattenReturn<T>;
|
|
7
|
+
export declare function tryFlatten<T>(flattenAble: CallbackFunction0<T> | PromiseLike<T>): Promise<FlattenReturn<T>>;
|
package/dist/try/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export type FlattenReturn<T = void> = readonly [Error, undefined] | readonly [
|
|
1
|
+
export type FlattenReturn<T = void> = readonly [Error, undefined] | readonly [undefined, T];
|
package/dist/try.cjs
CHANGED
|
@@ -1,34 +1,39 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const type = require("./type.cjs");
|
|
3
4
|
const error = require("./error.cjs");
|
|
4
|
-
const pkgName = "@cloudcome/utils-core";
|
|
5
|
-
const pkgVersion = "1.5.0";
|
|
6
5
|
function callbackCurry(cf, ...args) {
|
|
7
6
|
return function callbackCurried(callback) {
|
|
8
7
|
cf.apply(this, [...args, callback]);
|
|
9
8
|
};
|
|
10
9
|
}
|
|
11
|
-
function tryFunction(syncFn) {
|
|
12
|
-
try {
|
|
13
|
-
return [null, syncFn()];
|
|
14
|
-
} catch (err) {
|
|
15
|
-
return [error.errorNormalize(err), void 0];
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
10
|
function tryCallback(cf, ...args) {
|
|
19
11
|
return new Promise((resolve) => {
|
|
20
12
|
callbackCurry.apply(this, [cf, ...args])((err, res) => {
|
|
21
13
|
if (err) {
|
|
22
14
|
resolve([error.errorNormalize(err), void 0]);
|
|
23
15
|
} else {
|
|
24
|
-
resolve([
|
|
16
|
+
resolve([void 0, res]);
|
|
25
17
|
}
|
|
26
18
|
});
|
|
27
19
|
});
|
|
28
20
|
}
|
|
21
|
+
function trySync(syncFn) {
|
|
22
|
+
try {
|
|
23
|
+
return [void 0, syncFn()];
|
|
24
|
+
} catch (err) {
|
|
25
|
+
return [error.errorNormalize(err), void 0];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function tryAsync(asyncFn) {
|
|
29
|
+
return asyncFn().then(
|
|
30
|
+
(res) => [void 0, res],
|
|
31
|
+
(err) => [error.errorNormalize(err), void 0]
|
|
32
|
+
);
|
|
33
|
+
}
|
|
29
34
|
function tryPromise(promise) {
|
|
30
35
|
return promise.then(
|
|
31
|
-
(res) => [
|
|
36
|
+
(res) => [void 0, res],
|
|
32
37
|
(err) => [error.errorNormalize(err), void 0]
|
|
33
38
|
);
|
|
34
39
|
}
|
|
@@ -37,15 +42,10 @@ function tryFlatten(flattenAble) {
|
|
|
37
42
|
return tryPromise(flattenAble);
|
|
38
43
|
}
|
|
39
44
|
if (flattenAble.length === 0) {
|
|
40
|
-
return
|
|
45
|
+
if (type.isAsyncFunction(flattenAble)) return tryAsync(flattenAble);
|
|
46
|
+
return trySync(flattenAble);
|
|
41
47
|
}
|
|
42
48
|
return tryCallback(flattenAble);
|
|
43
49
|
}
|
|
44
|
-
exports.callbackCurry = callbackCurry;
|
|
45
|
-
exports.pkgName = pkgName;
|
|
46
|
-
exports.pkgVersion = pkgVersion;
|
|
47
|
-
exports.tryCallback = tryCallback;
|
|
48
50
|
exports.tryFlatten = tryFlatten;
|
|
49
|
-
exports.tryFunction = tryFunction;
|
|
50
|
-
exports.tryPromise = tryPromise;
|
|
51
51
|
//# sourceMappingURL=try.cjs.map
|
package/dist/try.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"try.cjs","sources":["../src/try/
|
|
1
|
+
{"version":3,"file":"try.cjs","sources":["../src/try/curry.ts","../src/try/callback.ts","../src/try/function.ts","../src/try/promise.ts","../src/try/main.ts"],"sourcesContent":["// biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\nexport type Callback<T = void> = (err: null | undefined | void | Error, res: T) => unknown;\n\nexport type CallbackFunction0<T = void> = (callback: Callback<T>) => unknown;\nexport type CallbackFunction1<A, T = void> = (a: A, callback: Callback<T>) => unknown;\nexport type CallbackFunction2<A, B, T = void> = (a: A, b: B, callback: Callback<T>) => unknown;\nexport type CallbackFunction3<A, B, C, T = void> = (a: A, b: B, c: C, callback: Callback<T>) => unknown;\nexport type CallbackFunction4<A, B, C, D, T = void> = (a: A, b: B, c: C, d: D, callback: Callback<T>) => unknown;\nexport type CallbackFunction5<A, B, C, D, E, T = void> = (\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n callback: Callback<T>,\n) => unknown;\nexport type CallbackFunction6<A, B, C, D, E, F, T = void> = (\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n f: F,\n callback: Callback<T>,\n) => unknown;\n\nexport type CallbackCurried<T> = (callback: Callback<T>) => unknown;\n\nexport function callbackCurry<T = void>(cf: CallbackFunction0<T>): CallbackCurried<T>;\nexport function callbackCurry<A, T = void>(cf: CallbackFunction1<A, T>, a: A): CallbackCurried<T>;\nexport function callbackCurry<A, B, T = void>(cf: CallbackFunction2<A, B, T>, a: A, b: B): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, T = void>(\n cf: CallbackFunction3<A, B, C, T>,\n a: A,\n b: B,\n c: C,\n): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, D, T = void>(\n cf: CallbackFunction4<A, B, C, D, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, D, E, T = void>(\n cf: CallbackFunction5<A, B, C, D, E, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, D, E, F, T = void>(\n cf: CallbackFunction6<A, B, C, D, E, F, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n f: F,\n): CallbackCurried<T>;\nexport function callbackCurry(cf: unknown, ...args: unknown[]): CallbackCurried<unknown> {\n return function callbackCurried(callback: Callback<unknown>) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n cf.apply(this, [...args, callback]);\n };\n}\n","import { errorNormalize } from '@/error';\nimport type {\n CallbackFunction0,\n CallbackFunction1,\n CallbackFunction2,\n CallbackFunction3,\n CallbackFunction4,\n CallbackFunction5,\n CallbackFunction6,\n} from './curry';\nimport { callbackCurry } from './curry';\nimport type { FlattenReturn } from './types';\n\nexport function tryCallback(cf: CallbackFunction0): Promise<FlattenReturn>;\nexport function tryCallback<T = void>(cf: CallbackFunction0<T>): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, T = void>(cf: CallbackFunction1<A, T>, a: A): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, T = void>(cf: CallbackFunction2<A, B, T>, a: A, b: B): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, T = void>(\n cf: CallbackFunction3<A, B, C, T>,\n a: A,\n b: B,\n c: C,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, D, T = void>(\n cf: CallbackFunction4<A, B, C, D>,\n a: A,\n b: B,\n c: C,\n d: D,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, D, E, T = void>(\n cf: CallbackFunction5<A, B, C, D, E, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, D, E, F, T = void>(\n cf: CallbackFunction6<A, B, C, D, E, F, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n f: F,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback(cf: unknown, ...args: unknown[]): Promise<FlattenReturn<unknown>> {\n return new Promise((resolve) => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n callbackCurry.apply(this, [cf, ...args])((err, res) => {\n if (err) {\n resolve([errorNormalize(err), undefined] as const);\n } else {\n resolve([undefined, res] as const);\n }\n });\n });\n}\n","import { errorNormalize } from '@/error';\nimport type { FlattenReturn } from './types';\n\nexport type SyncFunction<T> = () => T;\n\nexport function trySync<T>(syncFn: SyncFunction<T>): FlattenReturn<T> {\n try {\n return [undefined, syncFn()] as const;\n } catch (err) {\n return [errorNormalize(err), undefined] as const;\n }\n}\n\nexport type AsyncFunction<T> = () => Promise<T>;\n\nexport function tryAsync<T>(asyncFn: AsyncFunction<T>): Promise<FlattenReturn<T>> {\n return asyncFn().then(\n (res) => [undefined, res] as const,\n (err) => [errorNormalize(err), undefined] as const,\n );\n}\n","import { errorNormalize } from '@/error';\nimport type { FlattenReturn } from './types';\n\nexport function tryPromise<T>(promise: PromiseLike<T>): PromiseLike<FlattenReturn<T>> {\n return promise.then(\n (res) => [undefined, res] as const,\n (err) => [errorNormalize(err), undefined] as const,\n );\n}\n","import { isAsyncFunction } from '@/type';\nimport { tryCallback } from './callback';\nimport type { CallbackFunction0 } from './curry';\nimport { type AsyncFunction, type SyncFunction, tryAsync, trySync } from './function';\nimport { tryPromise } from './promise';\nimport type { FlattenReturn } from './types';\n\nexport type FlattenAble<T> = SyncFunction<T> | AsyncFunction<T> | CallbackFunction0<T> | PromiseLike<T>;\n\n// 注意顺序 AsyncFunction > SyncFunction > CallbackFunction0 > PromiseLike\n// 需要先匹配 AsyncFunction,否则会把入参当做同步函数\nexport function tryFlatten<T>(flattenAble: AsyncFunction<T>): Promise<FlattenReturn<T>>;\nexport function tryFlatten<T>(flattenAble: SyncFunction<T>): FlattenReturn<T>;\nexport function tryFlatten<T>(flattenAble: CallbackFunction0<T> | PromiseLike<T>): Promise<FlattenReturn<T>>;\nexport function tryFlatten<T>(flattenAble: FlattenAble<T>): unknown {\n if ('then' in flattenAble) {\n return tryPromise<T>(flattenAble);\n }\n\n // SyncFunction | AsyncFunction\n if (flattenAble.length === 0) {\n if (isAsyncFunction(flattenAble)) return tryAsync<T>(flattenAble as AsyncFunction<T>);\n return trySync<T>(flattenAble as SyncFunction<T>);\n }\n\n return tryCallback<T>(flattenAble);\n}\n"],"names":["errorNormalize","isAsyncFunction"],"mappings":";;;;AA6DgB,SAAA,cAAc,OAAgB,MAA2C;AAChF,SAAA,SAAS,gBAAgB,UAA6B;AAG3D,OAAG,MAAM,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC;AAAA,EACpC;AACF;ACpBgB,SAAA,YAAY,OAAgB,MAAkD;AACrF,SAAA,IAAI,QAAQ,CAAC,YAAY;AAGhB,kBAAA,MAAM,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,QAAQ;AACrD,UAAI,KAAK;AACP,gBAAQ,CAACA,MAAA,eAAe,GAAG,GAAG,MAAS,CAAU;AAAA,MAAA,OAC5C;AACG,gBAAA,CAAC,QAAW,GAAG,CAAU;AAAA,MAAA;AAAA,IACnC,CACD;AAAA,EAAA,CACF;AACH;ACtDO,SAAS,QAAW,QAA2C;AAChE,MAAA;AACK,WAAA,CAAC,QAAW,QAAQ;AAAA,WACpB,KAAK;AACZ,WAAO,CAACA,MAAA,eAAe,GAAG,GAAG,MAAS;AAAA,EAAA;AAE1C;AAIO,SAAS,SAAY,SAAsD;AAChF,SAAO,QAAU,EAAA;AAAA,IACf,CAAC,QAAQ,CAAC,QAAW,GAAG;AAAA,IACxB,CAAC,QAAQ,CAACA,qBAAe,GAAG,GAAG,MAAS;AAAA,EAC1C;AACF;ACjBO,SAAS,WAAc,SAAwD;AACpF,SAAO,QAAQ;AAAA,IACb,CAAC,QAAQ,CAAC,QAAW,GAAG;AAAA,IACxB,CAAC,QAAQ,CAACA,qBAAe,GAAG,GAAG,MAAS;AAAA,EAC1C;AACF;ACMO,SAAS,WAAc,aAAsC;AAClE,MAAI,UAAU,aAAa;AACzB,WAAO,WAAc,WAAW;AAAA,EAAA;AAI9B,MAAA,YAAY,WAAW,GAAG;AAC5B,QAAIC,KAAgB,gBAAA,WAAW,EAAG,QAAO,SAAY,WAA+B;AACpF,WAAO,QAAW,WAA8B;AAAA,EAAA;AAGlD,SAAO,YAAe,WAAW;AACnC;;"}
|
package/dist/try.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from './try/
|
|
1
|
+
export * from './try/main';
|
|
2
|
+
export * from './try/types';
|
package/dist/try.mjs
CHANGED
|
@@ -1,32 +1,37 @@
|
|
|
1
|
+
import { isAsyncFunction } from "./type.mjs";
|
|
1
2
|
import { errorNormalize } from "./error.mjs";
|
|
2
|
-
const pkgName = "@cloudcome/utils-core";
|
|
3
|
-
const pkgVersion = "1.5.0";
|
|
4
3
|
function callbackCurry(cf, ...args) {
|
|
5
4
|
return function callbackCurried(callback) {
|
|
6
5
|
cf.apply(this, [...args, callback]);
|
|
7
6
|
};
|
|
8
7
|
}
|
|
9
|
-
function tryFunction(syncFn) {
|
|
10
|
-
try {
|
|
11
|
-
return [null, syncFn()];
|
|
12
|
-
} catch (err) {
|
|
13
|
-
return [errorNormalize(err), void 0];
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
8
|
function tryCallback(cf, ...args) {
|
|
17
9
|
return new Promise((resolve) => {
|
|
18
10
|
callbackCurry.apply(this, [cf, ...args])((err, res) => {
|
|
19
11
|
if (err) {
|
|
20
12
|
resolve([errorNormalize(err), void 0]);
|
|
21
13
|
} else {
|
|
22
|
-
resolve([
|
|
14
|
+
resolve([void 0, res]);
|
|
23
15
|
}
|
|
24
16
|
});
|
|
25
17
|
});
|
|
26
18
|
}
|
|
19
|
+
function trySync(syncFn) {
|
|
20
|
+
try {
|
|
21
|
+
return [void 0, syncFn()];
|
|
22
|
+
} catch (err) {
|
|
23
|
+
return [errorNormalize(err), void 0];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function tryAsync(asyncFn) {
|
|
27
|
+
return asyncFn().then(
|
|
28
|
+
(res) => [void 0, res],
|
|
29
|
+
(err) => [errorNormalize(err), void 0]
|
|
30
|
+
);
|
|
31
|
+
}
|
|
27
32
|
function tryPromise(promise) {
|
|
28
33
|
return promise.then(
|
|
29
|
-
(res) => [
|
|
34
|
+
(res) => [void 0, res],
|
|
30
35
|
(err) => [errorNormalize(err), void 0]
|
|
31
36
|
);
|
|
32
37
|
}
|
|
@@ -35,17 +40,12 @@ function tryFlatten(flattenAble) {
|
|
|
35
40
|
return tryPromise(flattenAble);
|
|
36
41
|
}
|
|
37
42
|
if (flattenAble.length === 0) {
|
|
38
|
-
return
|
|
43
|
+
if (isAsyncFunction(flattenAble)) return tryAsync(flattenAble);
|
|
44
|
+
return trySync(flattenAble);
|
|
39
45
|
}
|
|
40
46
|
return tryCallback(flattenAble);
|
|
41
47
|
}
|
|
42
48
|
export {
|
|
43
|
-
|
|
44
|
-
pkgName,
|
|
45
|
-
pkgVersion,
|
|
46
|
-
tryCallback,
|
|
47
|
-
tryFlatten,
|
|
48
|
-
tryFunction,
|
|
49
|
-
tryPromise
|
|
49
|
+
tryFlatten
|
|
50
50
|
};
|
|
51
51
|
//# sourceMappingURL=try.mjs.map
|
package/dist/try.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"try.mjs","sources":["../src/try/
|
|
1
|
+
{"version":3,"file":"try.mjs","sources":["../src/try/curry.ts","../src/try/callback.ts","../src/try/function.ts","../src/try/promise.ts","../src/try/main.ts"],"sourcesContent":["// biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\nexport type Callback<T = void> = (err: null | undefined | void | Error, res: T) => unknown;\n\nexport type CallbackFunction0<T = void> = (callback: Callback<T>) => unknown;\nexport type CallbackFunction1<A, T = void> = (a: A, callback: Callback<T>) => unknown;\nexport type CallbackFunction2<A, B, T = void> = (a: A, b: B, callback: Callback<T>) => unknown;\nexport type CallbackFunction3<A, B, C, T = void> = (a: A, b: B, c: C, callback: Callback<T>) => unknown;\nexport type CallbackFunction4<A, B, C, D, T = void> = (a: A, b: B, c: C, d: D, callback: Callback<T>) => unknown;\nexport type CallbackFunction5<A, B, C, D, E, T = void> = (\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n callback: Callback<T>,\n) => unknown;\nexport type CallbackFunction6<A, B, C, D, E, F, T = void> = (\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n f: F,\n callback: Callback<T>,\n) => unknown;\n\nexport type CallbackCurried<T> = (callback: Callback<T>) => unknown;\n\nexport function callbackCurry<T = void>(cf: CallbackFunction0<T>): CallbackCurried<T>;\nexport function callbackCurry<A, T = void>(cf: CallbackFunction1<A, T>, a: A): CallbackCurried<T>;\nexport function callbackCurry<A, B, T = void>(cf: CallbackFunction2<A, B, T>, a: A, b: B): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, T = void>(\n cf: CallbackFunction3<A, B, C, T>,\n a: A,\n b: B,\n c: C,\n): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, D, T = void>(\n cf: CallbackFunction4<A, B, C, D, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, D, E, T = void>(\n cf: CallbackFunction5<A, B, C, D, E, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, D, E, F, T = void>(\n cf: CallbackFunction6<A, B, C, D, E, F, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n f: F,\n): CallbackCurried<T>;\nexport function callbackCurry(cf: unknown, ...args: unknown[]): CallbackCurried<unknown> {\n return function callbackCurried(callback: Callback<unknown>) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n cf.apply(this, [...args, callback]);\n };\n}\n","import { errorNormalize } from '@/error';\nimport type {\n CallbackFunction0,\n CallbackFunction1,\n CallbackFunction2,\n CallbackFunction3,\n CallbackFunction4,\n CallbackFunction5,\n CallbackFunction6,\n} from './curry';\nimport { callbackCurry } from './curry';\nimport type { FlattenReturn } from './types';\n\nexport function tryCallback(cf: CallbackFunction0): Promise<FlattenReturn>;\nexport function tryCallback<T = void>(cf: CallbackFunction0<T>): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, T = void>(cf: CallbackFunction1<A, T>, a: A): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, T = void>(cf: CallbackFunction2<A, B, T>, a: A, b: B): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, T = void>(\n cf: CallbackFunction3<A, B, C, T>,\n a: A,\n b: B,\n c: C,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, D, T = void>(\n cf: CallbackFunction4<A, B, C, D>,\n a: A,\n b: B,\n c: C,\n d: D,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, D, E, T = void>(\n cf: CallbackFunction5<A, B, C, D, E, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, D, E, F, T = void>(\n cf: CallbackFunction6<A, B, C, D, E, F, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n f: F,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback(cf: unknown, ...args: unknown[]): Promise<FlattenReturn<unknown>> {\n return new Promise((resolve) => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n callbackCurry.apply(this, [cf, ...args])((err, res) => {\n if (err) {\n resolve([errorNormalize(err), undefined] as const);\n } else {\n resolve([undefined, res] as const);\n }\n });\n });\n}\n","import { errorNormalize } from '@/error';\nimport type { FlattenReturn } from './types';\n\nexport type SyncFunction<T> = () => T;\n\nexport function trySync<T>(syncFn: SyncFunction<T>): FlattenReturn<T> {\n try {\n return [undefined, syncFn()] as const;\n } catch (err) {\n return [errorNormalize(err), undefined] as const;\n }\n}\n\nexport type AsyncFunction<T> = () => Promise<T>;\n\nexport function tryAsync<T>(asyncFn: AsyncFunction<T>): Promise<FlattenReturn<T>> {\n return asyncFn().then(\n (res) => [undefined, res] as const,\n (err) => [errorNormalize(err), undefined] as const,\n );\n}\n","import { errorNormalize } from '@/error';\nimport type { FlattenReturn } from './types';\n\nexport function tryPromise<T>(promise: PromiseLike<T>): PromiseLike<FlattenReturn<T>> {\n return promise.then(\n (res) => [undefined, res] as const,\n (err) => [errorNormalize(err), undefined] as const,\n );\n}\n","import { isAsyncFunction } from '@/type';\nimport { tryCallback } from './callback';\nimport type { CallbackFunction0 } from './curry';\nimport { type AsyncFunction, type SyncFunction, tryAsync, trySync } from './function';\nimport { tryPromise } from './promise';\nimport type { FlattenReturn } from './types';\n\nexport type FlattenAble<T> = SyncFunction<T> | AsyncFunction<T> | CallbackFunction0<T> | PromiseLike<T>;\n\n// 注意顺序 AsyncFunction > SyncFunction > CallbackFunction0 > PromiseLike\n// 需要先匹配 AsyncFunction,否则会把入参当做同步函数\nexport function tryFlatten<T>(flattenAble: AsyncFunction<T>): Promise<FlattenReturn<T>>;\nexport function tryFlatten<T>(flattenAble: SyncFunction<T>): FlattenReturn<T>;\nexport function tryFlatten<T>(flattenAble: CallbackFunction0<T> | PromiseLike<T>): Promise<FlattenReturn<T>>;\nexport function tryFlatten<T>(flattenAble: FlattenAble<T>): unknown {\n if ('then' in flattenAble) {\n return tryPromise<T>(flattenAble);\n }\n\n // SyncFunction | AsyncFunction\n if (flattenAble.length === 0) {\n if (isAsyncFunction(flattenAble)) return tryAsync<T>(flattenAble as AsyncFunction<T>);\n return trySync<T>(flattenAble as SyncFunction<T>);\n }\n\n return tryCallback<T>(flattenAble);\n}\n"],"names":[],"mappings":";;AA6DgB,SAAA,cAAc,OAAgB,MAA2C;AAChF,SAAA,SAAS,gBAAgB,UAA6B;AAG3D,OAAG,MAAM,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC;AAAA,EACpC;AACF;ACpBgB,SAAA,YAAY,OAAgB,MAAkD;AACrF,SAAA,IAAI,QAAQ,CAAC,YAAY;AAGhB,kBAAA,MAAM,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,QAAQ;AACrD,UAAI,KAAK;AACP,gBAAQ,CAAC,eAAe,GAAG,GAAG,MAAS,CAAU;AAAA,MAAA,OAC5C;AACG,gBAAA,CAAC,QAAW,GAAG,CAAU;AAAA,MAAA;AAAA,IACnC,CACD;AAAA,EAAA,CACF;AACH;ACtDO,SAAS,QAAW,QAA2C;AAChE,MAAA;AACK,WAAA,CAAC,QAAW,QAAQ;AAAA,WACpB,KAAK;AACZ,WAAO,CAAC,eAAe,GAAG,GAAG,MAAS;AAAA,EAAA;AAE1C;AAIO,SAAS,SAAY,SAAsD;AAChF,SAAO,QAAU,EAAA;AAAA,IACf,CAAC,QAAQ,CAAC,QAAW,GAAG;AAAA,IACxB,CAAC,QAAQ,CAAC,eAAe,GAAG,GAAG,MAAS;AAAA,EAC1C;AACF;ACjBO,SAAS,WAAc,SAAwD;AACpF,SAAO,QAAQ;AAAA,IACb,CAAC,QAAQ,CAAC,QAAW,GAAG;AAAA,IACxB,CAAC,QAAQ,CAAC,eAAe,GAAG,GAAG,MAAS;AAAA,EAC1C;AACF;ACMO,SAAS,WAAc,aAAsC;AAClE,MAAI,UAAU,aAAa;AACzB,WAAO,WAAc,WAAW;AAAA,EAAA;AAI9B,MAAA,YAAY,WAAW,GAAG;AAC5B,QAAI,gBAAgB,WAAW,EAAG,QAAO,SAAY,WAA+B;AACpF,WAAO,QAAW,WAA8B;AAAA,EAAA;AAGlD,SAAO,YAAe,WAAW;AACnC;"}
|
package/dist/types.d.ts
CHANGED
|
@@ -54,4 +54,12 @@ export type UnionToTuple<U, Last = _UnionLast<U>> = [U] extends [never] ? [] : [
|
|
|
54
54
|
export type MergeIntersection<A> = A extends infer T ? {
|
|
55
55
|
[Key in keyof T]: T[Key];
|
|
56
56
|
} : never;
|
|
57
|
+
/**
|
|
58
|
+
* 以小写字母开头的字符串类型
|
|
59
|
+
*/
|
|
60
|
+
export type LowercaseStartString = `${'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z'}${string}`;
|
|
61
|
+
/**
|
|
62
|
+
* 以大写字母开头的字符串类型
|
|
63
|
+
*/
|
|
64
|
+
export type UppercaseStartString = `${'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'}${string}`;
|
|
57
65
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcome/utils-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "cloudcome core utils",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22"
|
|
@@ -64,11 +64,6 @@
|
|
|
64
64
|
"import": "./dist/emitter.mjs",
|
|
65
65
|
"require": "./dist/emitter.cjs"
|
|
66
66
|
},
|
|
67
|
-
"./enum": {
|
|
68
|
-
"types": "./dist/enum.d.ts",
|
|
69
|
-
"import": "./dist/enum.mjs",
|
|
70
|
-
"require": "./dist/enum.cjs"
|
|
71
|
-
},
|
|
72
67
|
"./env": {
|
|
73
68
|
"types": "./dist/env.d.ts",
|
|
74
69
|
"import": "./dist/env.mjs",
|
|
@@ -84,10 +79,10 @@
|
|
|
84
79
|
"import": "./dist/exception.mjs",
|
|
85
80
|
"require": "./dist/exception.cjs"
|
|
86
81
|
},
|
|
87
|
-
"./
|
|
88
|
-
"types": "./dist/
|
|
89
|
-
"import": "./dist/
|
|
90
|
-
"require": "./dist/
|
|
82
|
+
"./function": {
|
|
83
|
+
"types": "./dist/function.d.ts",
|
|
84
|
+
"import": "./dist/function.mjs",
|
|
85
|
+
"require": "./dist/function.cjs"
|
|
91
86
|
},
|
|
92
87
|
"./number": {
|
|
93
88
|
"types": "./dist/number.d.ts",
|
|
@@ -109,10 +104,10 @@
|
|
|
109
104
|
"import": "./dist/promise.mjs",
|
|
110
105
|
"require": "./dist/promise.cjs"
|
|
111
106
|
},
|
|
112
|
-
"./
|
|
113
|
-
"types": "./dist/
|
|
114
|
-
"import": "./dist/
|
|
115
|
-
"require": "./dist/
|
|
107
|
+
"./query": {
|
|
108
|
+
"types": "./dist/query.d.ts",
|
|
109
|
+
"import": "./dist/query.mjs",
|
|
110
|
+
"require": "./dist/query.cjs"
|
|
116
111
|
},
|
|
117
112
|
"./regexp": {
|
|
118
113
|
"types": "./dist/regexp.d.ts",
|
|
@@ -202,9 +197,6 @@
|
|
|
202
197
|
"emitter": [
|
|
203
198
|
"./dist/emitter.d.ts"
|
|
204
199
|
],
|
|
205
|
-
"enum": [
|
|
206
|
-
"./dist/enum.d.ts"
|
|
207
|
-
],
|
|
208
200
|
"env": [
|
|
209
201
|
"./dist/env.d.ts"
|
|
210
202
|
],
|
|
@@ -214,8 +206,8 @@
|
|
|
214
206
|
"exception": [
|
|
215
207
|
"./dist/exception.d.ts"
|
|
216
208
|
],
|
|
217
|
-
"
|
|
218
|
-
"./dist/
|
|
209
|
+
"function": [
|
|
210
|
+
"./dist/function.d.ts"
|
|
219
211
|
],
|
|
220
212
|
"number": [
|
|
221
213
|
"./dist/number.d.ts"
|
|
@@ -229,8 +221,8 @@
|
|
|
229
221
|
"promise": [
|
|
230
222
|
"./dist/promise.d.ts"
|
|
231
223
|
],
|
|
232
|
-
"
|
|
233
|
-
"./dist/
|
|
224
|
+
"query": [
|
|
225
|
+
"./dist/query.d.ts"
|
|
234
226
|
],
|
|
235
227
|
"regexp": [
|
|
236
228
|
"./dist/regexp.d.ts"
|
package/dist/enum.cjs
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
function _defineEnum(definition) {
|
|
4
|
-
const keys = Object.keys(definition);
|
|
5
|
-
return {
|
|
6
|
-
...[...Object.entries(definition)].reduce((acc, [key, dfn]) => {
|
|
7
|
-
if (key[0].toUpperCase() !== key[0]) {
|
|
8
|
-
throw new Error(`错误:枚举键名 ${key} 必须以大写字母开头`);
|
|
9
|
-
}
|
|
10
|
-
if (key.startsWith("$")) {
|
|
11
|
-
throw new Error(`错误:枚举键名 ${key} 不能以 $ 符号开头`);
|
|
12
|
-
}
|
|
13
|
-
acc[key] = dfn.value;
|
|
14
|
-
acc[`$${key}`] = { key, ...dfn };
|
|
15
|
-
return acc;
|
|
16
|
-
}, {}),
|
|
17
|
-
definition,
|
|
18
|
-
descriptions: keys.map((key) => ({
|
|
19
|
-
key,
|
|
20
|
-
...definition[key]
|
|
21
|
-
})),
|
|
22
|
-
keys,
|
|
23
|
-
length: keys.length,
|
|
24
|
-
values: keys.map((key) => definition[key].value),
|
|
25
|
-
kvRecord: keys.reduce((acc, key) => {
|
|
26
|
-
acc[key] = definition[key].value;
|
|
27
|
-
return acc;
|
|
28
|
-
}, {}),
|
|
29
|
-
vkRecord: keys.reduce((acc, key) => {
|
|
30
|
-
acc[definition[key].value] = key;
|
|
31
|
-
return acc;
|
|
32
|
-
}, {}),
|
|
33
|
-
toKeyRecord(prop) {
|
|
34
|
-
return keys.reduce((acc, key) => {
|
|
35
|
-
acc[key] = definition[key][prop];
|
|
36
|
-
return acc;
|
|
37
|
-
}, {});
|
|
38
|
-
},
|
|
39
|
-
toValRecord(prop) {
|
|
40
|
-
return keys.reduce(
|
|
41
|
-
(acc, key) => {
|
|
42
|
-
acc[definition[key].value] = definition[key][prop];
|
|
43
|
-
return acc;
|
|
44
|
-
},
|
|
45
|
-
{}
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
function declareEnum() {
|
|
51
|
-
return {
|
|
52
|
-
define(definition) {
|
|
53
|
-
return _defineEnum(definition);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
exports.declareEnum = declareEnum;
|
|
58
|
-
//# sourceMappingURL=enum.cjs.map
|
package/dist/enum.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"enum.cjs","sources":["../src/enum.ts"],"sourcesContent":["import type { AnyObject, MergeIntersection, UnionToIntersection, UnionToTuple } from './types';\n\nexport type EnumKey = string;\nexport type EnumValue = number | string;\nexport type EnumMetaAppend = {\n key?: string;\n value?: string | number;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n [key: string]: any;\n};\nexport type EnumMeta<A extends EnumMetaAppend> = A & {\n value: EnumValue;\n};\nexport type EnumDescription<A extends EnumMetaAppend> = Record<EnumKey, EnumMeta<A>>;\n\nconst enumError = Symbol('enumKeyError');\n\ntype _StartWithDollarSign<T extends string> = T extends `$${infer R}` ? R : never;\n\ntype _CheckDefinition<O extends AnyObject> = {\n // [K in keyof O & string]: K extends Capitalize<K> ? O[K] : `错误:枚举键名 ${K} 必须大写字母开头`;\n [K in keyof O & string]: K extends Capitalize<K>\n ? K extends `$${infer R}`\n ? O[K] & { [enumError]: `错误:枚举键名 ${K} 不能以 $ 符号开头` }\n : O[K]\n : O[K] & { [enumError]: `错误:枚举键名 ${K} 必须以大写字母开头` };\n};\n\ntype _ToOriginDefProp<T extends AnyObject> = {\n [K in keyof T as `$${K & string}`]: MergeIntersection<T[K] & { readonly key: K }>;\n};\n\ntype _KVRecord<T> = T extends Record<string, AnyObject>\n ? {\n readonly [K in keyof T]: T[K]['value'];\n }\n : never;\n\ntype _VKRecord<T> = T extends Record<string, AnyObject>\n ? MergeIntersection<\n UnionToIntersection<\n {\n [K in keyof T]: {\n [P in keyof T[K] as P extends 'value' ? T[K][P] & (string | number) : never]: K;\n };\n }[keyof T]\n >\n >\n : never;\n\nexport type EnumExpose<A extends EnumMetaAppend, E extends EnumDescription<A>> = _ToOriginDefProp<E> &\n _KVRecord<E> & {\n readonly definition: E;\n readonly descriptions: MergeIntersection<A & { key: keyof E }>[];\n readonly keys: UnionToTuple<keyof E>;\n readonly length: UnionToTuple<keyof E>['length'];\n readonly values: UnionToTuple<E[keyof E]['value']>;\n readonly kvRecord: _KVRecord<E>;\n readonly vkRecord: _VKRecord<E>;\n toKeyRecord: <P extends keyof A>(prop: P) => Record<keyof E, A[P]>;\n toValRecord: <P extends keyof A>(prop: P) => Record<E[keyof E]['value'], A[P]>;\n };\n\n/**\n * 定义一个枚举类型,如果需要类型提示,需要使用 declareEnum 函数定义枚举。\n * @template A - 枚举元数据附加类型,扩展自 EnumMetaAppend\n * @template E - 枚举描述类型,键为枚举键名,值为枚举元数据\n * @param {_CheckDefinition<E>} definition - 枚举定义对象\n * @returns {EnumExpose<A, E>} 返回枚举的完整暴露对象\n * @example\n * ```typescript\n * const Status = defineEnum({\n * Pending: { value: 0, label: '待处理' },\n * Approved: { value: 1, label: '已批准' }\n * });\n * ```\n *\n * @property {E} definition - 原始枚举定义对象\n * @property {Array<MergeIntersection<A & { key: keyof E }>>} descriptions - 枚举项的完整描述数组\n * @property {UnionToTuple<keyof E>} keys - 枚举键名的元组\n * @property {\"UnionToTuple<keyof E>[\\\"length\\\"]\"} length - 枚举项的数量\n * @property {UnionToTuple<E[keyof E][\"value\"]>} values - 枚举值的元组\n * @property {Record<keyof E, E[keyof E][\"value\"]>} kvRecord - 键到值的映射记录\n * @property {Record<E[keyof E][\"value\"], E[keyof E]>} vkRecord - 值到键的映射记录\n * @property {function} toKeyRecord - 根据属性名创建键到属性值的映射记录\n * @property {function} toValueRecord - 根据属性名创建值到属性值的映射记录\n */\nfunction _defineEnum<A extends EnumMetaAppend, const E extends EnumDescription<A>>(\n definition: _CheckDefinition<E>,\n): EnumExpose<A, E> {\n const keys = Object.keys(definition);\n\n return {\n ...[...Object.entries(definition)].reduce((acc, [key, dfn]) => {\n if (key[0].toUpperCase() !== key[0]) {\n throw new Error(`错误:枚举键名 ${key} 必须以大写字母开头`);\n }\n\n if (key.startsWith('$')) {\n throw new Error(`错误:枚举键名 ${key} 不能以 $ 符号开头`);\n }\n\n // @ts-ignore\n acc[key] = dfn.value;\n // @ts-ignore\n acc[`$${key}`] = { key, ...dfn };\n return acc;\n }, {}),\n definition,\n descriptions: keys.map((key) => ({\n key,\n ...definition[key],\n })),\n keys,\n length: keys.length,\n values: keys.map((key) => definition[key as keyof E].value),\n kvRecord: keys.reduce((acc, key) => {\n // @ts-ignore\n acc[key] = definition[key].value;\n return acc;\n }, {}),\n vkRecord: keys.reduce((acc, key) => {\n // @ts-ignore\n acc[definition[key].value] = key;\n return acc;\n }, {}),\n toKeyRecord<P extends keyof A>(prop: P) {\n return keys.reduce((acc, key) => {\n // @ts-ignore\n acc[key] = definition[key][prop];\n return acc;\n }, {});\n },\n toValRecord<P extends keyof A>(prop: P) {\n return keys.reduce(\n (acc, key) => {\n // @ts-ignore\n acc[definition[key].value] = definition[key][prop];\n return acc;\n },\n {} as Record<E[keyof E]['value'], A[P]>,\n );\n },\n } as unknown as EnumExpose<A, E>;\n}\n\n/**\n * 声明一个枚举工厂函数\n * @template A - 枚举元数据附加类型,扩展自 EnumMetaAppend\n * @returns {Object} 返回包含 define 方法的对象\n *\n * @property {function} define - 定义枚举的函数\n * @template E - 枚举描述类型\n * @param {_CheckDefinition<E>} definition - 枚举定义对象\n * @returns {EnumExpose<A, E>} 返回枚举的完整暴露对象\n * @example\n * ```typescript\n * const createStatusEnum = declareEnum<{ label: string }>();\n * const Status = createStatusEnum.define({\n * Pending: { value: 0, label: '待处理' },\n * Approved: { value: 1, label: '已批准' }\n * });\n * ```\n */\nexport function declareEnum<A extends EnumMetaAppend>() {\n return {\n define<const E extends EnumDescription<A>>(definition: _CheckDefinition<E>): EnumExpose<A, E> {\n return _defineEnum(definition);\n },\n };\n}\n"],"names":[],"mappings":";;AAuFA,SAAS,YACP,YACkB;AACZ,QAAA,OAAO,OAAO,KAAK,UAAU;AAE5B,SAAA;AAAA,IACL,GAAG,CAAC,GAAG,OAAO,QAAQ,UAAU,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM;AAC7D,UAAI,IAAI,CAAC,EAAE,kBAAkB,IAAI,CAAC,GAAG;AACnC,cAAM,IAAI,MAAM,WAAW,GAAG,YAAY;AAAA,MAAA;AAGxC,UAAA,IAAI,WAAW,GAAG,GAAG;AACvB,cAAM,IAAI,MAAM,WAAW,GAAG,aAAa;AAAA,MAAA;AAIzC,UAAA,GAAG,IAAI,IAAI;AAEf,UAAI,IAAI,GAAG,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI;AACxB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL;AAAA,IACA,cAAc,KAAK,IAAI,CAAC,SAAS;AAAA,MAC/B;AAAA,MACA,GAAG,WAAW,GAAG;AAAA,IAAA,EACjB;AAAA,IACF;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,QAAQ,KAAK,IAAI,CAAC,QAAQ,WAAW,GAAc,EAAE,KAAK;AAAA,IAC1D,UAAU,KAAK,OAAO,CAAC,KAAK,QAAQ;AAElC,UAAI,GAAG,IAAI,WAAW,GAAG,EAAE;AACpB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL,UAAU,KAAK,OAAO,CAAC,KAAK,QAAQ;AAElC,UAAI,WAAW,GAAG,EAAE,KAAK,IAAI;AACtB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL,YAA+B,MAAS;AACtC,aAAO,KAAK,OAAO,CAAC,KAAK,QAAQ;AAE/B,YAAI,GAAG,IAAI,WAAW,GAAG,EAAE,IAAI;AACxB,eAAA;AAAA,MACT,GAAG,EAAE;AAAA,IACP;AAAA,IACA,YAA+B,MAAS;AACtC,aAAO,KAAK;AAAA,QACV,CAAC,KAAK,QAAQ;AAER,cAAA,WAAW,GAAG,EAAE,KAAK,IAAI,WAAW,GAAG,EAAE,IAAI;AAC1C,iBAAA;AAAA,QACT;AAAA,QACA,CAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AACF;AAoBO,SAAS,cAAwC;AAC/C,SAAA;AAAA,IACL,OAA2C,YAAmD;AAC5F,aAAO,YAAY,UAAU;AAAA,IAAA;AAAA,EAEjC;AACF;;"}
|