@kikiutils/shared 15.1.0 → 15.1.1

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.
Files changed (58) hide show
  1. package/dist/buffer.d.ts.map +1 -1
  2. package/dist/buffer.js.map +1 -1
  3. package/dist/classes/path.d.ts.map +1 -1
  4. package/dist/classes/path.js.map +1 -1
  5. package/dist/classes/precision-number.d.ts.map +1 -1
  6. package/dist/classes/precision-number.js.map +1 -1
  7. package/dist/classes/ssh-client.js.map +1 -1
  8. package/dist/clipboard.d.ts.map +1 -1
  9. package/dist/clipboard.js.map +1 -1
  10. package/dist/consola.d.ts.map +1 -1
  11. package/dist/consola.js.map +1 -1
  12. package/dist/crypto-hash.d.ts.map +1 -1
  13. package/dist/crypto-hash.js.map +1 -1
  14. package/dist/datetime.d.ts.map +1 -1
  15. package/dist/datetime.js.map +1 -1
  16. package/dist/element-plus.d.ts.map +1 -1
  17. package/dist/element-plus.js.map +1 -1
  18. package/dist/enum.d.ts.map +1 -1
  19. package/dist/enum.js.map +1 -1
  20. package/dist/env.d.ts.map +1 -1
  21. package/dist/env.js.map +1 -1
  22. package/dist/event-awaiter.d.ts.map +1 -1
  23. package/dist/event-awaiter.js.map +1 -1
  24. package/dist/general.d.ts.map +1 -1
  25. package/dist/general.js.map +1 -1
  26. package/dist/hash.d.ts.map +1 -1
  27. package/dist/hash.js.map +1 -1
  28. package/dist/math.d.ts.map +1 -1
  29. package/dist/math.js.map +1 -1
  30. package/dist/number.d.ts.map +1 -1
  31. package/dist/number.js.map +1 -1
  32. package/dist/object.d.ts.map +1 -1
  33. package/dist/object.js.map +1 -1
  34. package/dist/pino.d.ts.map +1 -1
  35. package/dist/pino.js.map +1 -1
  36. package/dist/random.d.ts.map +1 -1
  37. package/dist/random.js.map +1 -1
  38. package/dist/storages/lru/keyed-store.js.map +1 -1
  39. package/dist/storages/redis/keyed-store.js.map +1 -1
  40. package/dist/storages/redis/msgpack.d.ts.map +1 -1
  41. package/dist/storages/redis/msgpack.js.map +1 -1
  42. package/dist/storages/redis/types.d.ts.map +1 -1
  43. package/dist/string.d.ts.map +1 -1
  44. package/dist/string.js.map +1 -1
  45. package/dist/time.d.ts.map +1 -1
  46. package/dist/time.js.map +1 -1
  47. package/dist/types/filtered-key-path.d.ts.map +1 -1
  48. package/dist/types/index.d.ts.map +1 -1
  49. package/dist/url.d.ts +27 -3
  50. package/dist/url.d.ts.map +1 -1
  51. package/dist/url.js +37 -4
  52. package/dist/url.js.map +1 -1
  53. package/dist/vue.d.ts.map +1 -1
  54. package/dist/vue.js.map +1 -1
  55. package/dist/web.d.ts.map +1 -1
  56. package/dist/web.js.map +1 -1
  57. package/package.json +8 -8
  58. package/src/url.ts +39 -7
@@ -1 +1 @@
1
- {"version":3,"file":"buffer.d.ts","names":[],"sources":["../src/buffer.ts"],"mappings":";;;;;;AAkCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAsB,QAAA,CAAS,KAAA,EAAO,WAAA,GAAW,OAAA,CAAA,MAAA,CAAA,eAAA"}
1
+ {"version":3,"file":"buffer.d.ts","names":[],"sources":["../src/buffer.ts"],"mappings":";;;;;;AAkCA;;;;;;;;;;;;;;;AAAiD;;;;;;;;;;;;;iBAA3B,QAAA,CAAS,KAAA,EAAO,WAAA,GAAW,OAAA,CAAA,MAAA,CAAA,eAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"buffer.js","names":[],"sources":["../src/buffer.ts"],"sourcesContent":["import { Buffer } from 'node:buffer';\n\nimport type { BinaryInput } from './types';\n\n/**\n * Converts various binary data types to a Node.js Buffer.\n *\n * This function provides a unified, efficient way to convert different binary formats\n * (Blob, Buffer, File, ArrayBuffer, or Uint8Array) into a Node.js Buffer.\n * It prioritizes zero-copy conversions for TypedArrays and ArrayBuffers to ensure\n * optimal performance.\n *\n * @param {ArrayBuffer | Blob | Buffer | File | Uint8Array} input - The binary data input to convert.\n * Supports Blob, Buffer, File, ArrayBuffer, and Uint8Array.\n *\n * @returns {Promise<Buffer>} A promise that resolves to a Node.js Buffer.\n *\n * @example\n * ```typescript\n * import { toBuffer } from '@kikiutils/shared/buffer';\n *\n * // From ArrayBuffer\n * const ab = new ArrayBuffer(8);\n * const bufferFromAB = await toBuffer(ab);\n *\n * // From Uint8Array (Zero-copy)\n * const u8 = new Uint8Array([10, 20, 30]);\n * const bufferFromU8 = await toBuffer(u8);\n *\n * // From Blob or File\n * const blob = new Blob(['data'], { type: 'text/plain' });\n * const bufferFromBlob = await toBuffer(blob);\n * ```\n */\nexport async function toBuffer(input: BinaryInput) {\n if (Buffer.isBuffer(input)) return input;\n if (input instanceof ArrayBuffer) return Buffer.from(input);\n if (input instanceof Uint8Array) return Buffer.from(input.buffer, input.byteOffset, input.byteLength);\n if (typeof input.arrayBuffer === 'function') return Buffer.from(await input.arrayBuffer());\n // eslint-disable-next-line style/max-len\n throw new TypeError('The provided input is not a supported binary type (Blob, Buffer, File, ArrayBuffer, or Uint8Array).');\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,eAAsB,SAAS,OAAoB;CAC/C,IAAI,OAAO,SAAS,MAAM,EAAE,OAAO;CACnC,IAAI,iBAAiB,aAAa,OAAO,OAAO,KAAK,MAAM;CAC3D,IAAI,iBAAiB,YAAY,OAAO,OAAO,KAAK,MAAM,QAAQ,MAAM,YAAY,MAAM,WAAW;CACrG,IAAI,OAAO,MAAM,gBAAgB,YAAY,OAAO,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;CAE1F,MAAM,IAAI,UAAU,sGAAsG"}
1
+ {"version":3,"file":"buffer.js","names":[],"sources":["../src/buffer.ts"],"sourcesContent":["import { Buffer } from 'node:buffer';\n\nimport type { BinaryInput } from './types';\n\n/**\n * Converts various binary data types to a Node.js Buffer.\n *\n * This function provides a unified, efficient way to convert different binary formats\n * (Blob, Buffer, File, ArrayBuffer, or Uint8Array) into a Node.js Buffer.\n * It prioritizes zero-copy conversions for TypedArrays and ArrayBuffers to ensure\n * optimal performance.\n *\n * @param {ArrayBuffer | Blob | Buffer | File | Uint8Array} input - The binary data input to convert.\n * Supports Blob, Buffer, File, ArrayBuffer, and Uint8Array.\n *\n * @returns {Promise<Buffer>} A promise that resolves to a Node.js Buffer.\n *\n * @example\n * ```typescript\n * import { toBuffer } from '@kikiutils/shared/buffer';\n *\n * // From ArrayBuffer\n * const ab = new ArrayBuffer(8);\n * const bufferFromAB = await toBuffer(ab);\n *\n * // From Uint8Array (Zero-copy)\n * const u8 = new Uint8Array([10, 20, 30]);\n * const bufferFromU8 = await toBuffer(u8);\n *\n * // From Blob or File\n * const blob = new Blob(['data'], { type: 'text/plain' });\n * const bufferFromBlob = await toBuffer(blob);\n * ```\n */\nexport async function toBuffer(input: BinaryInput) {\n if (Buffer.isBuffer(input)) return input;\n if (input instanceof ArrayBuffer) return Buffer.from(input);\n if (input instanceof Uint8Array) return Buffer.from(input.buffer, input.byteOffset, input.byteLength);\n if (typeof input.arrayBuffer === 'function') return Buffer.from(await input.arrayBuffer());\n // eslint-disable-next-line style/max-len\n throw new TypeError('The provided input is not a supported binary type (Blob, Buffer, File, ArrayBuffer, or Uint8Array).');\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,eAAsB,SAAS,OAAoB;CAC/C,IAAI,OAAO,SAAS,KAAK,GAAG,OAAO;CACnC,IAAI,iBAAiB,aAAa,OAAO,OAAO,KAAK,KAAK;CAC1D,IAAI,iBAAiB,YAAY,OAAO,OAAO,KAAK,MAAM,QAAQ,MAAM,YAAY,MAAM,UAAU;CACpG,IAAI,OAAO,MAAM,gBAAgB,YAAY,OAAO,OAAO,KAAK,MAAM,MAAM,YAAY,CAAC;CAEzF,MAAM,IAAI,UAAU,qGAAqG;AAC7H"}
@@ -1 +1 @@
1
- {"version":3,"file":"path.d.ts","names":[],"sources":["../../src/classes/path.ts"],"mappings":"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"}
1
+ {"version":3,"file":"path.d.ts","names":[],"sources":["../../src/classes/path.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"path.js","names":["#value","#toStrings","#newInstance"],"sources":["../../src/classes/path.ts"],"sourcesContent":["import type { Buffer } from 'node:buffer';\nimport type { Abortable } from 'node:events';\nimport type * as fs from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport {\n basename,\n dirname,\n extname,\n format,\n isAbsolute,\n join,\n normalize,\n parse,\n relative,\n resolve,\n toNamespacedPath,\n} from 'node:path';\nimport type * as nodePath from 'node:path';\n\ntype DropFirstParameters<T extends (...args: any) => any> = Parameters<T> extends [any, ...infer R] ? R : never;\n\n/**\n * Values accepted by the `Path` constructor and path-composition methods.\n */\nexport type PathLike = fs.PathLike | Path;\n\n/**\n * Class representing a file system path with various utility methods for path operations.\n *\n * All methods in the `Path` class are immutable, returning new instances with modified values\n * and leaving the original instance unchanged.\n */\nexport class Path {\n readonly #value: string;\n\n /**\n * Creates a normalized path value by joining the provided path segments.\n *\n * @param {PathLike[]} paths - Path segments accepted by Node.js `path.join` or another `Path` instance\n */\n constructor(...paths: PathLike[]) {\n this.#value = join(...this.#toStrings(paths));\n }\n\n // Symbols\n [Symbol.for('nodejs.util.inspect.custom')]() {\n return this.#value;\n }\n\n [Symbol.toPrimitive](hint: string) {\n if (hint === 'number') throw new TypeError('Cannot convert a Path to a number');\n return this.#value;\n }\n\n // Private methods\n #newInstance(...paths: PathLike[]) {\n return new Path(...paths);\n }\n\n #toStrings(paths: PathLike[]) {\n return paths.map((path) => path.toString());\n }\n\n // Public getters\n\n /**\n * @see {@link nodePath.dirname}\n */\n get parent() {\n return this.dirname();\n }\n\n /**\n * Returns the internal path string value.\n */\n get value() {\n return this.#value;\n }\n\n // Public static methods\n\n /**\n * @see {@link nodePath.format}\n */\n static format(pathObject: nodePath.FormatInputPathObject) {\n return new Path(format(pathObject));\n }\n\n /**\n * @see {@link nodePath.resolve}\n */\n static resolve(...paths: PathLike[]) {\n return new this(...paths).resolve();\n }\n\n // Public base methods\n\n /**\n * @see {@link nodePath.basename}\n */\n basename(suffix?: string) {\n return basename(this.#value, suffix);\n }\n\n /**\n * @see {@link nodePath.dirname}\n */\n dirname() {\n return this.#newInstance(dirname(this.#value));\n }\n\n /**\n * @see {@link nodePath.extname}\n */\n extname() {\n return extname(this.#value);\n }\n\n /**\n * @see {@link nodePath.isAbsolute}\n */\n isAbsolute() {\n return isAbsolute(this.#value);\n }\n\n /**\n * @see {@link nodePath.normalize}\n */\n normalize() {\n return this.#newInstance(normalize(this.#value));\n }\n\n /**\n * @see {@link nodePath.join}\n */\n join(...paths: PathLike[]) {\n return this.#newInstance(this.#value, ...this.#toStrings(paths));\n }\n\n /**\n * @see {@link nodePath.parse}\n */\n parse() {\n return parse(this.#value);\n }\n\n /**\n * @see {@link nodePath.relative}\n */\n relative(to: PathLike) {\n return this.#newInstance(relative(this.#value, to.toString()));\n }\n\n /**\n * @see {@link nodePath.resolve}\n */\n resolve() {\n return this.#newInstance(resolve(this.#value));\n }\n\n toJSON() {\n return this.#value;\n }\n\n /**\n * @see {@link nodePath.toNamespacedPath}\n */\n toNamespacedPath() {\n return toNamespacedPath(this.#value);\n }\n\n /**\n * Converts the Path instance to a string.\n * This method returns the internal path string value,\n * making it useful for implicit and explicit string conversions.\n */\n toString() {\n return this.#value;\n }\n\n // Some commonly used promise fs methods\n\n /**\n * @see {@link fsp.access}\n */\n access(...args: DropFirstParameters<typeof fsp.access>) {\n return fsp.access(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.appendFile}\n */\n appendFile(...args: DropFirstParameters<typeof fsp.appendFile>) {\n return fsp.appendFile(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.chmod}\n */\n chmod(...args: DropFirstParameters<typeof fsp.chmod>) {\n return fsp.chmod(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.chown}\n */\n chown(...args: DropFirstParameters<typeof fsp.chown>) {\n return fsp.chown(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.copyFile}\n */\n copyFile(...args: DropFirstParameters<typeof fsp.copyFile>) {\n return fsp.copyFile(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.mkdir}\n */\n mkdir(\n options: fs.MakeDirectoryOptions & {\n recursive: true;\n },\n ): Promise<string>;\n mkdir(\n options?:\n | (fs.MakeDirectoryOptions & {\n recursive?: false;\n })\n | fs.Mode\n | null,\n ): Promise<void>;\n mkdir(options?: fs.MakeDirectoryOptions | fs.Mode | null): Promise<string | undefined>;\n mkdir(...args: any): any {\n return fsp.mkdir(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.open}\n */\n open(...args: DropFirstParameters<typeof fsp.open>) {\n return fsp.open(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.readdir}\n */\n readdir(\n path: PathLike,\n options?:\n | BufferEncoding\n | (fs.ObjectEncodingOptions & {\n recursive?: boolean;\n withFileTypes?: false;\n })\n | null,\n ): Promise<string[]>;\n readdir(\n path: PathLike,\n options:\n | 'buffer'\n | {\n encoding: 'buffer';\n recursive?: boolean;\n withFileTypes?: false;\n },\n ): Promise<Buffer[]>;\n readdir(\n path: PathLike,\n options?:\n | BufferEncoding\n | (fs.ObjectEncodingOptions & {\n recursive?: boolean;\n withFileTypes?: false;\n })\n | null,\n ): Promise<Buffer[] | string[]>;\n readdir(\n path: PathLike,\n options: fs.ObjectEncodingOptions & {\n recursive?: boolean;\n withFileTypes: true;\n },\n ): Promise<fs.Dirent[]>;\n readdir(\n path: PathLike,\n options: {\n encoding: 'buffer';\n recursive?: boolean;\n withFileTypes: true;\n },\n ): Promise<fs.Dirent<Buffer>[]>;\n readdir(...args: any): any {\n return fsp.readdir(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.readFile}\n */\n readFile(\n options?:\n | (Abortable & {\n encoding?: null;\n flag?: fs.OpenMode;\n })\n | null,\n ): Promise<Buffer>;\n readFile(\n options:\n | (Abortable & {\n encoding: BufferEncoding;\n flag?: fs.OpenMode;\n })\n | BufferEncoding,\n ): Promise<string>;\n readFile(\n options?:\n | (\n & Abortable\n & fs.ObjectEncodingOptions\n & { flag?: fs.OpenMode }\n )\n | BufferEncoding\n | null,\n ): Promise<Buffer | string>;\n readFile(...args: any): any {\n return fsp.readFile(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.rename}\n */\n rename(newPath: PathLike) {\n return fsp.rename(this.#value, newPath.toString());\n }\n\n /**\n * @see {@link fsp.rm}\n */\n rm(...args: DropFirstParameters<typeof fsp.rm>) {\n return fsp.rm(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.rmdir}\n */\n rmdir(...args: DropFirstParameters<typeof fsp.rmdir>) {\n return fsp.rmdir(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.stat}\n */\n stat(\n opts?: fs.StatOptions & {\n bigint?: false;\n },\n ): Promise<fs.Stats>;\n stat(\n opts: fs.StatOptions & {\n bigint: true;\n },\n ): Promise<fs.BigIntStats>;\n stat(opts?: fs.StatOptions): Promise<fs.BigIntStats | fs.Stats>;\n stat(...args: any): any {\n return fsp.stat(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.truncate}\n */\n truncate(...args: DropFirstParameters<typeof fsp.truncate>) {\n return fsp.truncate(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.unlink}\n */\n unlink() {\n return fsp.unlink(this.#value);\n }\n\n /**\n * @see {@link fsp.writeFile}\n */\n writeFile(...args: DropFirstParameters<typeof fsp.writeFile>) {\n return fsp.writeFile(this.#value, ...args);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"path.js","names":["#value","#toStrings","#newInstance"],"sources":["../../src/classes/path.ts"],"sourcesContent":["import type { Buffer } from 'node:buffer';\nimport type { Abortable } from 'node:events';\nimport type * as fs from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport {\n basename,\n dirname,\n extname,\n format,\n isAbsolute,\n join,\n normalize,\n parse,\n relative,\n resolve,\n toNamespacedPath,\n} from 'node:path';\nimport type * as nodePath from 'node:path';\n\ntype DropFirstParameters<T extends (...args: any) => any> = Parameters<T> extends [any, ...infer R] ? R : never;\n\n/**\n * Values accepted by the `Path` constructor and path-composition methods.\n */\nexport type PathLike = fs.PathLike | Path;\n\n/**\n * Class representing a file system path with various utility methods for path operations.\n *\n * All methods in the `Path` class are immutable, returning new instances with modified values\n * and leaving the original instance unchanged.\n */\nexport class Path {\n readonly #value: string;\n\n /**\n * Creates a normalized path value by joining the provided path segments.\n *\n * @param {PathLike[]} paths - Path segments accepted by Node.js `path.join` or another `Path` instance\n */\n constructor(...paths: PathLike[]) {\n this.#value = join(...this.#toStrings(paths));\n }\n\n // Symbols\n [Symbol.for('nodejs.util.inspect.custom')]() {\n return this.#value;\n }\n\n [Symbol.toPrimitive](hint: string) {\n if (hint === 'number') throw new TypeError('Cannot convert a Path to a number');\n return this.#value;\n }\n\n // Private methods\n #newInstance(...paths: PathLike[]) {\n return new Path(...paths);\n }\n\n #toStrings(paths: PathLike[]) {\n return paths.map((path) => path.toString());\n }\n\n // Public getters\n\n /**\n * @see {@link nodePath.dirname}\n */\n get parent() {\n return this.dirname();\n }\n\n /**\n * Returns the internal path string value.\n */\n get value() {\n return this.#value;\n }\n\n // Public static methods\n\n /**\n * @see {@link nodePath.format}\n */\n static format(pathObject: nodePath.FormatInputPathObject) {\n return new Path(format(pathObject));\n }\n\n /**\n * @see {@link nodePath.resolve}\n */\n static resolve(...paths: PathLike[]) {\n return new this(...paths).resolve();\n }\n\n // Public base methods\n\n /**\n * @see {@link nodePath.basename}\n */\n basename(suffix?: string) {\n return basename(this.#value, suffix);\n }\n\n /**\n * @see {@link nodePath.dirname}\n */\n dirname() {\n return this.#newInstance(dirname(this.#value));\n }\n\n /**\n * @see {@link nodePath.extname}\n */\n extname() {\n return extname(this.#value);\n }\n\n /**\n * @see {@link nodePath.isAbsolute}\n */\n isAbsolute() {\n return isAbsolute(this.#value);\n }\n\n /**\n * @see {@link nodePath.normalize}\n */\n normalize() {\n return this.#newInstance(normalize(this.#value));\n }\n\n /**\n * @see {@link nodePath.join}\n */\n join(...paths: PathLike[]) {\n return this.#newInstance(this.#value, ...this.#toStrings(paths));\n }\n\n /**\n * @see {@link nodePath.parse}\n */\n parse() {\n return parse(this.#value);\n }\n\n /**\n * @see {@link nodePath.relative}\n */\n relative(to: PathLike) {\n return this.#newInstance(relative(this.#value, to.toString()));\n }\n\n /**\n * @see {@link nodePath.resolve}\n */\n resolve() {\n return this.#newInstance(resolve(this.#value));\n }\n\n toJSON() {\n return this.#value;\n }\n\n /**\n * @see {@link nodePath.toNamespacedPath}\n */\n toNamespacedPath() {\n return toNamespacedPath(this.#value);\n }\n\n /**\n * Converts the Path instance to a string.\n * This method returns the internal path string value,\n * making it useful for implicit and explicit string conversions.\n */\n toString() {\n return this.#value;\n }\n\n // Some commonly used promise fs methods\n\n /**\n * @see {@link fsp.access}\n */\n access(...args: DropFirstParameters<typeof fsp.access>) {\n return fsp.access(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.appendFile}\n */\n appendFile(...args: DropFirstParameters<typeof fsp.appendFile>) {\n return fsp.appendFile(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.chmod}\n */\n chmod(...args: DropFirstParameters<typeof fsp.chmod>) {\n return fsp.chmod(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.chown}\n */\n chown(...args: DropFirstParameters<typeof fsp.chown>) {\n return fsp.chown(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.copyFile}\n */\n copyFile(...args: DropFirstParameters<typeof fsp.copyFile>) {\n return fsp.copyFile(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.mkdir}\n */\n mkdir(\n options: fs.MakeDirectoryOptions & {\n recursive: true;\n },\n ): Promise<string>;\n mkdir(\n options?:\n | (fs.MakeDirectoryOptions & {\n recursive?: false;\n })\n | fs.Mode\n | null,\n ): Promise<void>;\n mkdir(options?: fs.MakeDirectoryOptions | fs.Mode | null): Promise<string | undefined>;\n mkdir(...args: any): any {\n return fsp.mkdir(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.open}\n */\n open(...args: DropFirstParameters<typeof fsp.open>) {\n return fsp.open(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.readdir}\n */\n readdir(\n path: PathLike,\n options?:\n | BufferEncoding\n | (fs.ObjectEncodingOptions & {\n recursive?: boolean;\n withFileTypes?: false;\n })\n | null,\n ): Promise<string[]>;\n readdir(\n path: PathLike,\n options:\n | 'buffer'\n | {\n encoding: 'buffer';\n recursive?: boolean;\n withFileTypes?: false;\n },\n ): Promise<Buffer[]>;\n readdir(\n path: PathLike,\n options?:\n | BufferEncoding\n | (fs.ObjectEncodingOptions & {\n recursive?: boolean;\n withFileTypes?: false;\n })\n | null,\n ): Promise<Buffer[] | string[]>;\n readdir(\n path: PathLike,\n options: fs.ObjectEncodingOptions & {\n recursive?: boolean;\n withFileTypes: true;\n },\n ): Promise<fs.Dirent[]>;\n readdir(\n path: PathLike,\n options: {\n encoding: 'buffer';\n recursive?: boolean;\n withFileTypes: true;\n },\n ): Promise<fs.Dirent<Buffer>[]>;\n readdir(...args: any): any {\n return fsp.readdir(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.readFile}\n */\n readFile(\n options?:\n | (Abortable & {\n encoding?: null;\n flag?: fs.OpenMode;\n })\n | null,\n ): Promise<Buffer>;\n readFile(\n options:\n | (Abortable & {\n encoding: BufferEncoding;\n flag?: fs.OpenMode;\n })\n | BufferEncoding,\n ): Promise<string>;\n readFile(\n options?:\n | (\n & Abortable\n & fs.ObjectEncodingOptions\n & { flag?: fs.OpenMode }\n )\n | BufferEncoding\n | null,\n ): Promise<Buffer | string>;\n readFile(...args: any): any {\n return fsp.readFile(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.rename}\n */\n rename(newPath: PathLike) {\n return fsp.rename(this.#value, newPath.toString());\n }\n\n /**\n * @see {@link fsp.rm}\n */\n rm(...args: DropFirstParameters<typeof fsp.rm>) {\n return fsp.rm(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.rmdir}\n */\n rmdir(...args: DropFirstParameters<typeof fsp.rmdir>) {\n return fsp.rmdir(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.stat}\n */\n stat(\n opts?: fs.StatOptions & {\n bigint?: false;\n },\n ): Promise<fs.Stats>;\n stat(\n opts: fs.StatOptions & {\n bigint: true;\n },\n ): Promise<fs.BigIntStats>;\n stat(opts?: fs.StatOptions): Promise<fs.BigIntStats | fs.Stats>;\n stat(...args: any): any {\n return fsp.stat(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.truncate}\n */\n truncate(...args: DropFirstParameters<typeof fsp.truncate>) {\n return fsp.truncate(this.#value, ...args);\n }\n\n /**\n * @see {@link fsp.unlink}\n */\n unlink() {\n return fsp.unlink(this.#value);\n }\n\n /**\n * @see {@link fsp.writeFile}\n */\n writeFile(...args: DropFirstParameters<typeof fsp.writeFile>) {\n return fsp.writeFile(this.#value, ...args);\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"precision-number.d.ts","names":[],"sources":["../../src/classes/precision-number.ts"],"mappings":";;;;;AAKA;KAAY,oBAAA,GAAuB,OAAA,CAAQ,KAAA,GAAQ,eAAA;EAAoB,QAAA;AAAA;;;;;;;AAqBvE;;;;;;;;;;;;;cAAa,eAAA;EAAA;EAyLE;;;;;;;cA3KP,KAAA,GAAO,oBAAA,EACP,aAAA,WACA,QAAA,GAAU,OAAA,CAAQ,QAAA;EAgSP;;;;;EAAA,CA3Qd,MAAA,CAAO,WAAA,EAAa,IAAA;EAqSkB;;;EAAA,IAlRnC,aAAA,CAAA;EAsTY;;;EAAA,IA/SZ,QAAA,CAAA,GAAQ,OAAA,CAAA,QAAA;EAiUsB;;;EAAA,IA1T9B,KAAA,CAAA;EA+VW;;;;;;;;;EAAA,OAlVR,OAAA,CACH,KAAA,EAAO,oBAAA,EACP,aAAA,WACA,QAAA,GAAU,OAAA,CAAQ,QAAA;EAtEA;;;;;EAkFtB,aAAA,CAAA;EAnCI;;;;;;;EA+CJ,IAAA,CAAA;EAxBc;;;;;;;;;;EAuCd,KAAA,CAAM,GAAA,EAAK,oBAAA,EAAsB,GAAA,EAAK,oBAAA;EAWjC;;;EAAL,KAAA,CAAA,GAAK,eAAA;EAuBL;;;;;;;EAZA,SAAA,CAAU,KAAA,EAAO,oBAAA;EAsCN;;;;;;;EA1BX,MAAA,CAAO,KAAA,EAAO,oBAAA;EA2Ed;;;;;;;EAhEA,KAAA,CAAA;EA8EM;;;EAtEN,EAAA,CAAG,KAAA,EAAO,oBAAA;EA0FV;;;EAnFA,GAAA,CAAI,KAAA,EAAO,oBAAA;EAuGX;;;EAhGA,QAAA,CAAA;EAwGa;;;EAjGb,SAAA,CAAA;EAgHA;;;EAzGA,KAAA,CAAA;EAqHU;;;EA9GV,UAAA,CAAA;EAqHA;;;EA9GA,UAAA,CAAA;EAyHA;;;EAlHA,MAAA,CAAA;EAgIe;;;EAzHf,EAAA,CAAG,KAAA,EAAO,oBAAA;EAoIM;;;EA7HhB,GAAA,CAAI,KAAA,EAAO,oBAAA;EAwIF;;;EAjIT,KAAA,CAAM,KAAA,EAAO,oBAAA;EAwIqB;;;;;;;EA5HlC,MAAA,CAAO,KAAA,EAAO,oBAAA;EA0JN;;;EAlJR,MAAA,CAAA;EAyJA;;;EAjJA,IAAA,CAAK,KAAA,EAAO,oBAAA;EAiJuB;;;;;;;EArInC,GAAA,CAAI,KAAA,EAAO,oBAAA;;;;EAQX,KAAA,CAAM,KAAA,EAAO,oBAAA;;;;EAQb,eAAA,CAAA,GAAe,eAAA;;;;EAOf,MAAA,CAAA,GAAM,eAAA;;;;;;;;;EAYN,SAAA,CAAU,GAAA,EAAK,oBAAA,EAAsB,GAAA,EAAK,oBAAA,GAAoB,eAAA;;;;EAO9D,WAAA,CAAY,KAAA,EAAO,oBAAA,GAAoB,eAAA;;;;EAWvC,OAAA,CAAA,GAAO,eAAA;;;;EAOP,MAAA,CAAA;;;;EAOA,OAAA,CAAQ,KAAA,EAAO,oBAAA,GAAoB,eAAA;;;;EAWnC,QAAA,CAAS,KAAA,EAAO,oBAAA,GAAoB,eAAA;;;;EAWpC,SAAA,CAAA,GAAS,eAAA;;;;EAOT,MAAA,CAAO,KAAA,EAAO,oBAAA,GAAoB,eAAA;;;;EAOlC,KAAA,CAAM,KAAA,EAAO,oBAAA,GAAoB,eAAA;;;;;;EASjC,QAAA,CAAA;;;;EAOA,QAAA,CAAA;;;;EAOA,OAAA,CAAQ,aAAA,WAA6C,QAAA,GAAU,OAAA,CAAQ,QAAA;;;;EAOvE,OAAA,CAAQ,KAAA,EAAO,oBAAA,GAAoB,eAAA;AAAA"}
1
+ {"version":3,"file":"precision-number.d.ts","names":[],"sources":["../../src/classes/precision-number.ts"],"mappings":";;;;;AAKA;KAAY,oBAAA,GAAuB,OAAA,CAAQ,KAAA,GAAQ,eAAe;EAAK,QAAA;AAAA;;;;;;AAAQ;AAqB/E;;;;;;;;;;;;;cAAa,eAAA;EAAA;EAyLE;;;;;;;cA3KP,KAAA,GAAO,oBAAA,EACP,aAAA,WACA,QAAA,GAAU,OAAA,CAAQ,QAAA;EAgSP;;;;;EAAA,CA3Qd,MAAA,CAAO,WAAA,EAAa,IAAA;EAqSkB;;;EAAA,IAlRnC,aAAA,CAAA;EAsTY;;;EAAA,IA/SZ,QAAA,CAAA,GAAQ,OAAA,CAAA,QAAA;EAiUsB;;;EAAA,IA1T9B,KAAA,CAAA;EA+VW;;;;;;;;;EAAA,OAlVR,OAAA,CACH,KAAA,EAAO,oBAAA,EACP,aAAA,WACA,QAAA,GAAU,OAAA,CAAQ,QAAA;EAtEA;;;;;EAkFtB,aAAA,CAAA;EAnCI;;;;;;;EA+CJ,IAAA,CAAA;EAxBc;;;;;;;;;;EAuCd,KAAA,CAAM,GAAA,EAAK,oBAAA,EAAsB,GAAA,EAAK,oBAAA;EAWjC;;;EAAL,KAAA,CAAA,GAAK,eAAA;EAuBL;;;;;;;EAZA,SAAA,CAAU,KAAA,EAAO,oBAAA;EAsCN;;;;;;;EA1BX,MAAA,CAAO,KAAA,EAAO,oBAAA;EA2Ed;;;;;;;EAhEA,KAAA,CAAA;EA8EM;;;EAtEN,EAAA,CAAG,KAAA,EAAO,oBAAA;EA0FV;;;EAnFA,GAAA,CAAI,KAAA,EAAO,oBAAA;EAuGX;;;EAhGA,QAAA,CAAA;EAwGa;;;EAjGb,SAAA,CAAA;EAgHA;;;EAzGA,KAAA,CAAA;EAqHU;;;EA9GV,UAAA,CAAA;EAqHA;;;EA9GA,UAAA,CAAA;EAyHA;;;EAlHA,MAAA,CAAA;EAgIe;;;EAzHf,EAAA,CAAG,KAAA,EAAO,oBAAA;EAoIM;;;EA7HhB,GAAA,CAAI,KAAA,EAAO,oBAAA;EAwIF;;;EAjIT,KAAA,CAAM,KAAA,EAAO,oBAAA;EAwIqB;;;;;;;EA5HlC,MAAA,CAAO,KAAA,EAAO,oBAAA;EA0JN;;;EAlJR,MAAA,CAAA;EAyJA;;;EAjJA,IAAA,CAAK,KAAA,EAAO,oBAAA;EAiJuB;AAAA;;;;;;EArInC,GAAA,CAAI,KAAA,EAAO,oBAAA;;;;EAQX,KAAA,CAAM,KAAA,EAAO,oBAAA;;;;EAQb,eAAA,CAAA,GAAe,eAAA;;;;EAOf,MAAA,CAAA,GAAM,eAAA;;;;;;;;;EAYN,SAAA,CAAU,GAAA,EAAK,oBAAA,EAAsB,GAAA,EAAK,oBAAA,GAAoB,eAAA;;;;EAO9D,WAAA,CAAY,KAAA,EAAO,oBAAA,GAAoB,eAAA;;;;EAWvC,OAAA,CAAA,GAAO,eAAA;;;;EAOP,MAAA,CAAA;;;;EAOA,OAAA,CAAQ,KAAA,EAAO,oBAAA,GAAoB,eAAA;;;;EAWnC,QAAA,CAAS,KAAA,EAAO,oBAAA,GAAoB,eAAA;;;;EAWpC,SAAA,CAAA,GAAS,eAAA;;;;EAOT,MAAA,CAAO,KAAA,EAAO,oBAAA,GAAoB,eAAA;;;;EAOlC,KAAA,CAAM,KAAA,EAAO,oBAAA,GAAoB,eAAA;;;;;;EASjC,QAAA,CAAA;;;;EAOA,QAAA,CAAA;;;;EAOA,OAAA,CAAQ,aAAA,WAA6C,QAAA,GAAU,OAAA,CAAQ,QAAA;;;;EAOvE,OAAA,CAAQ,KAAA,EAAO,oBAAA,GAAoB,eAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"precision-number.js","names":["#decimalPlaces","#rounding","#decimal","#decimalToFixedDecimal","#valueToString"],"sources":["../../src/classes/precision-number.ts"],"sourcesContent":["import { Decimal } from 'decimal.js';\n\n/**\n * Values accepted by `PrecisionNumber` constructors and arithmetic methods.\n */\nexport type PrecisionNumberValue = Decimal.Value | PrecisionNumber | { toString: () => string };\n\n/**\n * Chainable fixed-decimal wrapper around `decimal.js`.\n *\n * `PrecisionNumber` stores values as `Decimal`, rounds every mutating operation to\n * the configured decimal places, and exposes both mutable and immutable arithmetic\n * methods. Mutable methods (`plus`, `minus`, `times`, `dividedBy`, `modulo`,\n * `pow`, `clamp`, `ceil`, `floor`, `negate`, `absoluteValue`) update the current\n * instance and return `this`; immutable methods prefixed with `to` return a new\n * `PrecisionNumber` with the same precision settings.\n *\n * @example\n * ```typescript\n * import { PrecisionNumber } from '@kikiutils/shared/classes/precision-number';\n *\n * const value = new PrecisionNumber('1.239', 2).plus('2.111');\n * value.toString(); // '3.35'\n * value.toMinus('1').toString(); // '2.35' (original value remains '3.35')\n * ```\n */\nexport class PrecisionNumber {\n // Private properties\n readonly #decimalPlaces: number;\n readonly #rounding: Decimal.Rounding;\n #decimal: Decimal;\n\n /**\n * Creates a fixed-decimal number.\n *\n * @param {PrecisionNumberValue} [value] - Initial value (default: `'0'`)\n * @param {number} [decimalPlaces] - Decimal places retained after operations (default: `2`)\n * @param {Decimal.Rounding} [rounding] - Decimal.js rounding mode (default: `Decimal.ROUND_DOWN`)\n */\n constructor(\n value: PrecisionNumberValue = '0',\n decimalPlaces: number = 2,\n rounding: Decimal.Rounding = Decimal.ROUND_DOWN,\n ) {\n this.#decimalPlaces = decimalPlaces;\n this.#rounding = rounding;\n this.#decimal = this.#decimalToFixedDecimal(new Decimal(value.toString().trim()));\n }\n\n // Symbols\n\n /**\n * Returns the formatted value when inspected by Node.js utilities.\n */\n [Symbol.for('nodejs.util.inspect.custom')]() {\n return this.value;\n }\n\n /**\n * Converts to a number for numeric coercion and to the fixed string otherwise.\n *\n * @param {string} hint - JavaScript primitive-conversion hint\n */\n [Symbol.toPrimitive](hint: string) {\n if (hint === 'number') return this.#decimal.toNumber();\n return this.value;\n }\n\n // Private methods\n #decimalToFixedDecimal(decimal: Decimal) {\n return decimal.toDecimalPlaces(this.#decimalPlaces, this.#rounding);\n }\n\n #valueToString(value: PrecisionNumberValue) {\n return value.toString().trim();\n }\n\n // Public getters\n\n /**\n * Decimal places retained by mutating operations and default formatting.\n */\n get decimalPlaces() {\n return this.#decimalPlaces;\n }\n\n /**\n * Decimal.js rounding mode used by mutating operations and default formatting.\n */\n get rounding() {\n return this.#rounding;\n }\n\n /**\n * Fixed-decimal string using the instance precision and rounding mode.\n */\n get value() {\n return this.#decimal.toFixed(this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Formats a value with decimal.js without creating a reusable instance.\n *\n * @param {PrecisionNumberValue} value - Value to format\n * @param {number} [decimalPlaces] - Decimal places to output (default: `2`)\n * @param {Decimal.Rounding} [rounding] - Decimal.js rounding mode (default: `Decimal.ROUND_DOWN`)\n *\n * @returns {string} Fixed-decimal string\n */\n static toFixed(\n value: PrecisionNumberValue,\n decimalPlaces: number = 2,\n rounding: Decimal.Rounding = Decimal.ROUND_DOWN,\n ) {\n return new Decimal(value.toString().trim()).toFixed(decimalPlaces, rounding);\n }\n\n // Public methods\n\n /**\n * Replaces the current value with its absolute value.\n *\n * @returns {this} The current instance for chaining\n */\n absoluteValue() {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.absoluteValue());\n return this;\n }\n\n /**\n * Rounds the current value up to the nearest integer in place.\n *\n * The stored value still uses this instance's configured decimal places for output.\n *\n * @returns {this} The current instance for chaining\n */\n ceil() {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.ceil());\n return this;\n }\n\n /**\n * Restricts the current value to the inclusive range `[min, max]` in place.\n *\n * @param {PrecisionNumberValue} min - Lower bound\n * @param {PrecisionNumberValue} max - Upper bound\n *\n * @returns {this} The current instance for chaining\n *\n * @throws {Error} If `min` is greater than `max`\n */\n clamp(min: PrecisionNumberValue, max: PrecisionNumberValue) {\n const minDecimal = new Decimal(this.#valueToString(min));\n const maxDecimal = new Decimal(this.#valueToString(max));\n if (minDecimal.gt(maxDecimal)) throw new Error('Invalid clamp range: min cannot be greater than max');\n this.#decimal = this.#decimalToFixedDecimal(Decimal.min(Decimal.max(this.#decimal, minDecimal), maxDecimal));\n return this;\n }\n\n /**\n * Returns a new instance with the same value, decimal places, and rounding mode.\n */\n clone() {\n return new PrecisionNumber(this.#decimal, this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Divides the current value by another value in place.\n *\n * @param {PrecisionNumberValue} value - Divisor\n *\n * @returns {this} The current instance for chaining\n */\n dividedBy(value: PrecisionNumberValue) {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.dividedBy(this.#valueToString(value)));\n return this;\n }\n\n /**\n * Checks whether the current value equals another value.\n *\n * @param {PrecisionNumberValue} value - Value to compare\n *\n * @returns {boolean} `true` when both numeric values are equal\n */\n equals(value: PrecisionNumberValue) {\n return this.#decimal.equals(this.#valueToString(value));\n }\n\n /**\n * Rounds the current value down to the nearest integer in place.\n *\n * The stored value still uses this instance's configured decimal places for output.\n *\n * @returns {this} The current instance for chaining\n */\n floor() {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.floor());\n return this;\n }\n\n /**\n * Checks whether the current value is greater than another value.\n */\n gt(value: PrecisionNumberValue) {\n return this.#decimal.gt(this.#valueToString(value));\n }\n\n /**\n * Checks whether the current value is greater than or equal to another value.\n */\n gte(value: PrecisionNumberValue) {\n return this.#decimal.gte(this.#valueToString(value));\n }\n\n /**\n * Checks whether the current value is finite.\n */\n isFinite() {\n return this.#decimal.isFinite();\n }\n\n /**\n * Checks whether the current value is an integer.\n */\n isInteger() {\n return this.#decimal.isInteger();\n }\n\n /**\n * Checks whether the current value is `NaN`.\n */\n isNaN() {\n return this.#decimal.isNaN();\n }\n\n /**\n * Checks whether the current value is negative.\n */\n isNegative() {\n return this.#decimal.isNegative();\n }\n\n /**\n * Checks whether the current value is positive.\n */\n isPositive() {\n return this.#decimal.isPositive();\n }\n\n /**\n * Checks whether the current value is zero.\n */\n isZero() {\n return this.#decimal.isZero();\n }\n\n /**\n * Checks whether the current value is less than another value.\n */\n lt(value: PrecisionNumberValue) {\n return this.#decimal.lt(this.#valueToString(value));\n }\n\n /**\n * Checks whether the current value is less than or equal to another value.\n */\n lte(value: PrecisionNumberValue) {\n return this.#decimal.lte(this.#valueToString(value));\n }\n\n /**\n * Subtracts another value from the current value in place.\n */\n minus(value: PrecisionNumberValue) {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.minus(this.#valueToString(value)));\n return this;\n }\n\n /**\n * Replaces the current value with the remainder after division by another value.\n *\n * @param {PrecisionNumberValue} value - Divisor used to compute the remainder\n *\n * @returns {this} The current instance for chaining\n */\n modulo(value: PrecisionNumberValue) {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.modulo(this.#valueToString(value)));\n return this;\n }\n\n /**\n * Negates the current value in place.\n */\n negate() {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.negated());\n return this;\n }\n\n /**\n * Adds another value to the current value in place.\n */\n plus(value: PrecisionNumberValue) {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.plus(this.#valueToString(value)));\n return this;\n }\n\n /**\n * Raises the current value to an exponent in place.\n *\n * @param {PrecisionNumberValue} value - Exponent\n *\n * @returns {this} The current instance for chaining\n */\n pow(value: PrecisionNumberValue) {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.pow(this.#valueToString(value)));\n return this;\n }\n\n /**\n * Multiplies the current value by another value in place.\n */\n times(value: PrecisionNumberValue) {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.times(this.#valueToString(value)));\n return this;\n }\n\n /**\n * Returns a new instance with the absolute value.\n */\n toAbsoluteValue() {\n return new PrecisionNumber(this.#decimal.absoluteValue(), this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Returns a new instance rounded up to the nearest integer.\n */\n toCeil() {\n return new PrecisionNumber(this.#decimal.ceil(), this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Returns a new instance restricted to the inclusive range `[min, max]`.\n *\n * @param {PrecisionNumberValue} min - Lower bound\n * @param {PrecisionNumberValue} max - Upper bound\n *\n * @throws {Error} If `min` is greater than `max`\n */\n toClamped(min: PrecisionNumberValue, max: PrecisionNumberValue) {\n return this.clone().clamp(min, max);\n }\n\n /**\n * Returns a new instance divided by another value.\n */\n toDividedBy(value: PrecisionNumberValue) {\n return new PrecisionNumber(\n this.#decimal.dividedBy(this.#valueToString(value)),\n this.#decimalPlaces,\n this.#rounding,\n );\n }\n\n /**\n * Returns a new instance rounded down to the nearest integer.\n */\n toFloor() {\n return new PrecisionNumber(this.#decimal.floor(), this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Serializes to the fixed-decimal string.\n */\n toJSON() {\n return this.value;\n }\n\n /**\n * Returns a new instance with another value subtracted.\n */\n toMinus(value: PrecisionNumberValue) {\n return new PrecisionNumber(\n this.#decimal.minus(this.#valueToString(value)),\n this.#decimalPlaces,\n this.#rounding,\n );\n }\n\n /**\n * Returns a new instance with the remainder after division by another value.\n */\n toModulo(value: PrecisionNumberValue) {\n return new PrecisionNumber(\n this.#decimal.modulo(this.#valueToString(value)),\n this.#decimalPlaces,\n this.#rounding,\n );\n }\n\n /**\n * Returns a new instance with the value negated.\n */\n toNegated() {\n return new PrecisionNumber(this.#decimal.negated(), this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Returns a new instance with another value added.\n */\n toPlus(value: PrecisionNumberValue) {\n return new PrecisionNumber(this.#decimal.plus(this.#valueToString(value)), this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Returns a new instance raised to an exponent.\n */\n toPow(value: PrecisionNumberValue) {\n return new PrecisionNumber(this.#decimal.pow(this.#valueToString(value)), this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Converts the current value to a JavaScript number.\n *\n * Use `toString`/`value` when preserving decimal precision is more important than native-number ergonomics.\n */\n toNumber() {\n return this.#decimal.toNumber();\n }\n\n /**\n * Converts the current value to its fixed-decimal string.\n */\n toString() {\n return this.value;\n }\n\n /**\n * Formats the current value with custom precision and rounding for this call only.\n */\n toFixed(decimalPlaces: number = this.#decimalPlaces, rounding: Decimal.Rounding = this.#rounding) {\n return this.#decimal.toFixed(decimalPlaces, rounding);\n }\n\n /**\n * Returns a new instance multiplied by another value.\n */\n toTimes(value: PrecisionNumberValue) {\n return new PrecisionNumber(\n this.#decimal.times(this.#valueToString(value)),\n this.#decimalPlaces,\n this.#rounding,\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"precision-number.js","names":["#decimalPlaces","#rounding","#decimal","#decimalToFixedDecimal","#valueToString"],"sources":["../../src/classes/precision-number.ts"],"sourcesContent":["import { Decimal } from 'decimal.js';\n\n/**\n * Values accepted by `PrecisionNumber` constructors and arithmetic methods.\n */\nexport type PrecisionNumberValue = Decimal.Value | PrecisionNumber | { toString: () => string };\n\n/**\n * Chainable fixed-decimal wrapper around `decimal.js`.\n *\n * `PrecisionNumber` stores values as `Decimal`, rounds every mutating operation to\n * the configured decimal places, and exposes both mutable and immutable arithmetic\n * methods. Mutable methods (`plus`, `minus`, `times`, `dividedBy`, `modulo`,\n * `pow`, `clamp`, `ceil`, `floor`, `negate`, `absoluteValue`) update the current\n * instance and return `this`; immutable methods prefixed with `to` return a new\n * `PrecisionNumber` with the same precision settings.\n *\n * @example\n * ```typescript\n * import { PrecisionNumber } from '@kikiutils/shared/classes/precision-number';\n *\n * const value = new PrecisionNumber('1.239', 2).plus('2.111');\n * value.toString(); // '3.35'\n * value.toMinus('1').toString(); // '2.35' (original value remains '3.35')\n * ```\n */\nexport class PrecisionNumber {\n // Private properties\n readonly #decimalPlaces: number;\n readonly #rounding: Decimal.Rounding;\n #decimal: Decimal;\n\n /**\n * Creates a fixed-decimal number.\n *\n * @param {PrecisionNumberValue} [value] - Initial value (default: `'0'`)\n * @param {number} [decimalPlaces] - Decimal places retained after operations (default: `2`)\n * @param {Decimal.Rounding} [rounding] - Decimal.js rounding mode (default: `Decimal.ROUND_DOWN`)\n */\n constructor(\n value: PrecisionNumberValue = '0',\n decimalPlaces: number = 2,\n rounding: Decimal.Rounding = Decimal.ROUND_DOWN,\n ) {\n this.#decimalPlaces = decimalPlaces;\n this.#rounding = rounding;\n this.#decimal = this.#decimalToFixedDecimal(new Decimal(value.toString().trim()));\n }\n\n // Symbols\n\n /**\n * Returns the formatted value when inspected by Node.js utilities.\n */\n [Symbol.for('nodejs.util.inspect.custom')]() {\n return this.value;\n }\n\n /**\n * Converts to a number for numeric coercion and to the fixed string otherwise.\n *\n * @param {string} hint - JavaScript primitive-conversion hint\n */\n [Symbol.toPrimitive](hint: string) {\n if (hint === 'number') return this.#decimal.toNumber();\n return this.value;\n }\n\n // Private methods\n #decimalToFixedDecimal(decimal: Decimal) {\n return decimal.toDecimalPlaces(this.#decimalPlaces, this.#rounding);\n }\n\n #valueToString(value: PrecisionNumberValue) {\n return value.toString().trim();\n }\n\n // Public getters\n\n /**\n * Decimal places retained by mutating operations and default formatting.\n */\n get decimalPlaces() {\n return this.#decimalPlaces;\n }\n\n /**\n * Decimal.js rounding mode used by mutating operations and default formatting.\n */\n get rounding() {\n return this.#rounding;\n }\n\n /**\n * Fixed-decimal string using the instance precision and rounding mode.\n */\n get value() {\n return this.#decimal.toFixed(this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Formats a value with decimal.js without creating a reusable instance.\n *\n * @param {PrecisionNumberValue} value - Value to format\n * @param {number} [decimalPlaces] - Decimal places to output (default: `2`)\n * @param {Decimal.Rounding} [rounding] - Decimal.js rounding mode (default: `Decimal.ROUND_DOWN`)\n *\n * @returns {string} Fixed-decimal string\n */\n static toFixed(\n value: PrecisionNumberValue,\n decimalPlaces: number = 2,\n rounding: Decimal.Rounding = Decimal.ROUND_DOWN,\n ) {\n return new Decimal(value.toString().trim()).toFixed(decimalPlaces, rounding);\n }\n\n // Public methods\n\n /**\n * Replaces the current value with its absolute value.\n *\n * @returns {this} The current instance for chaining\n */\n absoluteValue() {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.absoluteValue());\n return this;\n }\n\n /**\n * Rounds the current value up to the nearest integer in place.\n *\n * The stored value still uses this instance's configured decimal places for output.\n *\n * @returns {this} The current instance for chaining\n */\n ceil() {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.ceil());\n return this;\n }\n\n /**\n * Restricts the current value to the inclusive range `[min, max]` in place.\n *\n * @param {PrecisionNumberValue} min - Lower bound\n * @param {PrecisionNumberValue} max - Upper bound\n *\n * @returns {this} The current instance for chaining\n *\n * @throws {Error} If `min` is greater than `max`\n */\n clamp(min: PrecisionNumberValue, max: PrecisionNumberValue) {\n const minDecimal = new Decimal(this.#valueToString(min));\n const maxDecimal = new Decimal(this.#valueToString(max));\n if (minDecimal.gt(maxDecimal)) throw new Error('Invalid clamp range: min cannot be greater than max');\n this.#decimal = this.#decimalToFixedDecimal(Decimal.min(Decimal.max(this.#decimal, minDecimal), maxDecimal));\n return this;\n }\n\n /**\n * Returns a new instance with the same value, decimal places, and rounding mode.\n */\n clone() {\n return new PrecisionNumber(this.#decimal, this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Divides the current value by another value in place.\n *\n * @param {PrecisionNumberValue} value - Divisor\n *\n * @returns {this} The current instance for chaining\n */\n dividedBy(value: PrecisionNumberValue) {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.dividedBy(this.#valueToString(value)));\n return this;\n }\n\n /**\n * Checks whether the current value equals another value.\n *\n * @param {PrecisionNumberValue} value - Value to compare\n *\n * @returns {boolean} `true` when both numeric values are equal\n */\n equals(value: PrecisionNumberValue) {\n return this.#decimal.equals(this.#valueToString(value));\n }\n\n /**\n * Rounds the current value down to the nearest integer in place.\n *\n * The stored value still uses this instance's configured decimal places for output.\n *\n * @returns {this} The current instance for chaining\n */\n floor() {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.floor());\n return this;\n }\n\n /**\n * Checks whether the current value is greater than another value.\n */\n gt(value: PrecisionNumberValue) {\n return this.#decimal.gt(this.#valueToString(value));\n }\n\n /**\n * Checks whether the current value is greater than or equal to another value.\n */\n gte(value: PrecisionNumberValue) {\n return this.#decimal.gte(this.#valueToString(value));\n }\n\n /**\n * Checks whether the current value is finite.\n */\n isFinite() {\n return this.#decimal.isFinite();\n }\n\n /**\n * Checks whether the current value is an integer.\n */\n isInteger() {\n return this.#decimal.isInteger();\n }\n\n /**\n * Checks whether the current value is `NaN`.\n */\n isNaN() {\n return this.#decimal.isNaN();\n }\n\n /**\n * Checks whether the current value is negative.\n */\n isNegative() {\n return this.#decimal.isNegative();\n }\n\n /**\n * Checks whether the current value is positive.\n */\n isPositive() {\n return this.#decimal.isPositive();\n }\n\n /**\n * Checks whether the current value is zero.\n */\n isZero() {\n return this.#decimal.isZero();\n }\n\n /**\n * Checks whether the current value is less than another value.\n */\n lt(value: PrecisionNumberValue) {\n return this.#decimal.lt(this.#valueToString(value));\n }\n\n /**\n * Checks whether the current value is less than or equal to another value.\n */\n lte(value: PrecisionNumberValue) {\n return this.#decimal.lte(this.#valueToString(value));\n }\n\n /**\n * Subtracts another value from the current value in place.\n */\n minus(value: PrecisionNumberValue) {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.minus(this.#valueToString(value)));\n return this;\n }\n\n /**\n * Replaces the current value with the remainder after division by another value.\n *\n * @param {PrecisionNumberValue} value - Divisor used to compute the remainder\n *\n * @returns {this} The current instance for chaining\n */\n modulo(value: PrecisionNumberValue) {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.modulo(this.#valueToString(value)));\n return this;\n }\n\n /**\n * Negates the current value in place.\n */\n negate() {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.negated());\n return this;\n }\n\n /**\n * Adds another value to the current value in place.\n */\n plus(value: PrecisionNumberValue) {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.plus(this.#valueToString(value)));\n return this;\n }\n\n /**\n * Raises the current value to an exponent in place.\n *\n * @param {PrecisionNumberValue} value - Exponent\n *\n * @returns {this} The current instance for chaining\n */\n pow(value: PrecisionNumberValue) {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.pow(this.#valueToString(value)));\n return this;\n }\n\n /**\n * Multiplies the current value by another value in place.\n */\n times(value: PrecisionNumberValue) {\n this.#decimal = this.#decimalToFixedDecimal(this.#decimal.times(this.#valueToString(value)));\n return this;\n }\n\n /**\n * Returns a new instance with the absolute value.\n */\n toAbsoluteValue() {\n return new PrecisionNumber(this.#decimal.absoluteValue(), this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Returns a new instance rounded up to the nearest integer.\n */\n toCeil() {\n return new PrecisionNumber(this.#decimal.ceil(), this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Returns a new instance restricted to the inclusive range `[min, max]`.\n *\n * @param {PrecisionNumberValue} min - Lower bound\n * @param {PrecisionNumberValue} max - Upper bound\n *\n * @throws {Error} If `min` is greater than `max`\n */\n toClamped(min: PrecisionNumberValue, max: PrecisionNumberValue) {\n return this.clone().clamp(min, max);\n }\n\n /**\n * Returns a new instance divided by another value.\n */\n toDividedBy(value: PrecisionNumberValue) {\n return new PrecisionNumber(\n this.#decimal.dividedBy(this.#valueToString(value)),\n this.#decimalPlaces,\n this.#rounding,\n );\n }\n\n /**\n * Returns a new instance rounded down to the nearest integer.\n */\n toFloor() {\n return new PrecisionNumber(this.#decimal.floor(), this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Serializes to the fixed-decimal string.\n */\n toJSON() {\n return this.value;\n }\n\n /**\n * Returns a new instance with another value subtracted.\n */\n toMinus(value: PrecisionNumberValue) {\n return new PrecisionNumber(\n this.#decimal.minus(this.#valueToString(value)),\n this.#decimalPlaces,\n this.#rounding,\n );\n }\n\n /**\n * Returns a new instance with the remainder after division by another value.\n */\n toModulo(value: PrecisionNumberValue) {\n return new PrecisionNumber(\n this.#decimal.modulo(this.#valueToString(value)),\n this.#decimalPlaces,\n this.#rounding,\n );\n }\n\n /**\n * Returns a new instance with the value negated.\n */\n toNegated() {\n return new PrecisionNumber(this.#decimal.negated(), this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Returns a new instance with another value added.\n */\n toPlus(value: PrecisionNumberValue) {\n return new PrecisionNumber(this.#decimal.plus(this.#valueToString(value)), this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Returns a new instance raised to an exponent.\n */\n toPow(value: PrecisionNumberValue) {\n return new PrecisionNumber(this.#decimal.pow(this.#valueToString(value)), this.#decimalPlaces, this.#rounding);\n }\n\n /**\n * Converts the current value to a JavaScript number.\n *\n * Use `toString`/`value` when preserving decimal precision is more important than native-number ergonomics.\n */\n toNumber() {\n return this.#decimal.toNumber();\n }\n\n /**\n * Converts the current value to its fixed-decimal string.\n */\n toString() {\n return this.value;\n }\n\n /**\n * Formats the current value with custom precision and rounding for this call only.\n */\n toFixed(decimalPlaces: number = this.#decimalPlaces, rounding: Decimal.Rounding = this.#rounding) {\n return this.#decimal.toFixed(decimalPlaces, rounding);\n }\n\n /**\n * Returns a new instance multiplied by another value.\n */\n toTimes(value: PrecisionNumberValue) {\n return new PrecisionNumber(\n this.#decimal.times(this.#valueToString(value)),\n this.#decimalPlaces,\n this.#rounding,\n );\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ssh-client.js","names":["#connectConfig","#logger","#nodeSsh"],"sources":["../../src/classes/ssh-client.ts"],"sourcesContent":["import { createConsola } from 'consola';\nimport type { ConsolaInstance } from 'consola';\nimport { NodeSSH } from 'node-ssh';\nimport type {\n Config,\n SSHExecCommandOptions,\n SSHGetPutDirectoryOptions,\n SSHPutFilesOptions,\n} from 'node-ssh';\nimport type {\n SFTPWrapper,\n TransferOptions,\n} from 'ssh2';\n\nimport type { Nullable } from '../types';\n\nimport type { PathLike } from './path';\n\nconst loggerLevelStringToConsolaLogLevelMap = {\n debug: 4,\n error: 0,\n fatal: 0,\n info: 3,\n normal: 2,\n silent: -999,\n trace: 5,\n verbose: 999,\n warn: 1,\n} as const;\n\nexport class SshClient {\n readonly #connectConfig: Config;\n readonly #logger: ConsolaInstance;\n\n #nodeSsh: NodeSSH;\n\n constructor(host: string, username: string, password: string, port: number = 22, connectConfig?: Config) {\n this.#connectConfig = {\n ...connectConfig,\n host,\n password,\n port,\n username,\n };\n\n this.#logger = createConsola();\n this.#nodeSsh = new NodeSSH();\n if (process.env.NODE_ENV === 'production') this.setLoggerLevel('error');\n }\n\n get nodeSsh() {\n return this.#nodeSsh;\n }\n\n async connect() {\n try {\n this.#nodeSsh = await this.#nodeSsh.connect(this.#connectConfig);\n return true;\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n disconnect() {\n try {\n this.#nodeSsh.dispose();\n return true;\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n execCommand(command: string, options?: SSHExecCommandOptions) {\n return this.#nodeSsh.execCommand(command, options).catch(() => {});\n }\n\n execCommandWithIo(command: string, options?: SSHExecCommandOptions) {\n return this.execCommand(\n command,\n {\n ...options,\n onStderr: (data) => process.stderr.write(data.toString()),\n onStdout: (data) => process.stdout.write(data.toString()),\n },\n );\n }\n\n getDir = this.getDirectory;\n\n async getDirectory(localDirectory: PathLike, remoteDirectory: PathLike, options?: SSHGetPutDirectoryOptions) {\n try {\n return await this.#nodeSsh.getDirectory(localDirectory.toString(), remoteDirectory.toString(), options);\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n async getFile(\n localFile: PathLike,\n remoteFile: PathLike,\n givenSftp?: Nullable<SFTPWrapper>,\n transferOptions?: Nullable<TransferOptions>,\n ) {\n try {\n await this.#nodeSsh.getFile(localFile.toString(), remoteFile.toString(), givenSftp, transferOptions);\n return true;\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n isConnected() {\n return this.#nodeSsh.isConnected();\n }\n\n async mkdir(path: PathLike) {\n try {\n await this.#nodeSsh.mkdir(path.toString());\n return true;\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n putDir = this.putDirectory;\n\n async putDirectory(localDirectory: PathLike, remoteDirectory: PathLike, options?: SSHGetPutDirectoryOptions) {\n try {\n return await this.#nodeSsh.putDirectory(localDirectory.toString(), remoteDirectory.toString(), options);\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n async putFile(\n localFile: PathLike,\n remoteFile: PathLike,\n givenSftp?: Nullable<SFTPWrapper>,\n transferOptions?: Nullable<TransferOptions>,\n ) {\n try {\n await this.#nodeSsh.putFile(localFile.toString(), remoteFile.toString(), givenSftp, transferOptions);\n return true;\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n async putFiles(files: { local: PathLike; remote: PathLike }[], options?: SSHPutFilesOptions) {\n try {\n const convertedFiles = files.map(({ local, remote }) => ({\n local: local.toString(),\n remote: remote.toString(),\n }));\n\n await this.#nodeSsh.putFiles(convertedFiles, options);\n return true;\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n setLoggerLevel(level: keyof typeof loggerLevelStringToConsolaLogLevelMap) {\n this.#logger.level = loggerLevelStringToConsolaLogLevelMap[level];\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ssh-client.js","names":["#connectConfig","#logger","#nodeSsh"],"sources":["../../src/classes/ssh-client.ts"],"sourcesContent":["import { createConsola } from 'consola';\nimport type { ConsolaInstance } from 'consola';\nimport { NodeSSH } from 'node-ssh';\nimport type {\n Config,\n SSHExecCommandOptions,\n SSHGetPutDirectoryOptions,\n SSHPutFilesOptions,\n} from 'node-ssh';\nimport type {\n SFTPWrapper,\n TransferOptions,\n} from 'ssh2';\n\nimport type { Nullable } from '../types';\n\nimport type { PathLike } from './path';\n\nconst loggerLevelStringToConsolaLogLevelMap = {\n debug: 4,\n error: 0,\n fatal: 0,\n info: 3,\n normal: 2,\n silent: -999,\n trace: 5,\n verbose: 999,\n warn: 1,\n} as const;\n\nexport class SshClient {\n readonly #connectConfig: Config;\n readonly #logger: ConsolaInstance;\n\n #nodeSsh: NodeSSH;\n\n constructor(host: string, username: string, password: string, port: number = 22, connectConfig?: Config) {\n this.#connectConfig = {\n ...connectConfig,\n host,\n password,\n port,\n username,\n };\n\n this.#logger = createConsola();\n this.#nodeSsh = new NodeSSH();\n if (process.env.NODE_ENV === 'production') this.setLoggerLevel('error');\n }\n\n get nodeSsh() {\n return this.#nodeSsh;\n }\n\n async connect() {\n try {\n this.#nodeSsh = await this.#nodeSsh.connect(this.#connectConfig);\n return true;\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n disconnect() {\n try {\n this.#nodeSsh.dispose();\n return true;\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n execCommand(command: string, options?: SSHExecCommandOptions) {\n return this.#nodeSsh.execCommand(command, options).catch(() => {});\n }\n\n execCommandWithIo(command: string, options?: SSHExecCommandOptions) {\n return this.execCommand(\n command,\n {\n ...options,\n onStderr: (data) => process.stderr.write(data.toString()),\n onStdout: (data) => process.stdout.write(data.toString()),\n },\n );\n }\n\n getDir = this.getDirectory;\n\n async getDirectory(localDirectory: PathLike, remoteDirectory: PathLike, options?: SSHGetPutDirectoryOptions) {\n try {\n return await this.#nodeSsh.getDirectory(localDirectory.toString(), remoteDirectory.toString(), options);\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n async getFile(\n localFile: PathLike,\n remoteFile: PathLike,\n givenSftp?: Nullable<SFTPWrapper>,\n transferOptions?: Nullable<TransferOptions>,\n ) {\n try {\n await this.#nodeSsh.getFile(localFile.toString(), remoteFile.toString(), givenSftp, transferOptions);\n return true;\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n isConnected() {\n return this.#nodeSsh.isConnected();\n }\n\n async mkdir(path: PathLike) {\n try {\n await this.#nodeSsh.mkdir(path.toString());\n return true;\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n putDir = this.putDirectory;\n\n async putDirectory(localDirectory: PathLike, remoteDirectory: PathLike, options?: SSHGetPutDirectoryOptions) {\n try {\n return await this.#nodeSsh.putDirectory(localDirectory.toString(), remoteDirectory.toString(), options);\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n async putFile(\n localFile: PathLike,\n remoteFile: PathLike,\n givenSftp?: Nullable<SFTPWrapper>,\n transferOptions?: Nullable<TransferOptions>,\n ) {\n try {\n await this.#nodeSsh.putFile(localFile.toString(), remoteFile.toString(), givenSftp, transferOptions);\n return true;\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n async putFiles(files: { local: PathLike; remote: PathLike }[], options?: SSHPutFilesOptions) {\n try {\n const convertedFiles = files.map(({ local, remote }) => ({\n local: local.toString(),\n remote: remote.toString(),\n }));\n\n await this.#nodeSsh.putFiles(convertedFiles, options);\n return true;\n } catch (error) {\n this.#logger.error(error);\n return false;\n }\n }\n\n setLoggerLevel(level: keyof typeof loggerLevelStringToConsolaLogLevelMap) {\n this.#logger.level = loggerLevelStringToConsolaLogLevelMap[level];\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"clipboard.d.ts","names":[],"sources":["../src/clipboard.ts"],"mappings":";KAAK,UAAA;EACC,KAAA;EAAgB,EAAA;AAAA;EAChB,EAAA;AAAA;;;;;AA8BN;;;;;;;;;;;;;;;;;AA8CA;;;;;;;iBA9CsB,mBAAA,CAAoB,IAAA,EAAM,IAAA,EAAM,OAAA,GAAU,oBAAA,GAAuB,OAAA,CAAQ,UAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8CzE,mBAAA,CAAoB,IAAA,WAAe,OAAA,CAAQ,UAAA"}
1
+ {"version":3,"file":"clipboard.d.ts","names":[],"sources":["../src/clipboard.ts"],"mappings":";KAAK,UAAA;EACC,KAAA;EAAgB,EAAA;AAAA;EAChB,EAAA;AAAA;;;;AAAE;AA8BR;;;;;;;;;;;;;;;;AAAyG;AA8CzG;;;;;;;iBA9CsB,mBAAA,CAAoB,IAAA,EAAM,IAAA,EAAM,OAAA,GAAU,oBAAA,GAAuB,OAAA,CAAQ,UAAA;AA8CpB;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iBAArD,mBAAA,CAAoB,IAAA,WAAe,OAAO,CAAC,UAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"clipboard.js","names":[],"sources":["../src/clipboard.ts"],"sourcesContent":["type CopyResult =\n | { error: unknown; ok: false }\n | { ok: true };\n\n/**\n * Attempts to copy a Blob (e.g. image, plain text, HTML) to the user's clipboard using the ClipboardItem API.\n *\n * ⚠️ Usage Notes:\n * - Must be called in a **secure context** (HTTPS or localhost).\n * - Must be called **in response to a user interaction** (e.g. click, input).\n * - Not supported in Safari and some older browsers.\n *\n * @param {Blob} blob - The Blob object to copy (e.g. from a File, image, or text content)\n * @param {ClipboardItemOptions} [options] - Optional options passed to the ClipboardItem constructor\n *\n * @returns {Promise<CopyResult>} A promise resolving to a `CopyResult`:\n * - `{ ok: true }` if the copy succeeded\n * - `{ ok: false, error }` if the copy failed, with the error included\n *\n * @example\n * ```typescript\n * import { copyBlobToClipboard } from '@kikiutils/shared/clipboard';\n *\n * const blob = new Blob(['Hello world'], { type: 'text/plain' });\n * const result = await copyBlobToClipboard(blob);\n * if (result.ok) {\n * console.log('Copied blob!');\n * } else {\n * console.error('Copy failed:', result.error);\n * }\n * ```\n */\nexport async function copyBlobToClipboard(blob: Blob, options?: ClipboardItemOptions): Promise<CopyResult> {\n if (!navigator.clipboard?.write) {\n return {\n error: new Error('Clipboard.write is not supported in this browser'),\n ok: false,\n };\n }\n\n try {\n const item = new ClipboardItem({ [blob.type]: blob }, options);\n await navigator.clipboard.write([item]);\n return { ok: true };\n } catch (error) {\n return {\n error,\n ok: false,\n };\n }\n}\n\n/**\n * Attempts to copy the given text to the user's clipboard using the modern Clipboard API.\n *\n * ⚠️ Usage Notes:\n * - Must be called in a **secure context** (HTTPS or localhost).\n * - Must be called **in response to a user interaction** (e.g. click, input).\n * - Not supported in some older browsers (especially legacy Safari).\n *\n * @param {string} text - The string to be copied to the clipboard\n *\n * @returns {Promise<CopyResult>} A promise resolving to a `CopyResult`:\n * - `{ ok: true }` if the copy succeeded\n * - `{ ok: false, error }` if the copy failed, with the error included\n *\n * @example\n * ```typescript\n * import { copyTextToClipboard } from '@kikiutils/shared/clipboard';\n *\n * const result = await copyTextToClipboard('Hello!');\n * if (result.ok) {\n * console.log('Copied!');\n * } else {\n * console.error('Copy failed:', result.error);\n * }\n * ```\n */\nexport async function copyTextToClipboard(text: string): Promise<CopyResult> {\n try {\n await navigator.clipboard.writeText(text);\n return { ok: true };\n } catch (error) {\n return {\n error,\n ok: false,\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,eAAsB,oBAAoB,MAAY,SAAqD;CACvG,IAAI,CAAC,UAAU,WAAW,OACtB,OAAO;EACH,uBAAO,IAAI,MAAM,mDAAmD;EACpE,IAAI;EACP;CAGL,IAAI;EACA,MAAM,OAAO,IAAI,cAAc,GAAG,KAAK,OAAO,MAAM,EAAE,QAAQ;EAC9D,MAAM,UAAU,UAAU,MAAM,CAAC,KAAK,CAAC;EACvC,OAAO,EAAE,IAAI,MAAM;UACd,OAAO;EACZ,OAAO;GACH;GACA,IAAI;GACP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BT,eAAsB,oBAAoB,MAAmC;CACzE,IAAI;EACA,MAAM,UAAU,UAAU,UAAU,KAAK;EACzC,OAAO,EAAE,IAAI,MAAM;UACd,OAAO;EACZ,OAAO;GACH;GACA,IAAI;GACP"}
1
+ {"version":3,"file":"clipboard.js","names":[],"sources":["../src/clipboard.ts"],"sourcesContent":["type CopyResult =\n | { error: unknown; ok: false }\n | { ok: true };\n\n/**\n * Attempts to copy a Blob (e.g. image, plain text, HTML) to the user's clipboard using the ClipboardItem API.\n *\n * ⚠️ Usage Notes:\n * - Must be called in a **secure context** (HTTPS or localhost).\n * - Must be called **in response to a user interaction** (e.g. click, input).\n * - Not supported in Safari and some older browsers.\n *\n * @param {Blob} blob - The Blob object to copy (e.g. from a File, image, or text content)\n * @param {ClipboardItemOptions} [options] - Optional options passed to the ClipboardItem constructor\n *\n * @returns {Promise<CopyResult>} A promise resolving to a `CopyResult`:\n * - `{ ok: true }` if the copy succeeded\n * - `{ ok: false, error }` if the copy failed, with the error included\n *\n * @example\n * ```typescript\n * import { copyBlobToClipboard } from '@kikiutils/shared/clipboard';\n *\n * const blob = new Blob(['Hello world'], { type: 'text/plain' });\n * const result = await copyBlobToClipboard(blob);\n * if (result.ok) {\n * console.log('Copied blob!');\n * } else {\n * console.error('Copy failed:', result.error);\n * }\n * ```\n */\nexport async function copyBlobToClipboard(blob: Blob, options?: ClipboardItemOptions): Promise<CopyResult> {\n if (!navigator.clipboard?.write) {\n return {\n error: new Error('Clipboard.write is not supported in this browser'),\n ok: false,\n };\n }\n\n try {\n const item = new ClipboardItem({ [blob.type]: blob }, options);\n await navigator.clipboard.write([item]);\n return { ok: true };\n } catch (error) {\n return {\n error,\n ok: false,\n };\n }\n}\n\n/**\n * Attempts to copy the given text to the user's clipboard using the modern Clipboard API.\n *\n * ⚠️ Usage Notes:\n * - Must be called in a **secure context** (HTTPS or localhost).\n * - Must be called **in response to a user interaction** (e.g. click, input).\n * - Not supported in some older browsers (especially legacy Safari).\n *\n * @param {string} text - The string to be copied to the clipboard\n *\n * @returns {Promise<CopyResult>} A promise resolving to a `CopyResult`:\n * - `{ ok: true }` if the copy succeeded\n * - `{ ok: false, error }` if the copy failed, with the error included\n *\n * @example\n * ```typescript\n * import { copyTextToClipboard } from '@kikiutils/shared/clipboard';\n *\n * const result = await copyTextToClipboard('Hello!');\n * if (result.ok) {\n * console.log('Copied!');\n * } else {\n * console.error('Copy failed:', result.error);\n * }\n * ```\n */\nexport async function copyTextToClipboard(text: string): Promise<CopyResult> {\n try {\n await navigator.clipboard.writeText(text);\n return { ok: true };\n } catch (error) {\n return {\n error,\n ok: false,\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,eAAsB,oBAAoB,MAAY,SAAqD;CACvG,IAAI,CAAC,UAAU,WAAW,OACtB,OAAO;EACH,uBAAO,IAAI,MAAM,kDAAkD;EACnE,IAAI;CACR;CAGJ,IAAI;EACA,MAAM,OAAO,IAAI,cAAc,GAAG,KAAK,OAAO,KAAK,GAAG,OAAO;EAC7D,MAAM,UAAU,UAAU,MAAM,CAAC,IAAI,CAAC;EACtC,OAAO,EAAE,IAAI,KAAK;CACtB,SAAS,OAAO;EACZ,OAAO;GACH;GACA,IAAI;EACR;CACJ;AACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,eAAsB,oBAAoB,MAAmC;CACzE,IAAI;EACA,MAAM,UAAU,UAAU,UAAU,IAAI;EACxC,OAAO,EAAE,IAAI,KAAK;CACtB,SAAS,OAAO;EACZ,OAAO;GACH;GACA,IAAI;EACR;CACJ;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"consola.d.ts","names":[],"sources":["../src/consola.ts"],"mappings":";;;;;;AAuBA;;;;;AACA;;;;;;;;;;;;;cADa,aAAA,EAA+B,SAAA,CAAlB,eAAA;AAAA,cACb,MAAA,EAAsB,SAAA,CAAhB,eAAA"}
1
+ {"version":3,"file":"consola.d.ts","names":[],"sources":["../src/consola.ts"],"mappings":";;;;;;AAuBA;;;;AAA4C;AAC5C;;;;AAAmC;;;;;;;;;cADtB,aAAA,EAA+B,SAAA,CAAlB,eAAkB;AAAA,cAC/B,MAAA,EAAsB,SAAA,CAAhB,eAAgB"}
@@ -1 +1 @@
1
- {"version":3,"file":"consola.js","names":[],"sources":["../src/consola.ts"],"sourcesContent":["import { createConsola } from 'consola';\n\n/**\n * A consola logger instance.\n *\n * The logger's level is determined based on the `CONSOLA_LOGGER_LEVEL` and `NODE_ENV` environment variables.\n * If `CONSOLA_LOGGER_LEVEL` is set, it will be used; otherwise, if `NODE_ENV` is `production`,\n * the level will be set to `0`.\n *\n * To manually change the level, assign the desired level to `logger.level`.\n *\n * See available levels [here](https://github.com/unjs/consola?tab=readme-ov-file#log-level).\n *\n * @example\n * ```typescript\n * import { logger } from '@kikiutils/shared/consola';\n *\n * logger.info('test'); // ℹ test 3:56:30 AM\n *\n * // Manually change the level\n * logger.level = 3;\n * ```\n */\nexport const consolaLogger = createConsola();\nexport const logger = consolaLogger;\nif (process.env.CONSOLA_LOGGER_LEVEL !== undefined) consolaLogger.level = +process.env.CONSOLA_LOGGER_LEVEL;\nelse consolaLogger.level = process.env.NODE_ENV === 'production' ? 0 : consolaLogger.level;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,gBAAgB,eAAe;AAC5C,MAAa,SAAS;AACtB,IAAI,QAAQ,IAAI,yBAAyB,KAAA,GAAW,cAAc,QAAQ,CAAC,QAAQ,IAAI;KAClF,cAAc,QAAQ,QAAQ,IAAI,aAAa,eAAe,IAAI,cAAc"}
1
+ {"version":3,"file":"consola.js","names":[],"sources":["../src/consola.ts"],"sourcesContent":["import { createConsola } from 'consola';\n\n/**\n * A consola logger instance.\n *\n * The logger's level is determined based on the `CONSOLA_LOGGER_LEVEL` and `NODE_ENV` environment variables.\n * If `CONSOLA_LOGGER_LEVEL` is set, it will be used; otherwise, if `NODE_ENV` is `production`,\n * the level will be set to `0`.\n *\n * To manually change the level, assign the desired level to `logger.level`.\n *\n * See available levels [here](https://github.com/unjs/consola?tab=readme-ov-file#log-level).\n *\n * @example\n * ```typescript\n * import { logger } from '@kikiutils/shared/consola';\n *\n * logger.info('test'); // ℹ test 3:56:30 AM\n *\n * // Manually change the level\n * logger.level = 3;\n * ```\n */\nexport const consolaLogger = createConsola();\nexport const logger = consolaLogger;\nif (process.env.CONSOLA_LOGGER_LEVEL !== undefined) consolaLogger.level = +process.env.CONSOLA_LOGGER_LEVEL;\nelse consolaLogger.level = process.env.NODE_ENV === 'production' ? 0 : consolaLogger.level;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,gBAAgB,cAAc;AAC3C,MAAa,SAAS;AACtB,IAAI,QAAQ,IAAI,yBAAyB,KAAA,GAAW,cAAc,QAAQ,CAAC,QAAQ,IAAI;KAClF,cAAc,QAAQ,QAAQ,IAAI,aAAa,eAAe,IAAI,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"crypto-hash.d.ts","names":[],"sources":["../src/crypto-hash.ts"],"mappings":";;;;;AAqBA;;;;;;;;;;AAkBA;;;iBAlBgB,SAAA,CAAU,IAAA,EAAM,UAAA,EAAY,cAAA,GAAgB,oBAAA;;;;;;AAqC5D;;;;;;;;;iBAnBgB,iBAAA,CAAkB,IAAA,EAAM,UAAA,GAAU,eAAA;AAqClD;;;;;;;;;AAmBA;;;;;;AAnBA,iBAlBgB,aAAA,CAAc,IAAA,EAAM,UAAA,EAAY,cAAA,GAAgB,oBAAA;;;;AAuDhE;;;;;;;;;AAmBA;;iBAxDgB,qBAAA,CAAsB,IAAA,EAAM,UAAA,GAAU,eAAA;;;;;;;;AA0EtD;;;;;;;;iBAvDgB,aAAA,CAAc,IAAA,EAAM,UAAA,EAAY,cAAA,GAAgB,oBAAA;AA0EhE;;;;;;;;;;AAkBA;;;;AAlBA,iBAxDgB,qBAAA,CAAsB,IAAA,EAAM,UAAA,GAAU,eAAA;;;;;;;;;;;;;;;;iBAmBtC,aAAA,CAAc,IAAA,EAAM,UAAA,EAAY,cAAA,GAAgB,oBAAA;;;;;;;;;;;;;;;iBAkBhD,qBAAA,CAAsB,IAAA,EAAM,UAAA,GAAU,eAAA;;;;;;;;;;;;;;;;iBAmBtC,aAAA,CAAc,IAAA,EAAM,UAAA,EAAY,cAAA,GAAgB,oBAAA;;;;;;;;;;;;;;;iBAkBhD,qBAAA,CAAsB,IAAA,EAAM,UAAA,GAAU,eAAA"}
1
+ {"version":3,"file":"crypto-hash.d.ts","names":[],"sources":["../src/crypto-hash.ts"],"mappings":";;;;;AAqBA;;;;;;;;;AAAwF;AAkBxF;;;iBAlBgB,SAAA,CAAU,IAAA,EAAM,UAAA,EAAY,cAAA,GAAgB,oBAA4B;;;;;AAkBtC;AAmBlD;;;;;;;;;iBAnBgB,iBAAA,CAAkB,IAAA,EAAM,UAAA,GAAU,eAAA;AAqClD;;;;;;;;AAAsD;AAmBtD;;;;;;AAnBA,iBAlBgB,aAAA,CAAc,IAAA,EAAM,UAAA,EAAY,cAAA,GAAgB,oBAA4B;;;AAqCA;AAkB5F;;;;;;;;AAAsD;AAmBtD;;iBAxDgB,qBAAA,CAAsB,IAAA,EAAM,UAAA,GAAU,eAAA;;;;;;;AAwDsC;AAkB5F;;;;;;;;iBAvDgB,aAAA,CAAc,IAAA,EAAM,UAAA,EAAY,cAAA,GAAgB,oBAA4B;AA0E5F;;;;;;;;;AAA4F;AAkB5F;;;;AAlBA,iBAxDgB,qBAAA,CAAsB,IAAA,EAAM,UAAA,GAAU,eAAA;;;;AA0EA;;;;;;;;;;;;iBAvDtC,aAAA,CAAc,IAAA,EAAM,UAAA,EAAY,cAAA,GAAgB,oBAA4B;;;;;;;;;;;;;;;iBAkB5E,qBAAA,CAAsB,IAAA,EAAM,UAAA,GAAU,eAAA;;;;;;;;;;;;;;;;iBAmBtC,aAAA,CAAc,IAAA,EAAM,UAAA,EAAY,cAAA,GAAgB,oBAA4B;;;;;;;;;;;;;;;iBAkB5E,qBAAA,CAAsB,IAAA,EAAM,UAAA,GAAU,eAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"crypto-hash.js","names":[],"sources":["../src/crypto-hash.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport type {\n BinaryLike,\n BinaryToTextEncoding,\n} from 'node:crypto';\n\n/**\n * Computes the MD5 hash of the given data.\n *\n * @param {BinaryLike} data - The input data to hash\n * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)\n *\n * @returns {string | Buffer} The hash digest in the specified encoding\n *\n * @example\n * ```typescript\n * import { cryptoMd5 } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoMd5('test')); // 098f6bcd4621d373cade4e832627b4f6\n * ```\n */\nexport function cryptoMd5(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {\n return createHash('md5').update(data).digest(outputEncoding);\n}\n\n/**\n * Computes the MD5 hash of the given data and returns the raw buffer.\n *\n * @param {BinaryLike} data - The input data to hash\n *\n * @returns {Buffer} The raw hash digest as a Buffer\n *\n * @example\n * ```typescript\n * import { cryptoMd5ToBuffer } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoMd5ToBuffer('test')); // <Buffer 33 ed 9a ...>\n * ```\n */\nexport function cryptoMd5ToBuffer(data: BinaryLike) {\n return createHash('md5').update(data).digest();\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 224-bit digest.\n *\n * @param {BinaryLike} data - The input data to hash\n * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)\n *\n * @returns {string | Buffer} The hash digest in the specified encoding\n *\n * @example\n * ```typescript\n * import { cryptoSha3224 } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3224('test')); // 3797bf0afbbfca4a7bbba7602a2b552746876517a7f9b7ce2db0ae7b\n * ```\n */\nexport function cryptoSha3224(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {\n return createHash('sha3-224').update(data).digest(outputEncoding);\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 224-bit digest and returns the raw buffer.\n *\n * @param {BinaryLike} data - The input data to hash\n *\n * @returns {Buffer} The raw hash digest as a Buffer\n *\n * @example\n * ```typescript\n * import { cryptoSha3224ToBuffer } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3224ToBuffer('test')); // <Buffer 37 97 bf 0a ...>\n * ```\n */\nexport function cryptoSha3224ToBuffer(data: BinaryLike) {\n return createHash('sha3-224').update(data).digest();\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 256-bit digest.\n *\n * @param {BinaryLike} data - The input data to hash\n * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)\n *\n * @returns {string | Buffer} The hash digest in the specified encoding\n *\n * @example\n * ```typescript\n * import { cryptoSha3256 } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3256('test')); // 36f028580bb02cc8272a9a020f4200e346e276ae664e45ee80745574e2f5ab80\n * ```\n */\nexport function cryptoSha3256(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {\n return createHash('sha3-256').update(data).digest(outputEncoding);\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 256-bit digest and returns the raw buffer.\n *\n * @param {BinaryLike} data - The input data to hash\n *\n * @returns {Buffer} The raw hash digest as a Buffer\n *\n * @example\n * ```typescript\n * import { cryptoSha3256ToBuffer } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3256ToBuffer('test')); // <Buffer 36 f0 28 ...>\n * ```\n */\nexport function cryptoSha3256ToBuffer(data: BinaryLike) {\n return createHash('sha3-256').update(data).digest();\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 384-bit digest.\n *\n * @param {BinaryLike} data - The input data to hash\n * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)\n *\n * @returns {string | Buffer} The hash digest in the specified encoding\n *\n * @example\n * ```typescript\n * import { cryptoSha3384 } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3384('test')); // e516dabb23b6e30026863543282780a3ae0dccf05551cf0295178d7f...\n * ```\n */\nexport function cryptoSha3384(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {\n return createHash('sha3-384').update(data).digest(outputEncoding);\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 384-bit digest and returns the raw buffer.\n *\n * @param {BinaryLike} data - The input data to hash\n *\n * @returns {Buffer} The raw hash digest as a Buffer\n *\n * @example\n * ```typescript\n * import { cryptoSha3384ToBuffer } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3384ToBuffer('test')); // <Buffer e5 16 da bb ...>\n * ```\n */\nexport function cryptoSha3384ToBuffer(data: BinaryLike) {\n return createHash('sha3-384').update(data).digest();\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 512-bit digest.\n *\n * @param {BinaryLike} data - The input data to hash\n * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)\n *\n * @returns {string | Buffer} The hash digest in the specified encoding\n *\n * @example\n * ```typescript\n * import { cryptoSha3512 } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3512('test')); // 9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7...\n * ```\n */\nexport function cryptoSha3512(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {\n return createHash('sha3-512').update(data).digest(outputEncoding);\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 512-bit digest and returns the raw buffer.\n *\n * @param {BinaryLike} data - The input data to hash\n *\n * @returns {Buffer} The raw hash digest as a Buffer\n *\n * @example\n * ```typescript\n * import { cryptoSha3512ToBuffer } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3512ToBuffer('test')); // <Buffer 9e ce 08 6e ...>\n * ```\n */\nexport function cryptoSha3512ToBuffer(data: BinaryLike) {\n return createHash('sha3-512').update(data).digest();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAqBA,SAAgB,UAAU,MAAkB,iBAAuC,OAAO;CACtF,OAAO,WAAW,MAAM,CAAC,OAAO,KAAK,CAAC,OAAO,eAAe;;;;;;;;;;;;;;;;AAiBhE,SAAgB,kBAAkB,MAAkB;CAChD,OAAO,WAAW,MAAM,CAAC,OAAO,KAAK,CAAC,QAAQ;;;;;;;;;;;;;;;;;AAkBlD,SAAgB,cAAc,MAAkB,iBAAuC,OAAO;CAC1F,OAAO,WAAW,WAAW,CAAC,OAAO,KAAK,CAAC,OAAO,eAAe;;;;;;;;;;;;;;;;AAiBrE,SAAgB,sBAAsB,MAAkB;CACpD,OAAO,WAAW,WAAW,CAAC,OAAO,KAAK,CAAC,QAAQ;;;;;;;;;;;;;;;;;AAkBvD,SAAgB,cAAc,MAAkB,iBAAuC,OAAO;CAC1F,OAAO,WAAW,WAAW,CAAC,OAAO,KAAK,CAAC,OAAO,eAAe;;;;;;;;;;;;;;;;AAiBrE,SAAgB,sBAAsB,MAAkB;CACpD,OAAO,WAAW,WAAW,CAAC,OAAO,KAAK,CAAC,QAAQ;;;;;;;;;;;;;;;;;AAkBvD,SAAgB,cAAc,MAAkB,iBAAuC,OAAO;CAC1F,OAAO,WAAW,WAAW,CAAC,OAAO,KAAK,CAAC,OAAO,eAAe;;;;;;;;;;;;;;;;AAiBrE,SAAgB,sBAAsB,MAAkB;CACpD,OAAO,WAAW,WAAW,CAAC,OAAO,KAAK,CAAC,QAAQ;;;;;;;;;;;;;;;;;AAkBvD,SAAgB,cAAc,MAAkB,iBAAuC,OAAO;CAC1F,OAAO,WAAW,WAAW,CAAC,OAAO,KAAK,CAAC,OAAO,eAAe;;;;;;;;;;;;;;;;AAiBrE,SAAgB,sBAAsB,MAAkB;CACpD,OAAO,WAAW,WAAW,CAAC,OAAO,KAAK,CAAC,QAAQ"}
1
+ {"version":3,"file":"crypto-hash.js","names":[],"sources":["../src/crypto-hash.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport type {\n BinaryLike,\n BinaryToTextEncoding,\n} from 'node:crypto';\n\n/**\n * Computes the MD5 hash of the given data.\n *\n * @param {BinaryLike} data - The input data to hash\n * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)\n *\n * @returns {string | Buffer} The hash digest in the specified encoding\n *\n * @example\n * ```typescript\n * import { cryptoMd5 } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoMd5('test')); // 098f6bcd4621d373cade4e832627b4f6\n * ```\n */\nexport function cryptoMd5(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {\n return createHash('md5').update(data).digest(outputEncoding);\n}\n\n/**\n * Computes the MD5 hash of the given data and returns the raw buffer.\n *\n * @param {BinaryLike} data - The input data to hash\n *\n * @returns {Buffer} The raw hash digest as a Buffer\n *\n * @example\n * ```typescript\n * import { cryptoMd5ToBuffer } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoMd5ToBuffer('test')); // <Buffer 33 ed 9a ...>\n * ```\n */\nexport function cryptoMd5ToBuffer(data: BinaryLike) {\n return createHash('md5').update(data).digest();\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 224-bit digest.\n *\n * @param {BinaryLike} data - The input data to hash\n * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)\n *\n * @returns {string | Buffer} The hash digest in the specified encoding\n *\n * @example\n * ```typescript\n * import { cryptoSha3224 } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3224('test')); // 3797bf0afbbfca4a7bbba7602a2b552746876517a7f9b7ce2db0ae7b\n * ```\n */\nexport function cryptoSha3224(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {\n return createHash('sha3-224').update(data).digest(outputEncoding);\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 224-bit digest and returns the raw buffer.\n *\n * @param {BinaryLike} data - The input data to hash\n *\n * @returns {Buffer} The raw hash digest as a Buffer\n *\n * @example\n * ```typescript\n * import { cryptoSha3224ToBuffer } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3224ToBuffer('test')); // <Buffer 37 97 bf 0a ...>\n * ```\n */\nexport function cryptoSha3224ToBuffer(data: BinaryLike) {\n return createHash('sha3-224').update(data).digest();\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 256-bit digest.\n *\n * @param {BinaryLike} data - The input data to hash\n * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)\n *\n * @returns {string | Buffer} The hash digest in the specified encoding\n *\n * @example\n * ```typescript\n * import { cryptoSha3256 } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3256('test')); // 36f028580bb02cc8272a9a020f4200e346e276ae664e45ee80745574e2f5ab80\n * ```\n */\nexport function cryptoSha3256(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {\n return createHash('sha3-256').update(data).digest(outputEncoding);\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 256-bit digest and returns the raw buffer.\n *\n * @param {BinaryLike} data - The input data to hash\n *\n * @returns {Buffer} The raw hash digest as a Buffer\n *\n * @example\n * ```typescript\n * import { cryptoSha3256ToBuffer } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3256ToBuffer('test')); // <Buffer 36 f0 28 ...>\n * ```\n */\nexport function cryptoSha3256ToBuffer(data: BinaryLike) {\n return createHash('sha3-256').update(data).digest();\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 384-bit digest.\n *\n * @param {BinaryLike} data - The input data to hash\n * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)\n *\n * @returns {string | Buffer} The hash digest in the specified encoding\n *\n * @example\n * ```typescript\n * import { cryptoSha3384 } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3384('test')); // e516dabb23b6e30026863543282780a3ae0dccf05551cf0295178d7f...\n * ```\n */\nexport function cryptoSha3384(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {\n return createHash('sha3-384').update(data).digest(outputEncoding);\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 384-bit digest and returns the raw buffer.\n *\n * @param {BinaryLike} data - The input data to hash\n *\n * @returns {Buffer} The raw hash digest as a Buffer\n *\n * @example\n * ```typescript\n * import { cryptoSha3384ToBuffer } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3384ToBuffer('test')); // <Buffer e5 16 da bb ...>\n * ```\n */\nexport function cryptoSha3384ToBuffer(data: BinaryLike) {\n return createHash('sha3-384').update(data).digest();\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 512-bit digest.\n *\n * @param {BinaryLike} data - The input data to hash\n * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)\n *\n * @returns {string | Buffer} The hash digest in the specified encoding\n *\n * @example\n * ```typescript\n * import { cryptoSha3512 } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3512('test')); // 9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7...\n * ```\n */\nexport function cryptoSha3512(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {\n return createHash('sha3-512').update(data).digest(outputEncoding);\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 512-bit digest and returns the raw buffer.\n *\n * @param {BinaryLike} data - The input data to hash\n *\n * @returns {Buffer} The raw hash digest as a Buffer\n *\n * @example\n * ```typescript\n * import { cryptoSha3512ToBuffer } from '@kikiutils/shared/crypto-hash';\n *\n * console.log(cryptoSha3512ToBuffer('test')); // <Buffer 9e ce 08 6e ...>\n * ```\n */\nexport function cryptoSha3512ToBuffer(data: BinaryLike) {\n return createHash('sha3-512').update(data).digest();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAqBA,SAAgB,UAAU,MAAkB,iBAAuC,OAAO;CACtF,OAAO,WAAW,KAAK,EAAE,OAAO,IAAI,EAAE,OAAO,cAAc;AAC/D;;;;;;;;;;;;;;;AAgBA,SAAgB,kBAAkB,MAAkB;CAChD,OAAO,WAAW,KAAK,EAAE,OAAO,IAAI,EAAE,OAAO;AACjD;;;;;;;;;;;;;;;;AAiBA,SAAgB,cAAc,MAAkB,iBAAuC,OAAO;CAC1F,OAAO,WAAW,UAAU,EAAE,OAAO,IAAI,EAAE,OAAO,cAAc;AACpE;;;;;;;;;;;;;;;AAgBA,SAAgB,sBAAsB,MAAkB;CACpD,OAAO,WAAW,UAAU,EAAE,OAAO,IAAI,EAAE,OAAO;AACtD;;;;;;;;;;;;;;;;AAiBA,SAAgB,cAAc,MAAkB,iBAAuC,OAAO;CAC1F,OAAO,WAAW,UAAU,EAAE,OAAO,IAAI,EAAE,OAAO,cAAc;AACpE;;;;;;;;;;;;;;;AAgBA,SAAgB,sBAAsB,MAAkB;CACpD,OAAO,WAAW,UAAU,EAAE,OAAO,IAAI,EAAE,OAAO;AACtD;;;;;;;;;;;;;;;;AAiBA,SAAgB,cAAc,MAAkB,iBAAuC,OAAO;CAC1F,OAAO,WAAW,UAAU,EAAE,OAAO,IAAI,EAAE,OAAO,cAAc;AACpE;;;;;;;;;;;;;;;AAgBA,SAAgB,sBAAsB,MAAkB;CACpD,OAAO,WAAW,UAAU,EAAE,OAAO,IAAI,EAAE,OAAO;AACtD;;;;;;;;;;;;;;;;AAiBA,SAAgB,cAAc,MAAkB,iBAAuC,OAAO;CAC1F,OAAO,WAAW,UAAU,EAAE,OAAO,IAAI,EAAE,OAAO,cAAc;AACpE;;;;;;;;;;;;;;;AAgBA,SAAgB,sBAAsB,MAAkB;CACpD,OAAO,WAAW,UAAU,EAAE,OAAO,IAAI,EAAE,OAAO;AACtD"}
@@ -1 +1 @@
1
- {"version":3,"file":"datetime.d.ts","names":[],"sources":["../src/datetime.ts"],"mappings":";;;KAkBY,aAAA;;AAAZ;;;;;AA2BA;;;;;;;;;;;;;;;;AA+BA;;;iBA/BgB,UAAA,CAAW,IAAA,EAAM,OAAA,CAAQ,IAAA,QAAY,MAAA,WAAwC,OAAA,GAAU,aAAA;;;;;;;;;;;;;;;;;;;;;AAwGvG;;;;;;;iBAzEgB,oBAAA,CACZ,IAAA,EAAM,IAAA,EACN,IAAA,EAAM,aAAA,EACN,OAAA;EACI,wBAAA;EACA,YAAA,GAAe,GAAA;AAAA;;;;;;;;;;;;;;;;;;;;iBAoEP,wBAAA,CAAyB,UAAA,YAAsB,IAAA"}
1
+ {"version":3,"file":"datetime.d.ts","names":[],"sources":["../src/datetime.ts"],"mappings":";;;KAkBY,aAAA;;AAAZ;;;;AAAyB;AA2BzB;;;;;;;;;;;;;;;AAAoH;AA+BpH;;;iBA/BgB,UAAA,CAAW,IAAA,EAAM,OAAA,CAAQ,IAAA,QAAY,MAAA,WAAwC,OAAA,GAAU,aAAA;;;;;;;;;;;;;;;;;;;;;AAwGvG;;;;AAA+D;;;iBAzE/C,oBAAA,CACZ,IAAA,EAAM,IAAA,EACN,IAAA,EAAM,aAAA,EACN,OAAA;EACI,wBAAA;EACA,YAAA,GAAe,GAAA;AAAA;;;;;;;;;;;;;;;;;;;;iBAoEP,wBAAA,CAAyB,UAAA,YAAsB,IAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"datetime.js","names":["dateFnsFormat","format"],"sources":["../src/datetime.ts"],"sourcesContent":["import {\n format as dateFnsFormat,\n endOfDay,\n endOfMonth,\n endOfWeek,\n startOfDay,\n startOfMonth,\n startOfWeek,\n subDays,\n subMonths,\n subWeeks,\n} from 'date-fns';\nimport type {\n DateArg,\n Day,\n FormatOptions,\n} from 'date-fns';\n\nexport type DateRangeType = 'lastMonth' | 'lastWeek' | 'thisMonth' | 'thisWeek' | 'today' | 'yesterday';\n\n/**\n * Formats a given date, timestamp, or date string into a specified format.\n *\n * This function is a wrapper around `date-fns/format`.\n *\n * @param {DateArg<Date>} date - The input date to format. Can be a Date object, a timestamp, or a string\n * @param {string} [format] - The target format string\n * @param {FormatOptions} [options] - Optional formatting options passed to `date-fns/format`\n *\n * @returns {string} The formatted date string\n *\n * @example\n * ```typescript\n * import { formatDate } from '@kikiutils/shared/datetime';\n *\n * // Format a Date object\n * console.log(formatDate(new Date(), 'yyyy-MM-dd')); // 2024-07-10\n *\n * // Format a timestamp\n * console.log(formatDate(1657814400000, 'yyyy-MM-dd')); // 2022-07-15\n *\n * // Format a date string\n * console.log(formatDate('2024-07-10T00:00:00Z', 'yyyy-MM-dd')); // 2024-07-10\n * ```\n */\nexport function formatDate(date: DateArg<Date> & {}, format: string = 'yyyy-MM-dd HH:mm:ss', options?: FormatOptions) {\n return dateFnsFormat(date, format, options);\n}\n\n/**\n * Get the date range (start and end) based on a given date and range type.\n *\n * Supports common range types like 'lastMonth', 'lastWeek', 'thisMonth', 'thisWeek', 'today', and 'yesterday'.\n *\n * @param {Date} date - The reference date\n * @param {DateRangeType} type - The range type to compute\n * @param {object} [options] - Optional settings\n * @param {boolean} [options.setEndDateToNextDayStart] - If true, set `endDate` to 00:00:00.000 of the next day\n * @param {Day} [options.weekStartsOn] - The start day of the week (0 = Sunday, 1 = Monday, ..., 6 = Saturday)\n *\n * @returns {{ startDate: Date, endDate: Date }} An object with `startDate` and `endDate`\n *\n * @example\n * ```typescript\n * import { getDateRangeFromDate } from '@kikiutils/shared/datetime';\n *\n * // Get the date range for last month\n * const date = new Date('2023-07-01');\n * console.log(getDateRangeFromDate(date, 'lastMonth'));\n * // { startDate: 2023-06-01T00:00:00.000Z, endDate: 2023-06-30T23:59:59.999Z }\n *\n * // Get this week's range with Sunday as the first day\n * console.log(getDateRangeFromDate(date, 'thisWeek', { weekStartsOn: 0 }));\n * // { startDate: 2023-06-25T00:00:00.000Z, endDate: 2023-07-01T23:59:59.999Z }\n * ```\n */\nexport function getDateRangeFromDate(\n date: Date,\n type: DateRangeType,\n options?: {\n setEndDateToNextDayStart?: boolean;\n weekStartsOn?: Day;\n },\n) {\n let endDate: Date;\n let startDate: Date;\n switch (type) {\n case 'lastMonth':\n {\n const lastMonth = subMonths(date, 1);\n endDate = endOfMonth(lastMonth);\n startDate = startOfMonth(lastMonth);\n }\n\n break;\n case 'lastWeek':\n {\n const lastWeek = subWeeks(date, 1);\n endDate = endOfWeek(lastWeek, { weekStartsOn: options?.weekStartsOn ?? 1 });\n startDate = startOfWeek(lastWeek, { weekStartsOn: options?.weekStartsOn ?? 1 });\n }\n\n break;\n case 'thisMonth':\n endDate = endOfMonth(date);\n startDate = startOfMonth(date);\n break;\n case 'thisWeek':\n endDate = endOfWeek(date, { weekStartsOn: options?.weekStartsOn ?? 1 });\n startDate = startOfWeek(date, { weekStartsOn: options?.weekStartsOn ?? 1 });\n break;\n case 'today':\n endDate = endOfDay(date);\n startDate = startOfDay(date);\n break;\n case 'yesterday':\n {\n const yesterday = subDays(date, 1);\n endDate = endOfDay(yesterday);\n startDate = startOfDay(yesterday);\n }\n\n break;\n default: throw new Error(`Unsupported date range type: ${type}`);\n }\n\n if (options?.setEndDateToNextDayStart) endDate.setHours(24, 0, 0, 0);\n return {\n endDate,\n startDate,\n };\n}\n\n/**\n * Returns a `Date` object set to midnight (00:00:00) of today, with an optional day offset.\n *\n * @param {number} [offsetDays] - Number of days to offset from today. Can be negative\n *\n * @returns {Date} A `Date` object at 00:00:00 of the offset day\n *\n * @example\n * ```typescript\n * import { getMidnightDateFromToday } from '@kikiutils/shared/datetime';\n *\n * console.log(getMidnightDateFromToday()); // today at 00:00:00\n * console.log(getMidnightDateFromToday(3)); // 3 days from today at 00:00:00\n * console.log(getMidnightDateFromToday(-1)); // yesterday at 00:00:00\n * ```\n */\nexport function getMidnightDateFromToday(offsetDays: number = 0) {\n const date = new Date();\n date.setDate(date.getDate() + offsetDays);\n date.setHours(0, 0, 0, 0);\n return date;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,SAAgB,WAAW,MAA0B,WAAiB,uBAAuB,SAAyB;CAClH,OAAOA,OAAc,MAAMC,UAAQ,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8B/C,SAAgB,qBACZ,MACA,MACA,SAIF;CACE,IAAI;CACJ,IAAI;CACJ,QAAQ,MAAR;EACI,KAAK;GACD;IACI,MAAM,YAAY,UAAU,MAAM,EAAE;IACpC,UAAU,WAAW,UAAU;IAC/B,YAAY,aAAa,UAAU;;GAGvC;EACJ,KAAK;GACD;IACI,MAAM,WAAW,SAAS,MAAM,EAAE;IAClC,UAAU,UAAU,UAAU,EAAE,cAAc,SAAS,gBAAgB,GAAG,CAAC;IAC3E,YAAY,YAAY,UAAU,EAAE,cAAc,SAAS,gBAAgB,GAAG,CAAC;;GAGnF;EACJ,KAAK;GACD,UAAU,WAAW,KAAK;GAC1B,YAAY,aAAa,KAAK;GAC9B;EACJ,KAAK;GACD,UAAU,UAAU,MAAM,EAAE,cAAc,SAAS,gBAAgB,GAAG,CAAC;GACvE,YAAY,YAAY,MAAM,EAAE,cAAc,SAAS,gBAAgB,GAAG,CAAC;GAC3E;EACJ,KAAK;GACD,UAAU,SAAS,KAAK;GACxB,YAAY,WAAW,KAAK;GAC5B;EACJ,KAAK;GACD;IACI,MAAM,YAAY,QAAQ,MAAM,EAAE;IAClC,UAAU,SAAS,UAAU;IAC7B,YAAY,WAAW,UAAU;;GAGrC;EACJ,SAAS,MAAM,IAAI,MAAM,gCAAgC,OAAO;;CAGpE,IAAI,SAAS,0BAA0B,QAAQ,SAAS,IAAI,GAAG,GAAG,EAAE;CACpE,OAAO;EACH;EACA;EACH;;;;;;;;;;;;;;;;;;AAmBL,SAAgB,yBAAyB,aAAqB,GAAG;CAC7D,MAAM,uBAAO,IAAI,MAAM;CACvB,KAAK,QAAQ,KAAK,SAAS,GAAG,WAAW;CACzC,KAAK,SAAS,GAAG,GAAG,GAAG,EAAE;CACzB,OAAO"}
1
+ {"version":3,"file":"datetime.js","names":["dateFnsFormat","format"],"sources":["../src/datetime.ts"],"sourcesContent":["import {\n format as dateFnsFormat,\n endOfDay,\n endOfMonth,\n endOfWeek,\n startOfDay,\n startOfMonth,\n startOfWeek,\n subDays,\n subMonths,\n subWeeks,\n} from 'date-fns';\nimport type {\n DateArg,\n Day,\n FormatOptions,\n} from 'date-fns';\n\nexport type DateRangeType = 'lastMonth' | 'lastWeek' | 'thisMonth' | 'thisWeek' | 'today' | 'yesterday';\n\n/**\n * Formats a given date, timestamp, or date string into a specified format.\n *\n * This function is a wrapper around `date-fns/format`.\n *\n * @param {DateArg<Date>} date - The input date to format. Can be a Date object, a timestamp, or a string\n * @param {string} [format] - The target format string\n * @param {FormatOptions} [options] - Optional formatting options passed to `date-fns/format`\n *\n * @returns {string} The formatted date string\n *\n * @example\n * ```typescript\n * import { formatDate } from '@kikiutils/shared/datetime';\n *\n * // Format a Date object\n * console.log(formatDate(new Date(), 'yyyy-MM-dd')); // 2024-07-10\n *\n * // Format a timestamp\n * console.log(formatDate(1657814400000, 'yyyy-MM-dd')); // 2022-07-15\n *\n * // Format a date string\n * console.log(formatDate('2024-07-10T00:00:00Z', 'yyyy-MM-dd')); // 2024-07-10\n * ```\n */\nexport function formatDate(date: DateArg<Date> & {}, format: string = 'yyyy-MM-dd HH:mm:ss', options?: FormatOptions) {\n return dateFnsFormat(date, format, options);\n}\n\n/**\n * Get the date range (start and end) based on a given date and range type.\n *\n * Supports common range types like 'lastMonth', 'lastWeek', 'thisMonth', 'thisWeek', 'today', and 'yesterday'.\n *\n * @param {Date} date - The reference date\n * @param {DateRangeType} type - The range type to compute\n * @param {object} [options] - Optional settings\n * @param {boolean} [options.setEndDateToNextDayStart] - If true, set `endDate` to 00:00:00.000 of the next day\n * @param {Day} [options.weekStartsOn] - The start day of the week (0 = Sunday, 1 = Monday, ..., 6 = Saturday)\n *\n * @returns {{ startDate: Date, endDate: Date }} An object with `startDate` and `endDate`\n *\n * @example\n * ```typescript\n * import { getDateRangeFromDate } from '@kikiutils/shared/datetime';\n *\n * // Get the date range for last month\n * const date = new Date('2023-07-01');\n * console.log(getDateRangeFromDate(date, 'lastMonth'));\n * // { startDate: 2023-06-01T00:00:00.000Z, endDate: 2023-06-30T23:59:59.999Z }\n *\n * // Get this week's range with Sunday as the first day\n * console.log(getDateRangeFromDate(date, 'thisWeek', { weekStartsOn: 0 }));\n * // { startDate: 2023-06-25T00:00:00.000Z, endDate: 2023-07-01T23:59:59.999Z }\n * ```\n */\nexport function getDateRangeFromDate(\n date: Date,\n type: DateRangeType,\n options?: {\n setEndDateToNextDayStart?: boolean;\n weekStartsOn?: Day;\n },\n) {\n let endDate: Date;\n let startDate: Date;\n switch (type) {\n case 'lastMonth':\n {\n const lastMonth = subMonths(date, 1);\n endDate = endOfMonth(lastMonth);\n startDate = startOfMonth(lastMonth);\n }\n\n break;\n case 'lastWeek':\n {\n const lastWeek = subWeeks(date, 1);\n endDate = endOfWeek(lastWeek, { weekStartsOn: options?.weekStartsOn ?? 1 });\n startDate = startOfWeek(lastWeek, { weekStartsOn: options?.weekStartsOn ?? 1 });\n }\n\n break;\n case 'thisMonth':\n endDate = endOfMonth(date);\n startDate = startOfMonth(date);\n break;\n case 'thisWeek':\n endDate = endOfWeek(date, { weekStartsOn: options?.weekStartsOn ?? 1 });\n startDate = startOfWeek(date, { weekStartsOn: options?.weekStartsOn ?? 1 });\n break;\n case 'today':\n endDate = endOfDay(date);\n startDate = startOfDay(date);\n break;\n case 'yesterday':\n {\n const yesterday = subDays(date, 1);\n endDate = endOfDay(yesterday);\n startDate = startOfDay(yesterday);\n }\n\n break;\n default: throw new Error(`Unsupported date range type: ${type}`);\n }\n\n if (options?.setEndDateToNextDayStart) endDate.setHours(24, 0, 0, 0);\n return {\n endDate,\n startDate,\n };\n}\n\n/**\n * Returns a `Date` object set to midnight (00:00:00) of today, with an optional day offset.\n *\n * @param {number} [offsetDays] - Number of days to offset from today. Can be negative\n *\n * @returns {Date} A `Date` object at 00:00:00 of the offset day\n *\n * @example\n * ```typescript\n * import { getMidnightDateFromToday } from '@kikiutils/shared/datetime';\n *\n * console.log(getMidnightDateFromToday()); // today at 00:00:00\n * console.log(getMidnightDateFromToday(3)); // 3 days from today at 00:00:00\n * console.log(getMidnightDateFromToday(-1)); // yesterday at 00:00:00\n * ```\n */\nexport function getMidnightDateFromToday(offsetDays: number = 0) {\n const date = new Date();\n date.setDate(date.getDate() + offsetDays);\n date.setHours(0, 0, 0, 0);\n return date;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,SAAgB,WAAW,MAA0B,WAAiB,uBAAuB,SAAyB;CAClH,OAAOA,OAAc,MAAMC,UAAQ,OAAO;AAC9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,qBACZ,MACA,MACA,SAIF;CACE,IAAI;CACJ,IAAI;CACJ,QAAQ,MAAR;EACI,KAAK;GACD;IACI,MAAM,YAAY,UAAU,MAAM,CAAC;IACnC,UAAU,WAAW,SAAS;IAC9B,YAAY,aAAa,SAAS;GACtC;GAEA;EACJ,KAAK;GACD;IACI,MAAM,WAAW,SAAS,MAAM,CAAC;IACjC,UAAU,UAAU,UAAU,EAAE,cAAc,SAAS,gBAAgB,EAAE,CAAC;IAC1E,YAAY,YAAY,UAAU,EAAE,cAAc,SAAS,gBAAgB,EAAE,CAAC;GAClF;GAEA;EACJ,KAAK;GACD,UAAU,WAAW,IAAI;GACzB,YAAY,aAAa,IAAI;GAC7B;EACJ,KAAK;GACD,UAAU,UAAU,MAAM,EAAE,cAAc,SAAS,gBAAgB,EAAE,CAAC;GACtE,YAAY,YAAY,MAAM,EAAE,cAAc,SAAS,gBAAgB,EAAE,CAAC;GAC1E;EACJ,KAAK;GACD,UAAU,SAAS,IAAI;GACvB,YAAY,WAAW,IAAI;GAC3B;EACJ,KAAK;GACD;IACI,MAAM,YAAY,QAAQ,MAAM,CAAC;IACjC,UAAU,SAAS,SAAS;IAC5B,YAAY,WAAW,SAAS;GACpC;GAEA;EACJ,SAAS,MAAM,IAAI,MAAM,gCAAgC,MAAM;CACnE;CAEA,IAAI,SAAS,0BAA0B,QAAQ,SAAS,IAAI,GAAG,GAAG,CAAC;CACnE,OAAO;EACH;EACA;CACJ;AACJ;;;;;;;;;;;;;;;;;AAkBA,SAAgB,yBAAyB,aAAqB,GAAG;CAC7D,MAAM,uBAAO,IAAI,KAAK;CACtB,KAAK,QAAQ,KAAK,QAAQ,IAAI,UAAU;CACxC,KAAK,SAAS,GAAG,GAAG,GAAG,CAAC;CACxB,OAAO;AACX"}
@@ -1 +1 @@
1
- {"version":3,"file":"element-plus.d.ts","names":[],"sources":["../src/element-plus.ts"],"mappings":";;;;KAGY,wBAAA,GAA2B,QAAA;;AAAvC;;;;;AAyBA;;;;;;;;;;;;;;;;;iBAAgB,gCAAA,CACZ,OAAA,EAAS,YAAA,aACT,OAAA,GAAS,YAAA,GACV,YAAA"}
1
+ {"version":3,"file":"element-plus.d.ts","names":[],"sources":["../src/element-plus.ts"],"mappings":";;;;KAGY,wBAAA,GAA2B,QAAQ;;AAA/C;;;;AAA+C;AAyB/C;;;;;;;;;;;;;;AAGe;;;iBAHC,gCAAA,CACZ,OAAA,EAAS,YAAA,aACT,OAAA,GAAS,YAAA,GACV,YAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"element-plus.js","names":[],"sources":["../src/element-plus.ts"],"sourcesContent":["import type { RuleType } from 'async-validator';\nimport type { FormItemRule } from 'element-plus';\n\nexport type DoNotRemoveOrUseThisType = RuleType;\n\n/**\n * Creates a reusable Element Plus `<el-form-item>` validation rule with sensible defaults.\n *\n * This utility provides default values for `required`, `trigger`, and `type`,\n * while allowing overrides via the `options` parameter. It simplifies common\n * form validation rule creation and ensures consistency across forms.\n *\n * @param {FormItemRule['message']} message - The validation message to display when the rule fails\n * @param {FormItemRule} [options] - Optional overrides for the rule fields\n * @param {boolean} [options.required] - Whether the field is required (default: `true`)\n * @param {string | string[]} [options.trigger] - The event(s) that trigger validation (default: `'blur'`)\n * @param {RuleType} [options.type] - The expected type of the field (default: `'string'`)\n *\n * @returns A `FormItemRule` object that can be used in Element Plus form validation\n *\n * @example\n * ```typescript\n * import { createElFormItemRuleWithDefaults } from '@kikiutils/shared/element-plus';\n *\n * const rule = createElFormItemRuleWithDefaults('This field is required');\n * const optionalRule = createElFormItemRuleWithDefaults('Optional field', { required: false });\n * ```\n */\nexport function createElFormItemRuleWithDefaults(\n message: FormItemRule['message'],\n options: FormItemRule = {},\n): FormItemRule {\n return {\n ...options,\n message,\n required: options.required ?? true,\n trigger: options.trigger ?? 'blur',\n type: options.type ?? 'string',\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,iCACZ,SACA,UAAwB,EAAE,EACd;CACZ,OAAO;EACH,GAAG;EACH;EACA,UAAU,QAAQ,YAAY;EAC9B,SAAS,QAAQ,WAAW;EAC5B,MAAM,QAAQ,QAAQ;EACzB"}
1
+ {"version":3,"file":"element-plus.js","names":[],"sources":["../src/element-plus.ts"],"sourcesContent":["import type { RuleType } from 'async-validator';\nimport type { FormItemRule } from 'element-plus';\n\nexport type DoNotRemoveOrUseThisType = RuleType;\n\n/**\n * Creates a reusable Element Plus `<el-form-item>` validation rule with sensible defaults.\n *\n * This utility provides default values for `required`, `trigger`, and `type`,\n * while allowing overrides via the `options` parameter. It simplifies common\n * form validation rule creation and ensures consistency across forms.\n *\n * @param {FormItemRule['message']} message - The validation message to display when the rule fails\n * @param {FormItemRule} [options] - Optional overrides for the rule fields\n * @param {boolean} [options.required] - Whether the field is required (default: `true`)\n * @param {string | string[]} [options.trigger] - The event(s) that trigger validation (default: `'blur'`)\n * @param {RuleType} [options.type] - The expected type of the field (default: `'string'`)\n *\n * @returns A `FormItemRule` object that can be used in Element Plus form validation\n *\n * @example\n * ```typescript\n * import { createElFormItemRuleWithDefaults } from '@kikiutils/shared/element-plus';\n *\n * const rule = createElFormItemRuleWithDefaults('This field is required');\n * const optionalRule = createElFormItemRuleWithDefaults('Optional field', { required: false });\n * ```\n */\nexport function createElFormItemRuleWithDefaults(\n message: FormItemRule['message'],\n options: FormItemRule = {},\n): FormItemRule {\n return {\n ...options,\n message,\n required: options.required ?? true,\n trigger: options.trigger ?? 'blur',\n type: options.type ?? 'string',\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,iCACZ,SACA,UAAwB,CAAC,GACb;CACZ,OAAO;EACH,GAAG;EACH;EACA,UAAU,QAAQ,YAAY;EAC9B,SAAS,QAAQ,WAAW;EAC5B,MAAM,QAAQ,QAAQ;CAC1B;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"enum.d.ts","names":[],"sources":["../src/enum.ts"],"mappings":";;AAuBA;;;;;;;;;;;;;;;;;;;AA2BA;;;iBA3BgB,mBAAA,WAA8B,MAAA,cAAA,CAAqB,UAAA,EAAY,CAAA,GAAI,OAAA,CAAQ,CAAA,OAAQ,CAAA;;;;;;;;;;;;;;;;AA6EnG;;;;;;;;iBAlDgB,mBAAA,WAA8B,MAAA,cAAA,CAAqB,UAAA,EAAY,CAAA,GAAI,OAAA,CAAQ,CAAA,OAAQ,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkDnF,aAAA,WAAwB,MAAA,cAAA,CAAqB,UAAA,EAAY,CAAA,IAAK,CAAA,OAAQ,CAAA"}
1
+ {"version":3,"file":"enum.d.ts","names":[],"sources":["../src/enum.ts"],"mappings":";;AAuBA;;;;;;;;;;;;;;;;;;AAAoG;AA2BpG;;;iBA3BgB,mBAAA,WAA8B,MAAA,cAAA,CAAqB,UAAA,EAAY,CAAA,GAAI,OAAA,CAAQ,CAAA,OAAQ,CAAA;;;;;;;;;;;;;;;AA2BC;AAkDpG;;;;;;;;iBAlDgB,mBAAA,WAA8B,MAAA,cAAA,CAAqB,UAAA,EAAY,CAAA,GAAI,OAAA,CAAQ,CAAA,OAAQ,CAAA;;;;;;;;AAkDZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAvE,aAAA,WAAwB,MAAA,cAAA,CAAqB,UAAA,EAAY,CAAA,IAAK,CAAA,OAAQ,CAAA"}
package/dist/enum.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"enum.js","names":[],"sources":["../src/enum.ts"],"sourcesContent":["/**\n * Extracts only the numeric values from an enumeration-like object.\n *\n * @template T - The type of the enum object\n *\n * @param {T} enumObject - The enumeration-like object to extract numeric values from,\n * the object can contain numeric values, string values, or both.\n *\n * @returns {Extract<T[keyof T], number>[]} An array of numeric values extracted from the enum object\n *\n * @example\n * ```typescript\n * import { getEnumNumberValues } from '@kikiutils/shared/enum';\n *\n * enum RecordType {\n * Receive = 0,\n * Send = 1,\n * Unknown = 'unknown'\n * }\n *\n * console.log(getEnumNumberValues(RecordType)); // [0, 1]\n * ```\n */\nexport function getEnumNumberValues<T extends Record<string, any>>(enumObject: T): Extract<T[keyof T], number>[] {\n return getEnumValues(enumObject).filter((value) => typeof value === 'number');\n}\n\n/**\n * Extracts only the string values from an enumeration-like object.\n *\n * @template T - The type of the enum object\n *\n * @param {T} enumObject - The enumeration-like object to extract string values from,\n * the object can contain numeric values, string values, or both.\n *\n * @returns {Extract<T[keyof T], string>[]} An array of string values extracted from the enum object\n *\n * @example\n * ```typescript\n * import { getEnumStringValues } from '@kikiutils/shared/enum';\n *\n * enum RecordType {\n * Receive = 0,\n * Send = 1,\n * Unknown = 'unknown'\n * }\n *\n * console.log(getEnumStringValues(RecordType)); // ['unknown']\n * ```\n */\nexport function getEnumStringValues<T extends Record<string, any>>(enumObject: T): Extract<T[keyof T], string>[] {\n return getEnumValues(enumObject).filter((value) => typeof value === 'string');\n}\n\n/**\n * Extracts all values from an enumeration-like object.\n *\n * This function handles TypeScript enums correctly by accounting for the reverse mapping\n * that occurs with numeric enums. It works with pure numeric enums, pure string enums,\n * and mixed enums.\n *\n * @template T - The type of the enum object\n *\n * @param {T} enumObject - The enumeration-like object to extract values from,\n * the object can contain numeric values, string values, or both.\n *\n * @returns {(T[keyof T])[]} An array containing all the values from the enum object\n *\n * @example\n * ```typescript\n * import { getEnumValues } from '@kikiutils/shared/enum';\n *\n * // Numeric enum\n * enum Status {\n * Active = 0,\n * Inactive = 1,\n * Pending = 2\n * }\n *\n * console.log(getEnumValues(Status)); // [0, 1, 2]\n *\n * // String enum\n * enum Color {\n * Red = 'RED',\n * Green = 'GREEN',\n * Blue = 'BLUE'\n * }\n *\n * console.log(getEnumValues(Color)); // ['RED', 'GREEN', 'BLUE']\n *\n * // Mixed enum\n * enum RecordType {\n * Receive = 0,\n * Send = 1,\n * Unknown = 'unknown'\n * }\n *\n * console.log(getEnumValues(RecordType)); // [0, 1, 'unknown']\n * ```\n */\nexport function getEnumValues<T extends Record<string, any>>(enumObject: T): (T[keyof T])[] {\n const values = Object.values(enumObject);\n const hasNumberValues = values.some((value) => typeof value === 'number');\n if (!hasNumberValues) return values;\n return Object.keys(enumObject).filter((key) => Number.isNaN(Number(key))).map((key) => enumObject[key]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,oBAAmD,YAA8C;CAC7G,OAAO,cAAc,WAAW,CAAC,QAAQ,UAAU,OAAO,UAAU,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;AA0BjF,SAAgB,oBAAmD,YAA8C;CAC7G,OAAO,cAAc,WAAW,CAAC,QAAQ,UAAU,OAAO,UAAU,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDjF,SAAgB,cAA6C,YAA+B;CACxF,MAAM,SAAS,OAAO,OAAO,WAAW;CAExC,IAAI,CADoB,OAAO,MAAM,UAAU,OAAO,UAAU,SAC5C,EAAE,OAAO;CAC7B,OAAO,OAAO,KAAK,WAAW,CAAC,QAAQ,QAAQ,OAAO,MAAM,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,WAAW,KAAK"}
1
+ {"version":3,"file":"enum.js","names":[],"sources":["../src/enum.ts"],"sourcesContent":["/**\n * Extracts only the numeric values from an enumeration-like object.\n *\n * @template T - The type of the enum object\n *\n * @param {T} enumObject - The enumeration-like object to extract numeric values from,\n * the object can contain numeric values, string values, or both.\n *\n * @returns {Extract<T[keyof T], number>[]} An array of numeric values extracted from the enum object\n *\n * @example\n * ```typescript\n * import { getEnumNumberValues } from '@kikiutils/shared/enum';\n *\n * enum RecordType {\n * Receive = 0,\n * Send = 1,\n * Unknown = 'unknown'\n * }\n *\n * console.log(getEnumNumberValues(RecordType)); // [0, 1]\n * ```\n */\nexport function getEnumNumberValues<T extends Record<string, any>>(enumObject: T): Extract<T[keyof T], number>[] {\n return getEnumValues(enumObject).filter((value) => typeof value === 'number');\n}\n\n/**\n * Extracts only the string values from an enumeration-like object.\n *\n * @template T - The type of the enum object\n *\n * @param {T} enumObject - The enumeration-like object to extract string values from,\n * the object can contain numeric values, string values, or both.\n *\n * @returns {Extract<T[keyof T], string>[]} An array of string values extracted from the enum object\n *\n * @example\n * ```typescript\n * import { getEnumStringValues } from '@kikiutils/shared/enum';\n *\n * enum RecordType {\n * Receive = 0,\n * Send = 1,\n * Unknown = 'unknown'\n * }\n *\n * console.log(getEnumStringValues(RecordType)); // ['unknown']\n * ```\n */\nexport function getEnumStringValues<T extends Record<string, any>>(enumObject: T): Extract<T[keyof T], string>[] {\n return getEnumValues(enumObject).filter((value) => typeof value === 'string');\n}\n\n/**\n * Extracts all values from an enumeration-like object.\n *\n * This function handles TypeScript enums correctly by accounting for the reverse mapping\n * that occurs with numeric enums. It works with pure numeric enums, pure string enums,\n * and mixed enums.\n *\n * @template T - The type of the enum object\n *\n * @param {T} enumObject - The enumeration-like object to extract values from,\n * the object can contain numeric values, string values, or both.\n *\n * @returns {(T[keyof T])[]} An array containing all the values from the enum object\n *\n * @example\n * ```typescript\n * import { getEnumValues } from '@kikiutils/shared/enum';\n *\n * // Numeric enum\n * enum Status {\n * Active = 0,\n * Inactive = 1,\n * Pending = 2\n * }\n *\n * console.log(getEnumValues(Status)); // [0, 1, 2]\n *\n * // String enum\n * enum Color {\n * Red = 'RED',\n * Green = 'GREEN',\n * Blue = 'BLUE'\n * }\n *\n * console.log(getEnumValues(Color)); // ['RED', 'GREEN', 'BLUE']\n *\n * // Mixed enum\n * enum RecordType {\n * Receive = 0,\n * Send = 1,\n * Unknown = 'unknown'\n * }\n *\n * console.log(getEnumValues(RecordType)); // [0, 1, 'unknown']\n * ```\n */\nexport function getEnumValues<T extends Record<string, any>>(enumObject: T): (T[keyof T])[] {\n const values = Object.values(enumObject);\n const hasNumberValues = values.some((value) => typeof value === 'number');\n if (!hasNumberValues) return values;\n return Object.keys(enumObject).filter((key) => Number.isNaN(Number(key))).map((key) => enumObject[key]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,oBAAmD,YAA8C;CAC7G,OAAO,cAAc,UAAU,EAAE,QAAQ,UAAU,OAAO,UAAU,QAAQ;AAChF;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,oBAAmD,YAA8C;CAC7G,OAAO,cAAc,UAAU,EAAE,QAAQ,UAAU,OAAO,UAAU,QAAQ;AAChF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,SAAgB,cAA6C,YAA+B;CACxF,MAAM,SAAS,OAAO,OAAO,UAAU;CAEvC,IAAI,CADoB,OAAO,MAAM,UAAU,OAAO,UAAU,QAC7C,GAAG,OAAO;CAC7B,OAAO,OAAO,KAAK,UAAU,EAAE,QAAQ,QAAQ,OAAO,MAAM,OAAO,GAAG,CAAC,CAAC,EAAE,KAAK,QAAQ,WAAW,IAAI;AAC1G"}
package/dist/env.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.ts","names":[],"sources":["../src/env.ts"],"mappings":";;AAOA;;;;;;cAAa,wBAAA,SAAiC,KAAA;EAAA,SACjC,GAAA;EAOc;;AA+B3B;;;cA/BgB,GAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;iBA+BA,mBAAA,CAAoB,GAAA"}
1
+ {"version":3,"file":"env.d.ts","names":[],"sources":["../src/env.ts"],"mappings":";;AAOA;;;;;;cAAa,wBAAA,SAAiC,KAAK;EAAA,SACtC,GAAA;EAOc;AAAA;AA+B3B;;;cA/BgB,GAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;iBA+BA,mBAAA,CAAoB,GAAW"}
package/dist/env.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","names":[],"sources":["../src/env.ts"],"sourcesContent":["/**\n * Custom error class for handling missing environment variables.\n *\n * Extends the built-in `Error` class and includes the missing key.\n *\n * @extends {Error}\n */\nexport class EnvironmentNotFoundError extends Error {\n readonly key: string;\n\n /**\n * Creates a new EnvironmentNotFoundError.\n *\n * @param {string} key - The missing environment variable key\n */\n constructor(key: string) {\n super(`Missing environment variable: ${key}`);\n this.key = key;\n this.name = this.constructor.name;\n Error.captureStackTrace?.(this, this.constructor);\n }\n}\n\n/**\n * Retrieves the value of an environment variable, or throws an error if it is not defined.\n *\n * Only checks for `process.env[key] === undefined`. An empty string (e.g. '') or any falsy string\n * value like `'0'` or `'false'` is considered a valid (defined) value.\n *\n * @param {string} key - The environment variable key to retrieve\n *\n * @returns {string} The value of the environment variable\n *\n * @throws {EnvironmentNotFoundError} If the environment variable is not defined\n *\n * @example\n * ```typescript\n * import { checkAndGetEnvValue } from '@kikiutils/shared/env';\n *\n * process.env.API_KEY = '';\n * checkAndGetEnvValue('API_KEY'); // ✅ Returns '' (still considered \"defined\")\n *\n * delete process.env.API_KEY;\n * checkAndGetEnvValue('API_KEY'); // ❌ Throws EnvironmentNotFoundError\n * ```\n */\nexport function checkAndGetEnvValue(key: string) {\n if (process.env[key] === undefined) throw new EnvironmentNotFoundError(key);\n return process.env[key];\n}\n"],"mappings":";;;;;;;;AAOA,IAAa,2BAAb,cAA8C,MAAM;CAChD;;;;;;CAOA,YAAY,KAAa;EACrB,MAAM,iCAAiC,MAAM;EAC7C,KAAK,MAAM;EACX,KAAK,OAAO,KAAK,YAAY;EAC7B,MAAM,oBAAoB,MAAM,KAAK,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BzD,SAAgB,oBAAoB,KAAa;CAC7C,IAAI,QAAQ,IAAI,SAAS,KAAA,GAAW,MAAM,IAAI,yBAAyB,IAAI;CAC3E,OAAO,QAAQ,IAAI"}
1
+ {"version":3,"file":"env.js","names":[],"sources":["../src/env.ts"],"sourcesContent":["/**\n * Custom error class for handling missing environment variables.\n *\n * Extends the built-in `Error` class and includes the missing key.\n *\n * @extends {Error}\n */\nexport class EnvironmentNotFoundError extends Error {\n readonly key: string;\n\n /**\n * Creates a new EnvironmentNotFoundError.\n *\n * @param {string} key - The missing environment variable key\n */\n constructor(key: string) {\n super(`Missing environment variable: ${key}`);\n this.key = key;\n this.name = this.constructor.name;\n Error.captureStackTrace?.(this, this.constructor);\n }\n}\n\n/**\n * Retrieves the value of an environment variable, or throws an error if it is not defined.\n *\n * Only checks for `process.env[key] === undefined`. An empty string (e.g. '') or any falsy string\n * value like `'0'` or `'false'` is considered a valid (defined) value.\n *\n * @param {string} key - The environment variable key to retrieve\n *\n * @returns {string} The value of the environment variable\n *\n * @throws {EnvironmentNotFoundError} If the environment variable is not defined\n *\n * @example\n * ```typescript\n * import { checkAndGetEnvValue } from '@kikiutils/shared/env';\n *\n * process.env.API_KEY = '';\n * checkAndGetEnvValue('API_KEY'); // ✅ Returns '' (still considered \"defined\")\n *\n * delete process.env.API_KEY;\n * checkAndGetEnvValue('API_KEY'); // ❌ Throws EnvironmentNotFoundError\n * ```\n */\nexport function checkAndGetEnvValue(key: string) {\n if (process.env[key] === undefined) throw new EnvironmentNotFoundError(key);\n return process.env[key];\n}\n"],"mappings":";;;;;;;;AAOA,IAAa,2BAAb,cAA8C,MAAM;CAChD;;;;;;CAOA,YAAY,KAAa;EACrB,MAAM,iCAAiC,KAAK;EAC5C,KAAK,MAAM;EACX,KAAK,OAAO,KAAK,YAAY;EAC7B,MAAM,oBAAoB,MAAM,KAAK,WAAW;CACpD;AACJ;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,oBAAoB,KAAa;CAC7C,IAAI,QAAQ,IAAI,SAAS,KAAA,GAAW,MAAM,IAAI,yBAAyB,GAAG;CAC1E,OAAO,QAAQ,IAAI;AACvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"event-awaiter.d.ts","names":[],"sources":["../src/event-awaiter.ts"],"mappings":";;AAYA;;;;;;;;;;;cAAa,YAAA;EAAA;EAiIuD;;;;;;;;EAtHhE,OAAA,CAAQ,GAAA,UAAa,KAAA,EAAO,CAAA;EAiB5B;;;;;;;;;EAAA,UAAA,CAAW,KAAA,GAAO,CAAA;EA4BsE;;;;;;;;;;;;;;;;;;;;;;;EAAxF,IAAA,CAAK,GAAA,UAAa,SAAA,WAAoB,IAAA,0BAA8B,MAAA,GAAS,WAAA,GAAW,OAAA,CAAA,CAAA;;;;;;;;;;;EA2DxF,aAAA,CAAc,GAAA,UAAa,SAAA,WAAoB,MAAA,GAAS,WAAA,GAAW,OAAA,CAAA,CAAA;;;;;;;;;;;EAcnE,UAAA,CAAW,GAAA,UAAa,SAAA,WAAoB,MAAA,GAAS,WAAA,GAAW,OAAA,CAAA,CAAA;AAAA"}
1
+ {"version":3,"file":"event-awaiter.d.ts","names":[],"sources":["../src/event-awaiter.ts"],"mappings":";;AAYA;;;;;;;;;;;cAAa,YAAA;EAAA;EAiIuD;;;;;;;;EAtHhE,OAAA,CAAQ,GAAA,UAAa,KAAA,EAAO,CAAA;EAiB5B;;;;;;;;;EAAA,UAAA,CAAW,KAAA,GAAO,CAAA;EA4BsE;;;;;;;;;;;;;;;;AAyExB;;;;;;;EAzEhE,IAAA,CAAK,GAAA,UAAa,SAAA,WAAoB,IAAA,0BAA8B,MAAA,GAAS,WAAA,GAAW,OAAA,CAAA,CAAA;;;;;;;;;;;EA2DxF,aAAA,CAAc,GAAA,UAAa,SAAA,WAAoB,MAAA,GAAS,WAAA,GAAW,OAAA,CAAA,CAAA;;;;;;;;;;;EAcnE,UAAA,CAAW,GAAA,UAAa,SAAA,WAAoB,MAAA,GAAS,WAAA,GAAW,OAAA,CAAA,CAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"event-awaiter.js","names":["#promiseResolvers"],"sources":["../src/event-awaiter.ts"],"sourcesContent":["/**\n * EventAwaiter provides a mechanism to wait for events (by key) asynchronously.\n *\n * This class allows multiple consumers to `wait` for a specific key\n * and be resolved when `trigger` is called for that key, or automatically\n * resolved with `undefined` if a timeout occurs or an AbortSignal is triggered.\n *\n * Typical use cases include long-polling, request coordination,\n * or implementing event-driven primitives in applications or services.\n *\n * @template T - The type of value that will be resolved when the event is triggered\n */\nexport class EventAwaiter<T> {\n #promiseResolvers = new Map<string, ((value: PromiseLike<T | undefined> | T | undefined) => void)[]>();\n\n /**\n * Triggers all pending promises waiting for the given key.\n * Each promise will be resolved with the provided value.\n *\n * @param {string} key - Identifier for the awaited event\n * @param {T | undefined} value - The value to resolve the awaiting promises with.\n * May be `undefined` to indicate no result or a timeout-like behavior.\n */\n trigger(key: string, value: T | undefined) {\n const resolvers = this.#promiseResolvers.get(key);\n if (resolvers) {\n this.#promiseResolvers.delete(key);\n resolvers?.forEach((resolve) => resolve(value));\n }\n }\n\n /**\n * Triggers and resolves all pending promises across all keys.\n *\n * This is typically used during shutdown or cleanup to ensure that\n * no consumer is left waiting indefinitely.\n *\n * @param {T | undefined} [value] - Optional value to resolve all waiters with.\n * Defaults to `undefined`, which usually indicates cancellation or shutdown.\n */\n triggerAll(value: T | undefined = undefined) {\n for (const [_, resolvers] of this.#promiseResolvers.entries()) resolvers.forEach((resolve) => resolve(value));\n this.#promiseResolvers.clear();\n }\n\n /**\n * Waits for an event associated with the given key.\n *\n * The returned promise will resolve when:\n * - `trigger(key)` is called, in which case it resolves with the provided value.\n * - The optional timeout is reached, in which case it resolves with `undefined`.\n * - The optional `AbortSignal` is aborted, in which case it resolves with `undefined`.\n *\n * Behavior when multiple waiters exist for the same key:\n * - Default (no mode): multiple waiters are allowed, all will be resolved when triggered.\n * - `strict` mode: throws an error if a waiter already exists for the given key.\n * - `override` mode: cancels all existing waiters (resolving them with `undefined`)\n * and only keeps the latest one.\n *\n * @param {string} key - Identifier for the awaited event\n * @param {number} [timeoutMs] - Optional timeout (in milliseconds).\n * If reached, the promise resolves with `undefined`.\n * @param {'override' | 'strict'} [mode] - Optional behavior mode for handling multiple waiters\n * @param {AbortSignal} [signal] - Optional AbortSignal. If aborted, the promise resolves with `undefined`\n *\n * @returns {Promise<T | undefined>} A promise that resolves with the triggered value,\n * or `undefined` if timeout or abort occurs\n */\n wait(key: string, timeoutMs?: number, mode?: 'override' | 'strict', signal?: AbortSignal) {\n return new Promise<T | undefined>((resolve) => {\n const resolvers = this.#promiseResolvers.get(key) || [];\n if (resolvers.length) {\n switch (mode) {\n case 'override':\n resolvers.forEach((r) => r(undefined));\n resolvers.length = 0;\n break;\n case 'strict':\n throw new Error(`Duplicate wait detected for key: ${key}`);\n }\n }\n\n resolvers.push(resolve);\n this.#promiseResolvers.set(key, resolvers);\n if (timeoutMs != null) {\n setTimeout(\n () => {\n const resolvers = this.#promiseResolvers.get(key);\n if (resolvers?.includes(resolve)) {\n resolve(undefined);\n const newResolvers = resolvers.filter((r) => r !== resolve);\n if (newResolvers.length) this.#promiseResolvers.set(key, newResolvers);\n else this.#promiseResolvers.delete(key);\n }\n },\n timeoutMs,\n );\n }\n\n if (signal) {\n signal.addEventListener(\n 'abort',\n () => {\n const resolvers = this.#promiseResolvers.get(key);\n if (resolvers?.includes(resolve)) {\n resolve(undefined);\n const newResolvers = resolvers.filter((r) => r !== resolve);\n if (newResolvers.length) this.#promiseResolvers.set(key, newResolvers);\n else this.#promiseResolvers.delete(key);\n }\n },\n { once: true },\n );\n }\n });\n }\n\n /**\n * Waits for an event in strict mode.\n * Only one waiter is allowed per key. If another waiter already exists,\n * this method will throw an error.\n *\n * @param {string} key - Identifier for the awaited event\n * @param {number} [timeoutMs] - Optional timeout (in milliseconds).\n * If reached, the promise resolves with `undefined`.\n * @param {AbortSignal} [signal] - Optional AbortSignal. If aborted, the promise resolves with `undefined`\n */\n waitExclusive(key: string, timeoutMs?: number, signal?: AbortSignal) {\n return this.wait(key, timeoutMs, 'strict', signal);\n }\n\n /**\n * Waits for an event in override mode.\n * If another waiter already exists for the given key, it will be canceled\n * (resolved with `undefined`) and replaced by the new waiter.\n *\n * @param {string} key - Identifier for the awaited event\n * @param {number} [timeoutMs] - Optional timeout (in milliseconds).\n * If reached, the promise resolves with `undefined`.\n * @param {AbortSignal} [signal] - Optional AbortSignal. If aborted, the promise resolves with `undefined`\n */\n waitLatest(key: string, timeoutMs?: number, signal?: AbortSignal) {\n return this.wait(key, timeoutMs, 'override', signal);\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,IAAa,eAAb,MAA6B;CACzB,oCAAoB,IAAI,KAA8E;;;;;;;;;CAUtG,QAAQ,KAAa,OAAsB;EACvC,MAAM,YAAY,KAAKA,kBAAkB,IAAI,IAAI;EACjD,IAAI,WAAW;GACX,KAAKA,kBAAkB,OAAO,IAAI;GAClC,WAAW,SAAS,YAAY,QAAQ,MAAM,CAAC;;;;;;;;;;;;CAavD,WAAW,QAAuB,KAAA,GAAW;EACzC,KAAK,MAAM,CAAC,GAAG,cAAc,KAAKA,kBAAkB,SAAS,EAAE,UAAU,SAAS,YAAY,QAAQ,MAAM,CAAC;EAC7G,KAAKA,kBAAkB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;CA0BlC,KAAK,KAAa,WAAoB,MAA8B,QAAsB;EACtF,OAAO,IAAI,SAAwB,YAAY;GAC3C,MAAM,YAAY,KAAKA,kBAAkB,IAAI,IAAI,IAAI,EAAE;GACvD,IAAI,UAAU,QACV,QAAQ,MAAR;IACI,KAAK;KACD,UAAU,SAAS,MAAM,EAAE,KAAA,EAAU,CAAC;KACtC,UAAU,SAAS;KACnB;IACJ,KAAK,UACD,MAAM,IAAI,MAAM,oCAAoC,MAAM;;GAItE,UAAU,KAAK,QAAQ;GACvB,KAAKA,kBAAkB,IAAI,KAAK,UAAU;GAC1C,IAAI,aAAa,MACb,iBACU;IACF,MAAM,YAAY,KAAKA,kBAAkB,IAAI,IAAI;IACjD,IAAI,WAAW,SAAS,QAAQ,EAAE;KAC9B,QAAQ,KAAA,EAAU;KAClB,MAAM,eAAe,UAAU,QAAQ,MAAM,MAAM,QAAQ;KAC3D,IAAI,aAAa,QAAQ,KAAKA,kBAAkB,IAAI,KAAK,aAAa;UACjE,KAAKA,kBAAkB,OAAO,IAAI;;MAG/C,UACH;GAGL,IAAI,QACA,OAAO,iBACH,eACM;IACF,MAAM,YAAY,KAAKA,kBAAkB,IAAI,IAAI;IACjD,IAAI,WAAW,SAAS,QAAQ,EAAE;KAC9B,QAAQ,KAAA,EAAU;KAClB,MAAM,eAAe,UAAU,QAAQ,MAAM,MAAM,QAAQ;KAC3D,IAAI,aAAa,QAAQ,KAAKA,kBAAkB,IAAI,KAAK,aAAa;UACjE,KAAKA,kBAAkB,OAAO,IAAI;;MAG/C,EAAE,MAAM,MAAM,CACjB;IAEP;;;;;;;;;;;;CAaN,cAAc,KAAa,WAAoB,QAAsB;EACjE,OAAO,KAAK,KAAK,KAAK,WAAW,UAAU,OAAO;;;;;;;;;;;;CAatD,WAAW,KAAa,WAAoB,QAAsB;EAC9D,OAAO,KAAK,KAAK,KAAK,WAAW,YAAY,OAAO"}
1
+ {"version":3,"file":"event-awaiter.js","names":["#promiseResolvers"],"sources":["../src/event-awaiter.ts"],"sourcesContent":["/**\n * EventAwaiter provides a mechanism to wait for events (by key) asynchronously.\n *\n * This class allows multiple consumers to `wait` for a specific key\n * and be resolved when `trigger` is called for that key, or automatically\n * resolved with `undefined` if a timeout occurs or an AbortSignal is triggered.\n *\n * Typical use cases include long-polling, request coordination,\n * or implementing event-driven primitives in applications or services.\n *\n * @template T - The type of value that will be resolved when the event is triggered\n */\nexport class EventAwaiter<T> {\n #promiseResolvers = new Map<string, ((value: PromiseLike<T | undefined> | T | undefined) => void)[]>();\n\n /**\n * Triggers all pending promises waiting for the given key.\n * Each promise will be resolved with the provided value.\n *\n * @param {string} key - Identifier for the awaited event\n * @param {T | undefined} value - The value to resolve the awaiting promises with.\n * May be `undefined` to indicate no result or a timeout-like behavior.\n */\n trigger(key: string, value: T | undefined) {\n const resolvers = this.#promiseResolvers.get(key);\n if (resolvers) {\n this.#promiseResolvers.delete(key);\n resolvers?.forEach((resolve) => resolve(value));\n }\n }\n\n /**\n * Triggers and resolves all pending promises across all keys.\n *\n * This is typically used during shutdown or cleanup to ensure that\n * no consumer is left waiting indefinitely.\n *\n * @param {T | undefined} [value] - Optional value to resolve all waiters with.\n * Defaults to `undefined`, which usually indicates cancellation or shutdown.\n */\n triggerAll(value: T | undefined = undefined) {\n for (const [_, resolvers] of this.#promiseResolvers.entries()) resolvers.forEach((resolve) => resolve(value));\n this.#promiseResolvers.clear();\n }\n\n /**\n * Waits for an event associated with the given key.\n *\n * The returned promise will resolve when:\n * - `trigger(key)` is called, in which case it resolves with the provided value.\n * - The optional timeout is reached, in which case it resolves with `undefined`.\n * - The optional `AbortSignal` is aborted, in which case it resolves with `undefined`.\n *\n * Behavior when multiple waiters exist for the same key:\n * - Default (no mode): multiple waiters are allowed, all will be resolved when triggered.\n * - `strict` mode: throws an error if a waiter already exists for the given key.\n * - `override` mode: cancels all existing waiters (resolving them with `undefined`)\n * and only keeps the latest one.\n *\n * @param {string} key - Identifier for the awaited event\n * @param {number} [timeoutMs] - Optional timeout (in milliseconds).\n * If reached, the promise resolves with `undefined`.\n * @param {'override' | 'strict'} [mode] - Optional behavior mode for handling multiple waiters\n * @param {AbortSignal} [signal] - Optional AbortSignal. If aborted, the promise resolves with `undefined`\n *\n * @returns {Promise<T | undefined>} A promise that resolves with the triggered value,\n * or `undefined` if timeout or abort occurs\n */\n wait(key: string, timeoutMs?: number, mode?: 'override' | 'strict', signal?: AbortSignal) {\n return new Promise<T | undefined>((resolve) => {\n const resolvers = this.#promiseResolvers.get(key) || [];\n if (resolvers.length) {\n switch (mode) {\n case 'override':\n resolvers.forEach((r) => r(undefined));\n resolvers.length = 0;\n break;\n case 'strict':\n throw new Error(`Duplicate wait detected for key: ${key}`);\n }\n }\n\n resolvers.push(resolve);\n this.#promiseResolvers.set(key, resolvers);\n if (timeoutMs != null) {\n setTimeout(\n () => {\n const resolvers = this.#promiseResolvers.get(key);\n if (resolvers?.includes(resolve)) {\n resolve(undefined);\n const newResolvers = resolvers.filter((r) => r !== resolve);\n if (newResolvers.length) this.#promiseResolvers.set(key, newResolvers);\n else this.#promiseResolvers.delete(key);\n }\n },\n timeoutMs,\n );\n }\n\n if (signal) {\n signal.addEventListener(\n 'abort',\n () => {\n const resolvers = this.#promiseResolvers.get(key);\n if (resolvers?.includes(resolve)) {\n resolve(undefined);\n const newResolvers = resolvers.filter((r) => r !== resolve);\n if (newResolvers.length) this.#promiseResolvers.set(key, newResolvers);\n else this.#promiseResolvers.delete(key);\n }\n },\n { once: true },\n );\n }\n });\n }\n\n /**\n * Waits for an event in strict mode.\n * Only one waiter is allowed per key. If another waiter already exists,\n * this method will throw an error.\n *\n * @param {string} key - Identifier for the awaited event\n * @param {number} [timeoutMs] - Optional timeout (in milliseconds).\n * If reached, the promise resolves with `undefined`.\n * @param {AbortSignal} [signal] - Optional AbortSignal. If aborted, the promise resolves with `undefined`\n */\n waitExclusive(key: string, timeoutMs?: number, signal?: AbortSignal) {\n return this.wait(key, timeoutMs, 'strict', signal);\n }\n\n /**\n * Waits for an event in override mode.\n * If another waiter already exists for the given key, it will be canceled\n * (resolved with `undefined`) and replaced by the new waiter.\n *\n * @param {string} key - Identifier for the awaited event\n * @param {number} [timeoutMs] - Optional timeout (in milliseconds).\n * If reached, the promise resolves with `undefined`.\n * @param {AbortSignal} [signal] - Optional AbortSignal. If aborted, the promise resolves with `undefined`\n */\n waitLatest(key: string, timeoutMs?: number, signal?: AbortSignal) {\n return this.wait(key, timeoutMs, 'override', signal);\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,IAAa,eAAb,MAA6B;CACzB,oCAAoB,IAAI,IAA6E;;;;;;;;;CAUrG,QAAQ,KAAa,OAAsB;EACvC,MAAM,YAAY,KAAKA,kBAAkB,IAAI,GAAG;EAChD,IAAI,WAAW;GACX,KAAKA,kBAAkB,OAAO,GAAG;GACjC,WAAW,SAAS,YAAY,QAAQ,KAAK,CAAC;EAClD;CACJ;;;;;;;;;;CAWA,WAAW,QAAuB,KAAA,GAAW;EACzC,KAAK,MAAM,CAAC,GAAG,cAAc,KAAKA,kBAAkB,QAAQ,GAAG,UAAU,SAAS,YAAY,QAAQ,KAAK,CAAC;EAC5G,KAAKA,kBAAkB,MAAM;CACjC;;;;;;;;;;;;;;;;;;;;;;;;CAyBA,KAAK,KAAa,WAAoB,MAA8B,QAAsB;EACtF,OAAO,IAAI,SAAwB,YAAY;GAC3C,MAAM,YAAY,KAAKA,kBAAkB,IAAI,GAAG,KAAK,CAAC;GACtD,IAAI,UAAU,QACV,QAAQ,MAAR;IACI,KAAK;KACD,UAAU,SAAS,MAAM,EAAE,KAAA,CAAS,CAAC;KACrC,UAAU,SAAS;KACnB;IACJ,KAAK,UACD,MAAM,IAAI,MAAM,oCAAoC,KAAK;GACjE;GAGJ,UAAU,KAAK,OAAO;GACtB,KAAKA,kBAAkB,IAAI,KAAK,SAAS;GACzC,IAAI,aAAa,MACb,iBACU;IACF,MAAM,YAAY,KAAKA,kBAAkB,IAAI,GAAG;IAChD,IAAI,WAAW,SAAS,OAAO,GAAG;KAC9B,QAAQ,KAAA,CAAS;KACjB,MAAM,eAAe,UAAU,QAAQ,MAAM,MAAM,OAAO;KAC1D,IAAI,aAAa,QAAQ,KAAKA,kBAAkB,IAAI,KAAK,YAAY;UAChE,KAAKA,kBAAkB,OAAO,GAAG;IAC1C;GACJ,GACA,SACJ;GAGJ,IAAI,QACA,OAAO,iBACH,eACM;IACF,MAAM,YAAY,KAAKA,kBAAkB,IAAI,GAAG;IAChD,IAAI,WAAW,SAAS,OAAO,GAAG;KAC9B,QAAQ,KAAA,CAAS;KACjB,MAAM,eAAe,UAAU,QAAQ,MAAM,MAAM,OAAO;KAC1D,IAAI,aAAa,QAAQ,KAAKA,kBAAkB,IAAI,KAAK,YAAY;UAChE,KAAKA,kBAAkB,OAAO,GAAG;IAC1C;GACJ,GACA,EAAE,MAAM,KAAK,CACjB;EAER,CAAC;CACL;;;;;;;;;;;CAYA,cAAc,KAAa,WAAoB,QAAsB;EACjE,OAAO,KAAK,KAAK,KAAK,WAAW,UAAU,MAAM;CACrD;;;;;;;;;;;CAYA,WAAW,KAAa,WAAoB,QAAsB;EAC9D,OAAO,KAAK,KAAK,KAAK,WAAW,YAAY,MAAM;CACvD;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"general.d.ts","names":[],"sources":["../src/general.ts"],"mappings":";;AA2BA;;;;;;;;;;;;;;;AACA;;;;;;;;;iBADgB,iBAAA,GAAA,CAAqB,KAAA,EAAO,CAAA,GAAI,CAAA,KAAM,CAAA;AAAA,iBACtC,iBAAA,MAAA,CAAwB,KAAA,EAAO,CAAA,GAAI,CAAA,IAAK,YAAA,EAAc,CAAA,GAAI,CAAA,GAAI,WAAA,CAAY,CAAA"}
1
+ {"version":3,"file":"general.d.ts","names":[],"sources":["../src/general.ts"],"mappings":";;AA2BA;;;;;;;;;;;;;;AAAuD;AACvD;;;;;;;;;iBADgB,iBAAA,GAAA,CAAqB,KAAA,EAAO,CAAA,GAAI,CAAA,KAAM,CAAA;AAAA,iBACtC,iBAAA,MAAA,CAAwB,KAAA,EAAO,CAAA,GAAI,CAAA,IAAK,YAAA,EAAc,CAAA,GAAI,CAAA,GAAI,WAAA,CAAY,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"general.js","names":[],"sources":["../src/general.ts"],"sourcesContent":["/* eslint-disable jsdoc/check-param-names */\n\n/**\n * Extracts the first value from an array or returns the value itself if it's not an array.\n *\n * - If `value` is an array, returns the first element.\n * - If `value` is not an array, returns `value` directly.\n * - If the result is `null` or `undefined`, and `defaultValue` is provided, returns `defaultValue` instead.\n *\n * @template T - The type of the input value(s)\n * @template D - The type of the default value (if provided)\n *\n * @param {T | T[]} value - A single value or an array of values\n * @param {D} [defaultValue] - A fallback value if the result is `null` or `undefined`\n *\n * @returns {T | D | undefined} The first value or the fallback\n *\n * @example\n * ```typescript\n * import { extractFirstValue } from '@kikiutils/shared/general';\n *\n * console.log(extractFirstValue([1, 2, 3])); // 1\n * console.log(extractFirstValue('hello')); // hello\n * console.log(extractFirstValue([], 'default')); // default\n * console.log(extractFirstValue(undefined, 'fallback')); // fallback\n * ```\n */\nexport function extractFirstValue<T>(value: T | T[]): T | undefined;\nexport function extractFirstValue<T, D>(value: T | T[], defaultValue: D): D | NonNullable<T>;\nexport function extractFirstValue<T, D>(value: T | T[], defaultValue?: D) {\n return (Array.isArray(value) ? value[0] : value) ?? defaultValue;\n}\n\n/* eslint-enable jsdoc/check-param-names */\n"],"mappings":";AA6BA,SAAgB,kBAAwB,OAAgB,cAAkB;CACtE,QAAQ,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,UAAU"}
1
+ {"version":3,"file":"general.js","names":[],"sources":["../src/general.ts"],"sourcesContent":["/* eslint-disable jsdoc/check-param-names */\n\n/**\n * Extracts the first value from an array or returns the value itself if it's not an array.\n *\n * - If `value` is an array, returns the first element.\n * - If `value` is not an array, returns `value` directly.\n * - If the result is `null` or `undefined`, and `defaultValue` is provided, returns `defaultValue` instead.\n *\n * @template T - The type of the input value(s)\n * @template D - The type of the default value (if provided)\n *\n * @param {T | T[]} value - A single value or an array of values\n * @param {D} [defaultValue] - A fallback value if the result is `null` or `undefined`\n *\n * @returns {T | D | undefined} The first value or the fallback\n *\n * @example\n * ```typescript\n * import { extractFirstValue } from '@kikiutils/shared/general';\n *\n * console.log(extractFirstValue([1, 2, 3])); // 1\n * console.log(extractFirstValue('hello')); // hello\n * console.log(extractFirstValue([], 'default')); // default\n * console.log(extractFirstValue(undefined, 'fallback')); // fallback\n * ```\n */\nexport function extractFirstValue<T>(value: T | T[]): T | undefined;\nexport function extractFirstValue<T, D>(value: T | T[], defaultValue: D): D | NonNullable<T>;\nexport function extractFirstValue<T, D>(value: T | T[], defaultValue?: D) {\n return (Array.isArray(value) ? value[0] : value) ?? defaultValue;\n}\n\n/* eslint-enable jsdoc/check-param-names */\n"],"mappings":";AA6BA,SAAgB,kBAAwB,OAAgB,cAAkB;CACtE,QAAQ,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,UAAU;AACxD"}
@@ -1 +1 @@
1
- {"version":3,"file":"hash.d.ts","names":[],"sources":["../src/hash.ts"],"mappings":";;AAyBA;;;;;AAkBA;;;;;AAkBA;;;iBApCgB,OAAA,CAAQ,IAAA,WAAe,UAAA;;AAsDvC;;;;;;;;;;;;;iBApCgB,OAAA,CAAQ,IAAA,WAAe,UAAA;;;;;;;;;;;;;;;iBAkBvB,OAAA,CAAQ,IAAA,WAAe,UAAA;;;;;;;;;;;;;;;iBAkBvB,OAAA,CAAQ,IAAA,WAAe,UAAA"}
1
+ {"version":3,"file":"hash.d.ts","names":[],"sources":["../src/hash.ts"],"mappings":";;AAyBA;;;;AAAiD;AAkBjD;;;;AAAiD;AAkBjD;;;iBApCgB,OAAA,CAAQ,IAAyB,WAAV,UAAU;AAoCA;AAkBjD;;;;AAAiD;;;;;;;;;AAlBA,iBAlBjC,OAAA,CAAQ,IAAyB,WAAV,UAAU;;;;;;;;;;;;;;;iBAkBjC,OAAA,CAAQ,IAAyB,WAAV,UAAU;;;;;;;;;;;;;;;iBAkBjC,OAAA,CAAQ,IAAyB,WAAV,UAAU"}
package/dist/hash.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hash.js","names":[],"sources":["../src/hash.ts"],"sourcesContent":["import {\n sha3_224,\n sha3_256,\n sha3_384,\n sha3_512,\n} from '@noble/hashes/sha3.js';\nimport {\n bytesToHex,\n utf8ToBytes,\n} from '@noble/hashes/utils.js';\n\n/**\n * Computes the SHA-3 hash of the given data using the 224-bit digest.\n *\n * @param {string | Uint8Array} data - The input data to hash\n *\n * @returns {string} The hexadecimal hash digest\n *\n * @example\n * ```typescript\n * import { sha3224 } from '@kikiutils/shared/hash';\n *\n * console.log(sha3224('test')); // 3797bf0afbbfca4a7bbba7602a2b552746876517a7f9b7ce2db0ae7b\n * ```\n */\nexport function sha3224(data: string | Uint8Array) {\n return bytesToHex(sha3_224(typeof data === 'string' ? utf8ToBytes(data) : data));\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 256-bit digest.\n *\n * @param {string | Uint8Array} data - The input data to hash\n *\n * @returns {string} The hexadecimal hash digest\n *\n * @example\n * ```typescript\n * import { sha3256 } from '@kikiutils/shared/hash';\n *\n * console.log(sha3256('test')); // 36f028580bb02cc8272a9a020f4200e346e276ae664e45ee80745574e2f5ab80\n * ```\n */\nexport function sha3256(data: string | Uint8Array) {\n return bytesToHex(sha3_256(typeof data === 'string' ? utf8ToBytes(data) : data));\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 384-bit digest.\n *\n * @param {string | Uint8Array} data - The input data to hash\n *\n * @returns {string} The hexadecimal hash digest\n *\n * @example\n * ```typescript\n * import { sha3384 } from '@kikiutils/shared/hash';\n *\n * console.log(sha3384('test')); // e516dabb23b6e30026863543282780a3ae0dccf05551cf0295178d7f...\n * ```\n */\nexport function sha3384(data: string | Uint8Array) {\n return bytesToHex(sha3_384(typeof data === 'string' ? utf8ToBytes(data) : data));\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 512-bit digest.\n *\n * @param {string | Uint8Array} data - The input data to hash\n *\n * @returns {string} The hexadecimal hash digest\n *\n * @example\n * ```typescript\n * import { sha3512 } from '@kikiutils/shared/hash';\n *\n * console.log(sha3512('test')); // 9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7...\n * ```\n */\nexport function sha3512(data: string | Uint8Array) {\n return bytesToHex(sha3_512(typeof data === 'string' ? utf8ToBytes(data) : data));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAyBA,SAAgB,QAAQ,MAA2B;CAC/C,OAAO,WAAW,SAAS,OAAO,SAAS,WAAW,YAAY,KAAK,GAAG,KAAK,CAAC;;;;;;;;;;;;;;;;AAiBpF,SAAgB,QAAQ,MAA2B;CAC/C,OAAO,WAAW,SAAS,OAAO,SAAS,WAAW,YAAY,KAAK,GAAG,KAAK,CAAC;;;;;;;;;;;;;;;;AAiBpF,SAAgB,QAAQ,MAA2B;CAC/C,OAAO,WAAW,SAAS,OAAO,SAAS,WAAW,YAAY,KAAK,GAAG,KAAK,CAAC;;;;;;;;;;;;;;;;AAiBpF,SAAgB,QAAQ,MAA2B;CAC/C,OAAO,WAAW,SAAS,OAAO,SAAS,WAAW,YAAY,KAAK,GAAG,KAAK,CAAC"}
1
+ {"version":3,"file":"hash.js","names":[],"sources":["../src/hash.ts"],"sourcesContent":["import {\n sha3_224,\n sha3_256,\n sha3_384,\n sha3_512,\n} from '@noble/hashes/sha3.js';\nimport {\n bytesToHex,\n utf8ToBytes,\n} from '@noble/hashes/utils.js';\n\n/**\n * Computes the SHA-3 hash of the given data using the 224-bit digest.\n *\n * @param {string | Uint8Array} data - The input data to hash\n *\n * @returns {string} The hexadecimal hash digest\n *\n * @example\n * ```typescript\n * import { sha3224 } from '@kikiutils/shared/hash';\n *\n * console.log(sha3224('test')); // 3797bf0afbbfca4a7bbba7602a2b552746876517a7f9b7ce2db0ae7b\n * ```\n */\nexport function sha3224(data: string | Uint8Array) {\n return bytesToHex(sha3_224(typeof data === 'string' ? utf8ToBytes(data) : data));\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 256-bit digest.\n *\n * @param {string | Uint8Array} data - The input data to hash\n *\n * @returns {string} The hexadecimal hash digest\n *\n * @example\n * ```typescript\n * import { sha3256 } from '@kikiutils/shared/hash';\n *\n * console.log(sha3256('test')); // 36f028580bb02cc8272a9a020f4200e346e276ae664e45ee80745574e2f5ab80\n * ```\n */\nexport function sha3256(data: string | Uint8Array) {\n return bytesToHex(sha3_256(typeof data === 'string' ? utf8ToBytes(data) : data));\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 384-bit digest.\n *\n * @param {string | Uint8Array} data - The input data to hash\n *\n * @returns {string} The hexadecimal hash digest\n *\n * @example\n * ```typescript\n * import { sha3384 } from '@kikiutils/shared/hash';\n *\n * console.log(sha3384('test')); // e516dabb23b6e30026863543282780a3ae0dccf05551cf0295178d7f...\n * ```\n */\nexport function sha3384(data: string | Uint8Array) {\n return bytesToHex(sha3_384(typeof data === 'string' ? utf8ToBytes(data) : data));\n}\n\n/**\n * Computes the SHA-3 hash of the given data using the 512-bit digest.\n *\n * @param {string | Uint8Array} data - The input data to hash\n *\n * @returns {string} The hexadecimal hash digest\n *\n * @example\n * ```typescript\n * import { sha3512 } from '@kikiutils/shared/hash';\n *\n * console.log(sha3512('test')); // 9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7...\n * ```\n */\nexport function sha3512(data: string | Uint8Array) {\n return bytesToHex(sha3_512(typeof data === 'string' ? utf8ToBytes(data) : data));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAyBA,SAAgB,QAAQ,MAA2B;CAC/C,OAAO,WAAW,SAAS,OAAO,SAAS,WAAW,YAAY,IAAI,IAAI,IAAI,CAAC;AACnF;;;;;;;;;;;;;;;AAgBA,SAAgB,QAAQ,MAA2B;CAC/C,OAAO,WAAW,SAAS,OAAO,SAAS,WAAW,YAAY,IAAI,IAAI,IAAI,CAAC;AACnF;;;;;;;;;;;;;;;AAgBA,SAAgB,QAAQ,MAA2B;CAC/C,OAAO,WAAW,SAAS,OAAO,SAAS,WAAW,YAAY,IAAI,IAAI,IAAI,CAAC;AACnF;;;;;;;;;;;;;;;AAgBA,SAAgB,QAAQ,MAA2B;CAC/C,OAAO,WAAW,SAAS,OAAO,SAAS,WAAW,YAAY,IAAI,IAAI,IAAI,CAAC;AACnF"}
@@ -1 +1 @@
1
- {"version":3,"file":"math.d.ts","names":[],"sources":["../src/math.ts"],"mappings":";;;KAEK,eAAA,GAAkB,OAAA,CAAQ,KAAA;EAAU,QAAA;AAAA;;;;UAKxB,yBAAA;EALc;;;;AAK/B;EAMI,aAAA;;;;AAgCJ;;EAzBI,UAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;iBAyBY,kBAAA,CACZ,SAAA,EAAW,eAAA,EACX,WAAA,EAAa,eAAA,EACb,OAAA,GAAU,yBAAA"}
1
+ {"version":3,"file":"math.d.ts","names":[],"sources":["../src/math.ts"],"mappings":";;;KAEK,eAAA,GAAkB,OAAA,CAAQ,KAAK;EAAK,QAAA;AAAA;;;;UAKxB,yBAAA;EALc;;;AAAkB;AAKjD;EAMI,aAAA;;;AAOU;AAyBd;;EAzBI,UAAU;AAAA;;;;;;;;;;;;AA4ByB;;;;;;;;;;;iBAHvB,kBAAA,CACZ,SAAA,EAAW,eAAA,EACX,WAAA,EAAa,eAAA,EACb,OAAA,GAAU,yBAAA"}
package/dist/math.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"math.js","names":[],"sources":["../src/math.ts"],"sourcesContent":["import { Decimal } from 'decimal.js';\n\ntype CalculableValue = Decimal.Value | { toString: () => string };\n\n/**\n * Options for configuring the output of `toPercentageString`.\n */\nexport interface ToPercentageStringOptions {\n /**\n * Number of decimal places to include in the result.\n *\n * @default 2\n */\n decimalPlaces?: number;\n\n /**\n * Whether to include the '%' symbol in the result.\n *\n * @default true\n */\n withSymbol?: boolean;\n}\n\n/**\n * Converts a fraction (numerator / denominator) into a percentage string.\n *\n * - Uses `decimal.js` for precise decimal calculations.\n * - Supports custom decimal places and optional percentage symbol.\n * - Returns `'0.00%'` if result is `NaN` or division is invalid.\n *\n * @param {CalculableValue} molecular - The numerator of the fraction\n * @param {CalculableValue} denominator - The denominator of the fraction\n * @param {ToPercentageStringOptions} [options] - Optional output settings\n *\n * @returns {string} Formatted percentage string\n *\n * @example\n * ```typescript\n * import { toPercentageString } from '@kikiutils/shared/math';\n *\n * console.log(toPercentageString(50, 200)); // 25.00%\n * console.log(toPercentageString(50, 200, { withSymbol: false })); // 25.00\n * console.log(toPercentageString(50, 200, { decimalPlaces: 1 })); // 25.0%\n * ```\n */\nexport function toPercentageString(\n molecular: CalculableValue,\n denominator: CalculableValue,\n options?: ToPercentageStringOptions,\n) {\n const molecularDecimal = new Decimal(molecular.toString());\n const denominatorDecimal = new Decimal(denominator.toString());\n const calculationResult = molecularDecimal.div(denominatorDecimal);\n\n const result = calculationResult.isNaN() || !calculationResult.isFinite()\n ? '0.00'\n : calculationResult.times(100).toFixed(options?.decimalPlaces ?? 2);\n\n return options?.withSymbol ?? true ? `${result}%` : result;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA6CA,SAAgB,mBACZ,WACA,aACA,SACF;CACE,MAAM,mBAAmB,IAAI,QAAQ,UAAU,UAAU,CAAC;CAC1D,MAAM,qBAAqB,IAAI,QAAQ,YAAY,UAAU,CAAC;CAC9D,MAAM,oBAAoB,iBAAiB,IAAI,mBAAmB;CAElE,MAAM,SAAS,kBAAkB,OAAO,IAAI,CAAC,kBAAkB,UAAU,GACnE,SACA,kBAAkB,MAAM,IAAI,CAAC,QAAQ,SAAS,iBAAiB,EAAE;CAEvE,OAAO,SAAS,cAAc,OAAO,GAAG,OAAO,KAAK"}
1
+ {"version":3,"file":"math.js","names":[],"sources":["../src/math.ts"],"sourcesContent":["import { Decimal } from 'decimal.js';\n\ntype CalculableValue = Decimal.Value | { toString: () => string };\n\n/**\n * Options for configuring the output of `toPercentageString`.\n */\nexport interface ToPercentageStringOptions {\n /**\n * Number of decimal places to include in the result.\n *\n * @default 2\n */\n decimalPlaces?: number;\n\n /**\n * Whether to include the '%' symbol in the result.\n *\n * @default true\n */\n withSymbol?: boolean;\n}\n\n/**\n * Converts a fraction (numerator / denominator) into a percentage string.\n *\n * - Uses `decimal.js` for precise decimal calculations.\n * - Supports custom decimal places and optional percentage symbol.\n * - Returns `'0.00%'` if result is `NaN` or division is invalid.\n *\n * @param {CalculableValue} molecular - The numerator of the fraction\n * @param {CalculableValue} denominator - The denominator of the fraction\n * @param {ToPercentageStringOptions} [options] - Optional output settings\n *\n * @returns {string} Formatted percentage string\n *\n * @example\n * ```typescript\n * import { toPercentageString } from '@kikiutils/shared/math';\n *\n * console.log(toPercentageString(50, 200)); // 25.00%\n * console.log(toPercentageString(50, 200, { withSymbol: false })); // 25.00\n * console.log(toPercentageString(50, 200, { decimalPlaces: 1 })); // 25.0%\n * ```\n */\nexport function toPercentageString(\n molecular: CalculableValue,\n denominator: CalculableValue,\n options?: ToPercentageStringOptions,\n) {\n const molecularDecimal = new Decimal(molecular.toString());\n const denominatorDecimal = new Decimal(denominator.toString());\n const calculationResult = molecularDecimal.div(denominatorDecimal);\n\n const result = calculationResult.isNaN() || !calculationResult.isFinite()\n ? '0.00'\n : calculationResult.times(100).toFixed(options?.decimalPlaces ?? 2);\n\n return options?.withSymbol ?? true ? `${result}%` : result;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA6CA,SAAgB,mBACZ,WACA,aACA,SACF;CACE,MAAM,mBAAmB,IAAI,QAAQ,UAAU,SAAS,CAAC;CACzD,MAAM,qBAAqB,IAAI,QAAQ,YAAY,SAAS,CAAC;CAC7D,MAAM,oBAAoB,iBAAiB,IAAI,kBAAkB;CAEjE,MAAM,SAAS,kBAAkB,MAAM,KAAK,CAAC,kBAAkB,SAAS,IAClE,SACA,kBAAkB,MAAM,GAAG,EAAE,QAAQ,SAAS,iBAAiB,CAAC;CAEtE,OAAO,SAAS,cAAc,OAAO,GAAG,OAAO,KAAK;AACxD"}
@@ -1 +1 @@
1
- {"version":3,"file":"number.d.ts","names":[],"sources":["../src/number.ts"],"mappings":";;;;;AAoBA;;;;;;;;;;;;;;;;iBAAgB,qBAAA,CAAsB,KAAA,UAAe,OAAA,GAAU,UAAA,QAAkB,OAAA"}
1
+ {"version":3,"file":"number.d.ts","names":[],"sources":["../src/number.ts"],"mappings":";;;;;AAoBA;;;;;;;;;AAA4F;;;;;;;iBAA5E,qBAAA,CAAsB,KAAA,UAAe,OAAA,GAAU,UAAU,QAAQ,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"number.js","names":[],"sources":["../src/number.ts"],"sourcesContent":["import { millify } from 'millify';\n\n/**\n * Converts a large number into a compact, human-readable string using `millify`.\n *\n * Applies lowercase units (e.g. 'k', 'm') and default precision of 2, unless overridden.\n *\n * @param {number} value - The number to format\n * @param {Parameters<typeof millify>[1]} [options] - Optional configuration passed to `millify`\n *\n * @returns {string} The compact number string\n *\n * @example\n * ```typescript\n * import { toCompactNumberString } from '@kikiutils/shared/number';\n *\n * console.log(toCompactNumberString(1234567)); // 1.23m\n * console.log(toCompactNumberString(1234567, { precision: 3 })); // 1.235m\n * ```\n */\nexport function toCompactNumberString(value: number, options?: Parameters<typeof millify>[1]) {\n return millify(\n value,\n {\n lowercase: true,\n precision: 2,\n ...options,\n },\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,sBAAsB,OAAe,SAAyC;CAC1F,OAAO,QACH,OACA;EACI,WAAW;EACX,WAAW;EACX,GAAG;EACN,CACJ"}
1
+ {"version":3,"file":"number.js","names":[],"sources":["../src/number.ts"],"sourcesContent":["import { millify } from 'millify';\n\n/**\n * Converts a large number into a compact, human-readable string using `millify`.\n *\n * Applies lowercase units (e.g. 'k', 'm') and default precision of 2, unless overridden.\n *\n * @param {number} value - The number to format\n * @param {Parameters<typeof millify>[1]} [options] - Optional configuration passed to `millify`\n *\n * @returns {string} The compact number string\n *\n * @example\n * ```typescript\n * import { toCompactNumberString } from '@kikiutils/shared/number';\n *\n * console.log(toCompactNumberString(1234567)); // 1.23m\n * console.log(toCompactNumberString(1234567, { precision: 3 })); // 1.235m\n * ```\n */\nexport function toCompactNumberString(value: number, options?: Parameters<typeof millify>[1]) {\n return millify(\n value,\n {\n lowercase: true,\n precision: 2,\n ...options,\n },\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,sBAAsB,OAAe,SAAyC;CAC1F,OAAO,QACH,OACA;EACI,WAAW;EACX,WAAW;EACX,GAAG;CACP,CACJ;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"object.d.ts","names":[],"sources":["../src/object.ts"],"mappings":";;AA2BA;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,gCAAA,CACZ,KAAA,EAAO,MAAA,eACP,WAAA,WACA,aAAA"}
1
+ {"version":3,"file":"object.d.ts","names":[],"sources":["../src/object.ts"],"mappings":";;AA2BA;;;;;;;;;AAG+B;;;;;;;;;;;;;;;;;iBAHf,gCAAA,CACZ,KAAA,EAAO,MAAM,eACb,WAAA,WACA,aAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"object.js","names":[],"sources":["../src/object.ts"],"sourcesContent":["/**\n * Serializes a nested object into a deterministic, flat string format.\n *\n * This function recursively traverses the input object (including nested objects and arrays),\n * flattens it into key paths using dot notation (e.g. \"a.b.0.c\"), sorts all keys,\n * and joins each key-value pair into a string with customizable separators.\n *\n * It is designed for use cases such as signature generation, cache key construction,\n * or any context requiring consistent and predictable object serialization.\n *\n * Note: Empty objects and arrays produce an empty string, which is useful for\n * generating deterministic signature payloads.\n *\n * @param {Record<string, any>} input - The object to serialize. Can contain nested objects and arrays\n * @param {string} kvSeparator - The string used to separate each key from its value (default: '=')\n * @param {string} pairSeparator - The string used to separate each key-value pair (default: '&')\n * @returns {string} A deterministic string representation of the input object\n *\n * @example\n * ```typescript\n * import { stringifyObjectDeterministically } from '@kikiutils/shared/object';\n *\n * console.log(stringifyObjectDeterministically({ b: 2, a: { x: 1, y: [3, 4] } })); // a.x=1&a.y.0=3&a.y.1=4&b=2\n * console.log(stringifyObjectDeterministically({ foo: 'bar' }, ':', '|')); // foo:bar\n * console.log(stringifyObjectDeterministically({})); // ''\n * ```\n */\nexport function stringifyObjectDeterministically(\n input: Record<string, any>,\n kvSeparator: string = '=',\n pairSeparator: string = '&',\n) {\n const entries: string[] = [];\n\n function walk(object: any, path: string[] = []) {\n if (Array.isArray(object)) {\n object.forEach((value, i) => {\n walk(\n value,\n [\n ...path,\n i.toString(),\n ],\n );\n });\n } else if (\n object !== null\n && typeof object === 'object'\n && Object.prototype.toString.call(object) === '[object Object]'\n ) {\n Object.keys(object).sort().forEach((key) => {\n walk(\n object[key],\n [\n ...path,\n key,\n ],\n );\n });\n } else entries.push(`${path.join('.')}${kvSeparator}${String(object)}`);\n }\n\n walk(input);\n return entries.sort().join(pairSeparator);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,SAAgB,iCACZ,OACA,cAAsB,KACtB,gBAAwB,KAC1B;CACE,MAAM,UAAoB,EAAE;CAE5B,SAAS,KAAK,QAAa,OAAiB,EAAE,EAAE;EAC5C,IAAI,MAAM,QAAQ,OAAO,EACrB,OAAO,SAAS,OAAO,MAAM;GACzB,KACI,OACA,CACI,GAAG,MACH,EAAE,UAAU,CACf,CACJ;IACH;OACC,IACH,WAAW,QACR,OAAO,WAAW,YAClB,OAAO,UAAU,SAAS,KAAK,OAAO,KAAK,mBAE9C,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,SAAS,QAAQ;GACxC,KACI,OAAO,MACP,CACI,GAAG,MACH,IACH,CACJ;IACH;OACC,QAAQ,KAAK,GAAG,KAAK,KAAK,IAAI,GAAG,cAAc,OAAO,OAAO,GAAG;;CAG3E,KAAK,MAAM;CACX,OAAO,QAAQ,MAAM,CAAC,KAAK,cAAc"}
1
+ {"version":3,"file":"object.js","names":[],"sources":["../src/object.ts"],"sourcesContent":["/**\n * Serializes a nested object into a deterministic, flat string format.\n *\n * This function recursively traverses the input object (including nested objects and arrays),\n * flattens it into key paths using dot notation (e.g. \"a.b.0.c\"), sorts all keys,\n * and joins each key-value pair into a string with customizable separators.\n *\n * It is designed for use cases such as signature generation, cache key construction,\n * or any context requiring consistent and predictable object serialization.\n *\n * Note: Empty objects and arrays produce an empty string, which is useful for\n * generating deterministic signature payloads.\n *\n * @param {Record<string, any>} input - The object to serialize. Can contain nested objects and arrays\n * @param {string} kvSeparator - The string used to separate each key from its value (default: '=')\n * @param {string} pairSeparator - The string used to separate each key-value pair (default: '&')\n * @returns {string} A deterministic string representation of the input object\n *\n * @example\n * ```typescript\n * import { stringifyObjectDeterministically } from '@kikiutils/shared/object';\n *\n * console.log(stringifyObjectDeterministically({ b: 2, a: { x: 1, y: [3, 4] } })); // a.x=1&a.y.0=3&a.y.1=4&b=2\n * console.log(stringifyObjectDeterministically({ foo: 'bar' }, ':', '|')); // foo:bar\n * console.log(stringifyObjectDeterministically({})); // ''\n * ```\n */\nexport function stringifyObjectDeterministically(\n input: Record<string, any>,\n kvSeparator: string = '=',\n pairSeparator: string = '&',\n) {\n const entries: string[] = [];\n\n function walk(object: any, path: string[] = []) {\n if (Array.isArray(object)) {\n object.forEach((value, i) => {\n walk(\n value,\n [\n ...path,\n i.toString(),\n ],\n );\n });\n } else if (\n object !== null\n && typeof object === 'object'\n && Object.prototype.toString.call(object) === '[object Object]'\n ) {\n Object.keys(object).sort().forEach((key) => {\n walk(\n object[key],\n [\n ...path,\n key,\n ],\n );\n });\n } else entries.push(`${path.join('.')}${kvSeparator}${String(object)}`);\n }\n\n walk(input);\n return entries.sort().join(pairSeparator);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,SAAgB,iCACZ,OACA,cAAsB,KACtB,gBAAwB,KAC1B;CACE,MAAM,UAAoB,CAAC;CAE3B,SAAS,KAAK,QAAa,OAAiB,CAAC,GAAG;EAC5C,IAAI,MAAM,QAAQ,MAAM,GACpB,OAAO,SAAS,OAAO,MAAM;GACzB,KACI,OACA,CACI,GAAG,MACH,EAAE,SAAS,CACf,CACJ;EACJ,CAAC;OACE,IACH,WAAW,QACR,OAAO,WAAW,YAClB,OAAO,UAAU,SAAS,KAAK,MAAM,MAAM,mBAE9C,OAAO,KAAK,MAAM,EAAE,KAAK,EAAE,SAAS,QAAQ;GACxC,KACI,OAAO,MACP,CACI,GAAG,MACH,GACJ,CACJ;EACJ,CAAC;OACE,QAAQ,KAAK,GAAG,KAAK,KAAK,GAAG,IAAI,cAAc,OAAO,MAAM,GAAG;CAC1E;CAEA,KAAK,KAAK;CACV,OAAO,QAAQ,KAAK,EAAE,KAAK,aAAa;AAC5C"}
@@ -1 +1 @@
1
- {"version":3,"file":"pino.d.ts","names":[],"sources":["../src/pino.ts"],"mappings":";;;;;;AAiCA;;;;;AACA;;;;;;;;;;;;;cADa,UAAA,EAA6B,MAAA,CAAnB,MAAA;AAAA,cACV,MAAA,EAAmB,MAAA,CAAb,MAAA"}
1
+ {"version":3,"file":"pino.d.ts","names":[],"sources":["../src/pino.ts"],"mappings":";;;;;;AAiCA;;;;AAAuB;AACvB;;;;AAAmB;;;;;;;;;cADN,UAAA,EAA6B,MAAA,CAAnB,MAAA;AAAA,cACV,MAAA,EAAmB,MAAA,CAAb,MAAA"}
package/dist/pino.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"pino.js","names":[],"sources":["../src/pino.ts"],"sourcesContent":["import { pino } from 'pino';\nimport { PinoPretty } from 'pino-pretty';\n\n/**\n * Configure pinoPretty to enhance the log output.\n */\nconst stream = PinoPretty({\n colorize: true, // Enable colored output for better readability\n ignore: 'hostname,pid', // Exclude 'hostname' and 'pid' fields from the logs\n translateTime: 'SYS:yyyy-mm-dd HH:MM:ss.l', // Format the timestamp in 'yyyy-mm-dd HH:MM:ss.l' format\n});\n\n/**\n * A pino logger instance with the configured stream.\n *\n * The logger's level is determined based on the `PINO_LOGGER_LEVEL` and `NODE_ENV` environment variables.\n * If `PINO_LOGGER_LEVEL` is set, it will be used; otherwise, if `NODE_ENV` is `production`,\n * the level will be set to `error`.\n *\n * To manually change the level, assign the desired level to `logger.level`.\n *\n * See available levels [here](https://getpino.io/#/docs/api?id=level-string).\n *\n * @example\n * ```typescript\n * import { logger } from '@kikiutils/shared/pino';\n *\n * logger.info('test'); // [2024-07-11 12:12:30.085] INFO: test\n *\n * // Manually change the level\n * logger.level = 'info';\n * ```\n */\nexport const pinoLogger = pino({}, stream);\nexport const logger = pinoLogger;\n// eslint-disable-next-line style/max-len\npinoLogger.level = process.env.PINO_LOGGER_LEVEL || (process.env.NODE_ENV === 'production' ? 'error' : pinoLogger.level);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAa,aAAa,KAAK,EAAE,EA3BlB,WAAW;CACtB,UAAU;CACV,QAAQ;CACR,eAAe;CAClB,CAuBkC,CAAO;AAC1C,MAAa,SAAS;AAEtB,WAAW,QAAQ,QAAQ,IAAI,sBAAsB,QAAQ,IAAI,aAAa,eAAe,UAAU,WAAW"}
1
+ {"version":3,"file":"pino.js","names":[],"sources":["../src/pino.ts"],"sourcesContent":["import { pino } from 'pino';\nimport { PinoPretty } from 'pino-pretty';\n\n/**\n * Configure pinoPretty to enhance the log output.\n */\nconst stream = PinoPretty({\n colorize: true, // Enable colored output for better readability\n ignore: 'hostname,pid', // Exclude 'hostname' and 'pid' fields from the logs\n translateTime: 'SYS:yyyy-mm-dd HH:MM:ss.l', // Format the timestamp in 'yyyy-mm-dd HH:MM:ss.l' format\n});\n\n/**\n * A pino logger instance with the configured stream.\n *\n * The logger's level is determined based on the `PINO_LOGGER_LEVEL` and `NODE_ENV` environment variables.\n * If `PINO_LOGGER_LEVEL` is set, it will be used; otherwise, if `NODE_ENV` is `production`,\n * the level will be set to `error`.\n *\n * To manually change the level, assign the desired level to `logger.level`.\n *\n * See available levels [here](https://getpino.io/#/docs/api?id=level-string).\n *\n * @example\n * ```typescript\n * import { logger } from '@kikiutils/shared/pino';\n *\n * logger.info('test'); // [2024-07-11 12:12:30.085] INFO: test\n *\n * // Manually change the level\n * logger.level = 'info';\n * ```\n */\nexport const pinoLogger = pino({}, stream);\nexport const logger = pinoLogger;\n// eslint-disable-next-line style/max-len\npinoLogger.level = process.env.PINO_LOGGER_LEVEL || (process.env.NODE_ENV === 'production' ? 'error' : pinoLogger.level);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAa,aAAa,KAAK,CAAC,GA3BjB,WAAW;CACtB,UAAU;CACV,QAAQ;CACR,eAAe;AACnB,CAuBmC,CAAM;AACzC,MAAa,SAAS;AAEtB,WAAW,QAAQ,QAAQ,IAAI,sBAAsB,QAAQ,IAAI,aAAa,eAAe,UAAU,WAAW"}
@@ -1 +1 @@
1
- {"version":3,"file":"random.d.ts","names":[],"sources":["../src/random.ts"],"mappings":";;AAoBA;;;;;;;;;;;;;;;;;;;iBAAgB,8BAAA,YAAA,CACZ,SAAA,GAAY,MAAA,aAAmB,CAAA,EAC/B,MAAA,UACA,MAAA,UACA,MAAA,UACA,MAAA,WAAc,CAAA"}
1
+ {"version":3,"file":"random.d.ts","names":[],"sources":["../src/random.ts"],"mappings":";;AAoBA;;;;;;;;;;;;;;AAKkB;;;;;iBALF,8BAAA,YAAA,CACZ,SAAA,GAAY,MAAA,aAAmB,CAAA,EAC/B,MAAA,UACA,MAAA,UACA,MAAA,UACA,MAAA,WAAc,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"random.js","names":[],"sources":["../src/random.ts"],"sourcesContent":["/**\n * Generates a value using a provided generator function, where the input length\n * is determined by two levels of nested random ranges:\n *\n * 1. First, a random number (`innerMin`) is chosen between `minMin` and `minMax`.\n * 2. Then, a final length is chosen between `Math.max(innerMin, maxMin)` and `maxMax`.\n * 3. The generator is called with the final length and its result is returned.\n *\n * This function supports any return type by using a generic type parameter.\n *\n * @template T - The return type of the generator function\n *\n * @param {(length: number) => T} generator - A function that accepts a length and returns a value of type T\n * @param {number} minMin - Lower bound of the first random range\n * @param {number} minMax - Upper bound of the first random range\n * @param {number} maxMin - Lower bound of the second random range\n * @param {number} maxMax - Upper bound of the second random range\n *\n * @returns {T} The result of the generator function using the computed final length\n */\nexport function generateWithNestedRandomLength<T = string>(\n generator: (length: number) => T,\n minMin: number,\n minMax: number,\n maxMin: number,\n maxMax: number,\n) {\n if (minMin > minMax) throw new Error(`Invalid range: minMin (${minMin}) cannot be greater than minMax (${minMax})`);\n if (maxMin > maxMax) throw new Error(`Invalid range: maxMin (${maxMin}) cannot be greater than maxMax (${maxMax})`);\n\n const random = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1)) + min;\n const innerMin = random(minMin, minMax);\n const finalLength = random(Math.max(innerMin, maxMin), maxMax);\n return generator(finalLength);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,+BACZ,WACA,QACA,QACA,QACA,QACF;CACE,IAAI,SAAS,QAAQ,MAAM,IAAI,MAAM,0BAA0B,OAAO,mCAAmC,OAAO,GAAG;CACnH,IAAI,SAAS,QAAQ,MAAM,IAAI,MAAM,0BAA0B,OAAO,mCAAmC,OAAO,GAAG;CAEnH,MAAM,UAAU,KAAa,QAAgB,KAAK,MAAM,KAAK,QAAQ,IAAI,MAAM,MAAM,GAAG,GAAG;CAC3F,MAAM,WAAW,OAAO,QAAQ,OAAO;CAEvC,OAAO,UADa,OAAO,KAAK,IAAI,UAAU,OAAO,EAAE,OAC3B,CAAC"}
1
+ {"version":3,"file":"random.js","names":[],"sources":["../src/random.ts"],"sourcesContent":["/**\n * Generates a value using a provided generator function, where the input length\n * is determined by two levels of nested random ranges:\n *\n * 1. First, a random number (`innerMin`) is chosen between `minMin` and `minMax`.\n * 2. Then, a final length is chosen between `Math.max(innerMin, maxMin)` and `maxMax`.\n * 3. The generator is called with the final length and its result is returned.\n *\n * This function supports any return type by using a generic type parameter.\n *\n * @template T - The return type of the generator function\n *\n * @param {(length: number) => T} generator - A function that accepts a length and returns a value of type T\n * @param {number} minMin - Lower bound of the first random range\n * @param {number} minMax - Upper bound of the first random range\n * @param {number} maxMin - Lower bound of the second random range\n * @param {number} maxMax - Upper bound of the second random range\n *\n * @returns {T} The result of the generator function using the computed final length\n */\nexport function generateWithNestedRandomLength<T = string>(\n generator: (length: number) => T,\n minMin: number,\n minMax: number,\n maxMin: number,\n maxMax: number,\n) {\n if (minMin > minMax) throw new Error(`Invalid range: minMin (${minMin}) cannot be greater than minMax (${minMax})`);\n if (maxMin > maxMax) throw new Error(`Invalid range: maxMin (${maxMin}) cannot be greater than maxMax (${maxMax})`);\n\n const random = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1)) + min;\n const innerMin = random(minMin, minMax);\n const finalLength = random(Math.max(innerMin, maxMin), maxMax);\n return generator(finalLength);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,+BACZ,WACA,QACA,QACA,QACA,QACF;CACE,IAAI,SAAS,QAAQ,MAAM,IAAI,MAAM,0BAA0B,OAAO,mCAAmC,OAAO,EAAE;CAClH,IAAI,SAAS,QAAQ,MAAM,IAAI,MAAM,0BAA0B,OAAO,mCAAmC,OAAO,EAAE;CAElH,MAAM,UAAU,KAAa,QAAgB,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,MAAM,EAAE,IAAI;CAC3F,MAAM,WAAW,OAAO,QAAQ,MAAM;CAEtC,OAAO,UADa,OAAO,KAAK,IAAI,UAAU,MAAM,GAAG,MAC5B,CAAC;AAChC"}
@@ -1 +1 @@
1
- {"version":3,"file":"keyed-store.js","names":[],"sources":["../../../src/storages/lru/keyed-store.ts"],"sourcesContent":["import type { LRUCache } from 'lru-cache';\n\n/**\n * Creates a keyed store wrapper around an LRU cache instance.\n *\n * @template D - The data type stored in the keyed store\n *\n * @param {LRUCache<any, any, any>} lruInstance - The underlying lru-cache instance\n *\n * @returns {(keyFn: (...args: P) => string) => Readonly<{\n * getItem, getItemTtl, hasItem, removeItem, resolveKey, setItem\n * }>} A factory that accepts a key resolver and returns a frozen keyed cache facade\n *\n * @example\n * ```typescript\n * import { createLruKeyedStore } from '@kikiutils/shared/storages/lru/keyed-store';\n * import { LRUCache } from 'lru-cache';\n *\n * const lru = new LRUCache({ max: 100 });\n * const keyedStore = createLruKeyedStore(lru)((userId: string) => `user:${userId}`);\n * keyedStore.setItem({ name: 'Alice' }, 'user-123');\n * const user = keyedStore.getItem('user-123'); // { name: 'Alice' }\n * ```\n */\nexport function createLruKeyedStore<D = unknown>(lruInstance: LRUCache<any, any, any>) {\n return <P extends any[]>(keyFn: (...args: P) => string) => Object.freeze({\n /**\n * Return a value from the cache. Will update the recency of the cache entry found.\n *\n * If the key is not found, returns `null`.\n */\n getItem(...args: P) {\n const rawValue = lruInstance.get(keyFn(...args));\n return rawValue as D ?? null;\n },\n getItemTtl: (...args: P) => lruInstance.getRemainingTTL(keyFn(...args)),\n hasItem: (...args: P) => lruInstance.has(keyFn(...args)),\n removeItem: (...args: P) => lruInstance.delete(keyFn(...args)),\n /**\n * Resolves the full cache key from the given arguments.\n */\n resolveKey: (...args: P) => keyFn(...args),\n setItem: (value: D, ...args: P) => lruInstance.set(keyFn(...args), value),\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,oBAAiC,aAAsC;CACnF,QAAyB,UAAkC,OAAO,OAAO;;;;;;EAMrE,QAAQ,GAAG,MAAS;GAEhB,OADiB,YAAY,IAAI,MAAM,GAAG,KAAK,CAChC,IAAS;;EAE5B,aAAa,GAAG,SAAY,YAAY,gBAAgB,MAAM,GAAG,KAAK,CAAC;EACvE,UAAU,GAAG,SAAY,YAAY,IAAI,MAAM,GAAG,KAAK,CAAC;EACxD,aAAa,GAAG,SAAY,YAAY,OAAO,MAAM,GAAG,KAAK,CAAC;;;;EAI9D,aAAa,GAAG,SAAY,MAAM,GAAG,KAAK;EAC1C,UAAU,OAAU,GAAG,SAAY,YAAY,IAAI,MAAM,GAAG,KAAK,EAAE,MAAM;EAC5E,CAAC"}
1
+ {"version":3,"file":"keyed-store.js","names":[],"sources":["../../../src/storages/lru/keyed-store.ts"],"sourcesContent":["import type { LRUCache } from 'lru-cache';\n\n/**\n * Creates a keyed store wrapper around an LRU cache instance.\n *\n * @template D - The data type stored in the keyed store\n *\n * @param {LRUCache<any, any, any>} lruInstance - The underlying lru-cache instance\n *\n * @returns {(keyFn: (...args: P) => string) => Readonly<{\n * getItem, getItemTtl, hasItem, removeItem, resolveKey, setItem\n * }>} A factory that accepts a key resolver and returns a frozen keyed cache facade\n *\n * @example\n * ```typescript\n * import { createLruKeyedStore } from '@kikiutils/shared/storages/lru/keyed-store';\n * import { LRUCache } from 'lru-cache';\n *\n * const lru = new LRUCache({ max: 100 });\n * const keyedStore = createLruKeyedStore(lru)((userId: string) => `user:${userId}`);\n * keyedStore.setItem({ name: 'Alice' }, 'user-123');\n * const user = keyedStore.getItem('user-123'); // { name: 'Alice' }\n * ```\n */\nexport function createLruKeyedStore<D = unknown>(lruInstance: LRUCache<any, any, any>) {\n return <P extends any[]>(keyFn: (...args: P) => string) => Object.freeze({\n /**\n * Return a value from the cache. Will update the recency of the cache entry found.\n *\n * If the key is not found, returns `null`.\n */\n getItem(...args: P) {\n const rawValue = lruInstance.get(keyFn(...args));\n return rawValue as D ?? null;\n },\n getItemTtl: (...args: P) => lruInstance.getRemainingTTL(keyFn(...args)),\n hasItem: (...args: P) => lruInstance.has(keyFn(...args)),\n removeItem: (...args: P) => lruInstance.delete(keyFn(...args)),\n /**\n * Resolves the full cache key from the given arguments.\n */\n resolveKey: (...args: P) => keyFn(...args),\n setItem: (value: D, ...args: P) => lruInstance.set(keyFn(...args), value),\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,oBAAiC,aAAsC;CACnF,QAAyB,UAAkC,OAAO,OAAO;;;;;;EAMrE,QAAQ,GAAG,MAAS;GAEhB,OADiB,YAAY,IAAI,MAAM,GAAG,IAAI,CAChC,KAAU;EAC5B;EACA,aAAa,GAAG,SAAY,YAAY,gBAAgB,MAAM,GAAG,IAAI,CAAC;EACtE,UAAU,GAAG,SAAY,YAAY,IAAI,MAAM,GAAG,IAAI,CAAC;EACvD,aAAa,GAAG,SAAY,YAAY,OAAO,MAAM,GAAG,IAAI,CAAC;;;;EAI7D,aAAa,GAAG,SAAY,MAAM,GAAG,IAAI;EACzC,UAAU,OAAU,GAAG,SAAY,YAAY,IAAI,MAAM,GAAG,IAAI,GAAG,KAAK;CAC5E,CAAC;AACL"}
@@ -1 +1 @@
1
- {"version":3,"file":"keyed-store.js","names":[],"sources":["../../../src/storages/redis/keyed-store.ts"],"sourcesContent":["import type { MaybeReadonly } from '../../types';\n\nimport type { RedisLikeStorage } from './types';\n\n/**\n * Creates a keyed store wrapper around a Redis-like storage.\n *\n * @template D - The data type stored in the keyed store\n *\n * @param {MaybeReadonly<RedisLikeStorage>} storage - The underlying Redis-like storage instance\n *\n * @returns {(keyFn: (...args: P) => string) => Readonly<{\n * getItem, getItemTtl, hasItem, removeItem, resolveKey, setItem, setItemWithTtl\n * }>} A factory that accepts a key resolver and returns a frozen Redis keyed-store facade\n *\n * @example\n * ```typescript\n * import { createRedisKeyedStore } from '@kikiutils/shared/storages/redis/keyed-store';\n * import { createRedisMsgpackStorage } from '@kikiutils/shared/storages/redis/msgpack';\n * import { createClient } from 'redis';\n *\n * const client = createClient();\n * await client.connect();\n * const storage = createRedisMsgpackStorage(client as unknown as RedisLikeAdapter);\n * const keyedStore = createRedisKeyedStore(storage)((userId: string) => `user:${userId}`);\n * await keyedStore.setItem({ name: 'Alice' }, 'user-123');\n * const user = await keyedStore.getItem('user-123'); // { name: 'Alice' }\n * ```\n */\nexport function createRedisKeyedStore<D = unknown>(storage: MaybeReadonly<RedisLikeStorage>) {\n return <P extends any[]>(keyFn: (...args: P) => string) => Object.freeze({\n getItem: (...args: P) => storage.getItem<D>(keyFn(...args)),\n getItemTtl: (...args: P) => storage.getItemTtl(keyFn(...args)),\n hasItem: (...args: P) => storage.hasItem(keyFn(...args)),\n removeItem: (...args: P) => storage.removeItem(keyFn(...args)),\n resolveKey: (...args: P) => keyFn(...args),\n setItem: (value: D, ...args: P) => storage.setItem(keyFn(...args), value),\n setItemWithTtl(ttlSeconds: number, value: D, ...args: P) {\n return storage.setItemWithTtl(keyFn(...args), ttlSeconds, value);\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,sBAAmC,SAA0C;CACzF,QAAyB,UAAkC,OAAO,OAAO;EACrE,UAAU,GAAG,SAAY,QAAQ,QAAW,MAAM,GAAG,KAAK,CAAC;EAC3D,aAAa,GAAG,SAAY,QAAQ,WAAW,MAAM,GAAG,KAAK,CAAC;EAC9D,UAAU,GAAG,SAAY,QAAQ,QAAQ,MAAM,GAAG,KAAK,CAAC;EACxD,aAAa,GAAG,SAAY,QAAQ,WAAW,MAAM,GAAG,KAAK,CAAC;EAC9D,aAAa,GAAG,SAAY,MAAM,GAAG,KAAK;EAC1C,UAAU,OAAU,GAAG,SAAY,QAAQ,QAAQ,MAAM,GAAG,KAAK,EAAE,MAAM;EACzE,eAAe,YAAoB,OAAU,GAAG,MAAS;GACrD,OAAO,QAAQ,eAAe,MAAM,GAAG,KAAK,EAAE,YAAY,MAAM;;EAEvE,CAAC"}
1
+ {"version":3,"file":"keyed-store.js","names":[],"sources":["../../../src/storages/redis/keyed-store.ts"],"sourcesContent":["import type { MaybeReadonly } from '../../types';\n\nimport type { RedisLikeStorage } from './types';\n\n/**\n * Creates a keyed store wrapper around a Redis-like storage.\n *\n * @template D - The data type stored in the keyed store\n *\n * @param {MaybeReadonly<RedisLikeStorage>} storage - The underlying Redis-like storage instance\n *\n * @returns {(keyFn: (...args: P) => string) => Readonly<{\n * getItem, getItemTtl, hasItem, removeItem, resolveKey, setItem, setItemWithTtl\n * }>} A factory that accepts a key resolver and returns a frozen Redis keyed-store facade\n *\n * @example\n * ```typescript\n * import { createRedisKeyedStore } from '@kikiutils/shared/storages/redis/keyed-store';\n * import { createRedisMsgpackStorage } from '@kikiutils/shared/storages/redis/msgpack';\n * import { createClient } from 'redis';\n *\n * const client = createClient();\n * await client.connect();\n * const storage = createRedisMsgpackStorage(client as unknown as RedisLikeAdapter);\n * const keyedStore = createRedisKeyedStore(storage)((userId: string) => `user:${userId}`);\n * await keyedStore.setItem({ name: 'Alice' }, 'user-123');\n * const user = await keyedStore.getItem('user-123'); // { name: 'Alice' }\n * ```\n */\nexport function createRedisKeyedStore<D = unknown>(storage: MaybeReadonly<RedisLikeStorage>) {\n return <P extends any[]>(keyFn: (...args: P) => string) => Object.freeze({\n getItem: (...args: P) => storage.getItem<D>(keyFn(...args)),\n getItemTtl: (...args: P) => storage.getItemTtl(keyFn(...args)),\n hasItem: (...args: P) => storage.hasItem(keyFn(...args)),\n removeItem: (...args: P) => storage.removeItem(keyFn(...args)),\n resolveKey: (...args: P) => keyFn(...args),\n setItem: (value: D, ...args: P) => storage.setItem(keyFn(...args), value),\n setItemWithTtl(ttlSeconds: number, value: D, ...args: P) {\n return storage.setItemWithTtl(keyFn(...args), ttlSeconds, value);\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,sBAAmC,SAA0C;CACzF,QAAyB,UAAkC,OAAO,OAAO;EACrE,UAAU,GAAG,SAAY,QAAQ,QAAW,MAAM,GAAG,IAAI,CAAC;EAC1D,aAAa,GAAG,SAAY,QAAQ,WAAW,MAAM,GAAG,IAAI,CAAC;EAC7D,UAAU,GAAG,SAAY,QAAQ,QAAQ,MAAM,GAAG,IAAI,CAAC;EACvD,aAAa,GAAG,SAAY,QAAQ,WAAW,MAAM,GAAG,IAAI,CAAC;EAC7D,aAAa,GAAG,SAAY,MAAM,GAAG,IAAI;EACzC,UAAU,OAAU,GAAG,SAAY,QAAQ,QAAQ,MAAM,GAAG,IAAI,GAAG,KAAK;EACxE,eAAe,YAAoB,OAAU,GAAG,MAAS;GACrD,OAAO,QAAQ,eAAe,MAAM,GAAG,IAAI,GAAG,YAAY,KAAK;EACnE;CACJ,CAAC;AACL"}
@@ -1 +1 @@
1
- {"version":3,"file":"msgpack.d.ts","names":[],"sources":["../../../src/storages/redis/msgpack.ts"],"mappings":";;;;;AAmCA;;;;;;;;;;;;;;;;;;iBAAgB,yBAAA,CAA0B,OAAA,EAAS,gBAAA,GAAmB,QAAA,CAAS,gBAAA"}
1
+ {"version":3,"file":"msgpack.d.ts","names":[],"sources":["../../../src/storages/redis/msgpack.ts"],"mappings":";;;;;AAmCA;;;;;;;;;;;;;AAA+F;;;;;iBAA/E,yBAAA,CAA0B,OAAA,EAAS,gBAAA,GAAmB,QAAA,CAAS,gBAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"msgpack.js","names":[],"sources":["../../../src/storages/redis/msgpack.ts"],"sourcesContent":["import {\n decode,\n encode,\n isNativeAccelerationEnabled,\n} from 'msgpackr';\n\nimport type {\n RedisLikeAdapter,\n RedisLikeStorage,\n} from './types';\n\nif (!isNativeAccelerationEnabled) {\n console.warn('Native acceleration not enabled for msgpackr, verify that install finished properly');\n}\n\n/**\n * Creates a Redis-like storage using msgpack serialization.\n *\n * @param {RedisLikeAdapter} adapter - The Redis-like adapter to use for raw buffer operations\n *\n * @returns {Readonly<RedisLikeStorage>} A readonly storage instance\n * with getItem, setItem, hasItem, removeItem, getItemTtl, setItemWithTtl\n *\n * @example\n * ```typescript\n * import { createRedisMsgpackStorage } from '@kikiutils/shared/storages/redis/msgpack';\n * import { createClient } from 'redis';\n *\n * const client = createClient();\n * await client.connect();\n * const storage = createRedisMsgpackStorage(client as unknown as RedisLikeAdapter);\n * await storage.setItem('key', { foo: 'bar' });\n * const value = await storage.getItem('key'); // { foo: 'bar' }\n * ```\n */\nexport function createRedisMsgpackStorage(adapter: RedisLikeAdapter): Readonly<RedisLikeStorage> {\n return Object.freeze({\n async getItem<T = unknown>(key: string) {\n const rawValue = await adapter.getBuffer(key);\n return rawValue ? decode(rawValue) as T : null;\n },\n getItemTtl: (key: string) => adapter.ttl(key),\n hasItem: (key: string) => adapter.has(key),\n removeItem: async (key: string) => await adapter.delete(key) === 1,\n setItem: async (key: string, value: any) => await adapter.setBuffer(key, encode(value)) === 'OK',\n async setItemWithTtl(key: string, ttlSeconds: number, value: any) {\n return await adapter.setBufferEx(key, ttlSeconds, encode(value)) === 'OK';\n },\n });\n}\n"],"mappings":";;AAWA,IAAI,CAAC,6BACD,QAAQ,KAAK,sFAAsF;;;;;;;;;;;;;;;;;;;;;AAuBvG,SAAgB,0BAA0B,SAAuD;CAC7F,OAAO,OAAO,OAAO;EACjB,MAAM,QAAqB,KAAa;GACpC,MAAM,WAAW,MAAM,QAAQ,UAAU,IAAI;GAC7C,OAAO,WAAW,OAAO,SAAS,GAAQ;;EAE9C,aAAa,QAAgB,QAAQ,IAAI,IAAI;EAC7C,UAAU,QAAgB,QAAQ,IAAI,IAAI;EAC1C,YAAY,OAAO,QAAgB,MAAM,QAAQ,OAAO,IAAI,KAAK;EACjE,SAAS,OAAO,KAAa,UAAe,MAAM,QAAQ,UAAU,KAAK,OAAO,MAAM,CAAC,KAAK;EAC5F,MAAM,eAAe,KAAa,YAAoB,OAAY;GAC9D,OAAO,MAAM,QAAQ,YAAY,KAAK,YAAY,OAAO,MAAM,CAAC,KAAK;;EAE5E,CAAC"}
1
+ {"version":3,"file":"msgpack.js","names":[],"sources":["../../../src/storages/redis/msgpack.ts"],"sourcesContent":["import {\n decode,\n encode,\n isNativeAccelerationEnabled,\n} from 'msgpackr';\n\nimport type {\n RedisLikeAdapter,\n RedisLikeStorage,\n} from './types';\n\nif (!isNativeAccelerationEnabled) {\n console.warn('Native acceleration not enabled for msgpackr, verify that install finished properly');\n}\n\n/**\n * Creates a Redis-like storage using msgpack serialization.\n *\n * @param {RedisLikeAdapter} adapter - The Redis-like adapter to use for raw buffer operations\n *\n * @returns {Readonly<RedisLikeStorage>} A readonly storage instance\n * with getItem, setItem, hasItem, removeItem, getItemTtl, setItemWithTtl\n *\n * @example\n * ```typescript\n * import { createRedisMsgpackStorage } from '@kikiutils/shared/storages/redis/msgpack';\n * import { createClient } from 'redis';\n *\n * const client = createClient();\n * await client.connect();\n * const storage = createRedisMsgpackStorage(client as unknown as RedisLikeAdapter);\n * await storage.setItem('key', { foo: 'bar' });\n * const value = await storage.getItem('key'); // { foo: 'bar' }\n * ```\n */\nexport function createRedisMsgpackStorage(adapter: RedisLikeAdapter): Readonly<RedisLikeStorage> {\n return Object.freeze({\n async getItem<T = unknown>(key: string) {\n const rawValue = await adapter.getBuffer(key);\n return rawValue ? decode(rawValue) as T : null;\n },\n getItemTtl: (key: string) => adapter.ttl(key),\n hasItem: (key: string) => adapter.has(key),\n removeItem: async (key: string) => await adapter.delete(key) === 1,\n setItem: async (key: string, value: any) => await adapter.setBuffer(key, encode(value)) === 'OK',\n async setItemWithTtl(key: string, ttlSeconds: number, value: any) {\n return await adapter.setBufferEx(key, ttlSeconds, encode(value)) === 'OK';\n },\n });\n}\n"],"mappings":";;AAWA,IAAI,CAAC,6BACD,QAAQ,KAAK,qFAAqF;;;;;;;;;;;;;;;;;;;;;AAuBtG,SAAgB,0BAA0B,SAAuD;CAC7F,OAAO,OAAO,OAAO;EACjB,MAAM,QAAqB,KAAa;GACpC,MAAM,WAAW,MAAM,QAAQ,UAAU,GAAG;GAC5C,OAAO,WAAW,OAAO,QAAQ,IAAS;EAC9C;EACA,aAAa,QAAgB,QAAQ,IAAI,GAAG;EAC5C,UAAU,QAAgB,QAAQ,IAAI,GAAG;EACzC,YAAY,OAAO,QAAgB,MAAM,QAAQ,OAAO,GAAG,MAAM;EACjE,SAAS,OAAO,KAAa,UAAe,MAAM,QAAQ,UAAU,KAAK,OAAO,KAAK,CAAC,MAAM;EAC5F,MAAM,eAAe,KAAa,YAAoB,OAAY;GAC9D,OAAO,MAAM,QAAQ,YAAY,KAAK,YAAY,OAAO,KAAK,CAAC,MAAM;EACzE;CACJ,CAAC;AACL"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/storages/redis/types.ts"],"mappings":";;;;;AAKA;UAAiB,gBAAA;;;;EAIb,MAAA,GAAS,GAAA,aAAgB,OAAA;EAKG;;;EAA5B,SAAA,GAAY,GAAA,aAAgB,OAAA,CAAQ,QAAA,CAAS,UAAA;EAeS;;;EAVtD,GAAA,GAAM,GAAA,aAAgB,OAAA;EAeO;;;EAV7B,SAAA,GAAY,GAAA,UAAa,KAAA,EAAO,UAAA,KAAe,OAAA;EAV/C;;;EAeA,WAAA,GAAc,GAAA,UAAa,UAAA,UAAoB,KAAA,EAAO,UAAA,KAAe,OAAA;EAfxB;;;EAoB7C,GAAA,GAAM,GAAA,aAAgB,OAAA;AAAA;;;;UAMT,gBAAA;EAXb;;;EAeA,OAAA,gBAAuB,GAAA,aAAgB,OAAA,CAAQ,QAAA,CAAS,CAAA;EAfT;;;EAoB/C,UAAA,GAAa,GAAA,aAAgB,OAAA;EAfP;;;EAoBtB,OAAA,GAAU,GAAA,aAAgB,OAAA;EAdG;;;EAmB7B,UAAA,GAAa,GAAA,aAAgB,OAAA;EAfU;;;EAoBvC,OAAA,GAAU,GAAA,UAAa,KAAA,UAAe,OAAA;EAAA;;;EAKtC,cAAA,GAAiB,GAAA,UAAa,UAAA,UAAoB,KAAA,UAAe,OAAA;AAAA"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/storages/redis/types.ts"],"mappings":";;;;;AAKA;UAAiB,gBAAA;;;;EAIb,MAAA,GAAS,GAAA,aAAgB,OAAA;EAKG;;;EAA5B,SAAA,GAAY,GAAA,aAAgB,OAAA,CAAQ,QAAA,CAAS,UAAA;EAeS;;;EAVtD,GAAA,GAAM,GAAA,aAAgB,OAAA;EAeO;;;EAV7B,SAAA,GAAY,GAAA,UAAa,KAAA,EAAO,UAAA,KAAe,OAAA;EAV/C;;;EAeA,WAAA,GAAc,GAAA,UAAa,UAAA,UAAoB,KAAA,EAAO,UAAA,KAAe,OAAA;EAfxB;;;EAoB7C,GAAA,GAAM,GAAA,aAAgB,OAAA;AAAA;;;;UAMT,gBAAA;EAXb;;;EAeA,OAAA,gBAAuB,GAAA,aAAgB,OAAA,CAAQ,QAAA,CAAS,CAAA;EAfT;;;EAoB/C,UAAA,GAAa,GAAA,aAAgB,OAAA;EAfP;;AAAO;EAoB7B,OAAA,GAAU,GAAA,aAAgB,OAAA;EAdG;;;EAmB7B,UAAA,GAAa,GAAA,aAAgB,OAAA;EAfU;;;EAoBvC,OAAA,GAAU,GAAA,UAAa,KAAA,UAAe,OAAA;EAAA;;;EAKtC,cAAA,GAAiB,GAAA,UAAa,UAAA,UAAoB,KAAA,UAAe,OAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"string.d.ts","names":[],"sources":["../src/string.ts"],"mappings":";;AAGA;;KAAY,gBAAA;;;AA4CZ;;;;;;;;;;;;;;;;;;;;iBAAgB,YAAA,CAAa,MAAA,UAAgB,IAAA,GAAM,gBAAA"}
1
+ {"version":3,"file":"string.d.ts","names":[],"sources":["../src/string.ts"],"mappings":";;AAGA;;KAAY,gBAAA;;AAAgB;AA4C5B;;;;;;;;AAAkF;;;;;;;;;;;;iBAAlE,YAAA,CAAa,MAAA,UAAgB,IAAA,GAAM,gBAA+B"}
@@ -1 +1 @@
1
- {"version":3,"file":"string.js","names":[],"sources":["../src/string.ts"],"sourcesContent":["/**\n * Character-set presets supported by `randomString`.\n */\nexport type RandomStringMode =\n | 'alphabetic'\n | 'alphanumeric'\n | 'lowercase'\n | 'lowercase-numeric'\n | 'numeric'\n | 'uppercase'\n | 'uppercase-numeric';\n\nconst DIGITS = '0123456789';\nconst LOWERCASE = 'abcdefghijklmnopqrstuvwxyz';\nconst UPPERCASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';\nconst CHARSETS: Record<RandomStringMode, string> = {\n 'alphabetic': LOWERCASE + UPPERCASE,\n 'alphanumeric': DIGITS + LOWERCASE + UPPERCASE,\n 'lowercase': LOWERCASE,\n 'lowercase-numeric': DIGITS + LOWERCASE,\n 'numeric': DIGITS,\n 'uppercase': UPPERCASE,\n 'uppercase-numeric': DIGITS + UPPERCASE,\n};\n\n/**\n * Generates a random string of a given length using a predefined character set.\n *\n * Uses `Math.random`, so this helper is suitable for display tokens, placeholders,\n * and test data, but not for passwords, API keys, or other cryptographic secrets.\n *\n * @param {number} length - The positive integer length of the string to generate\n * @param {RandomStringMode} [mode] - The character set to use (default: `'alphabetic'`)\n *\n * @returns {string} The generated random string\n *\n * @throws {Error} If the length is not a positive integer or the mode is unsupported\n *\n * @example\n * ```typescript\n * import { randomString } from '@kikiutils/shared/string';\n *\n * randomString(8); // e.g. 'aZbXwTyQ'\n * randomString(6, 'numeric'); // e.g. '402398'\n * randomString(10, 'alphanumeric'); // e.g. 'a9Z4pQ8xY2'\n * ```\n */\nexport function randomString(length: number, mode: RandomStringMode = 'alphabetic') {\n if (!Number.isInteger(length) || length <= 0) {\n throw new Error(`Invalid length: ${length}. Must be a positive integer`);\n }\n\n const charset = CHARSETS[mode];\n if (!charset) throw new Error(`Unsupported mode: ${mode}`);\n return Array.from({ length }, () => charset[Math.floor(Math.random() * charset.length)]).join('');\n}\n"],"mappings":";AAYA,MAAM,SAAS;AACf,MAAM,YAAY;AAClB,MAAM,YAAY;AAClB,MAAM,WAA6C;CAC/C,cAAc,YAAY;CAC1B,gBAAgB,SAAS,YAAY;CACrC,aAAa;CACb,qBAAqB,SAAS;CAC9B,WAAW;CACX,aAAa;CACb,qBAAqB,SAAS;CACjC;;;;;;;;;;;;;;;;;;;;;;;AAwBD,SAAgB,aAAa,QAAgB,OAAyB,cAAc;CAChF,IAAI,CAAC,OAAO,UAAU,OAAO,IAAI,UAAU,GACvC,MAAM,IAAI,MAAM,mBAAmB,OAAO,8BAA8B;CAG5E,MAAM,UAAU,SAAS;CACzB,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,qBAAqB,OAAO;CAC1D,OAAO,MAAM,KAAK,EAAE,QAAQ,QAAQ,QAAQ,KAAK,MAAM,KAAK,QAAQ,GAAG,QAAQ,OAAO,EAAE,CAAC,KAAK,GAAG"}
1
+ {"version":3,"file":"string.js","names":[],"sources":["../src/string.ts"],"sourcesContent":["/**\n * Character-set presets supported by `randomString`.\n */\nexport type RandomStringMode =\n | 'alphabetic'\n | 'alphanumeric'\n | 'lowercase'\n | 'lowercase-numeric'\n | 'numeric'\n | 'uppercase'\n | 'uppercase-numeric';\n\nconst DIGITS = '0123456789';\nconst LOWERCASE = 'abcdefghijklmnopqrstuvwxyz';\nconst UPPERCASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';\nconst CHARSETS: Record<RandomStringMode, string> = {\n 'alphabetic': LOWERCASE + UPPERCASE,\n 'alphanumeric': DIGITS + LOWERCASE + UPPERCASE,\n 'lowercase': LOWERCASE,\n 'lowercase-numeric': DIGITS + LOWERCASE,\n 'numeric': DIGITS,\n 'uppercase': UPPERCASE,\n 'uppercase-numeric': DIGITS + UPPERCASE,\n};\n\n/**\n * Generates a random string of a given length using a predefined character set.\n *\n * Uses `Math.random`, so this helper is suitable for display tokens, placeholders,\n * and test data, but not for passwords, API keys, or other cryptographic secrets.\n *\n * @param {number} length - The positive integer length of the string to generate\n * @param {RandomStringMode} [mode] - The character set to use (default: `'alphabetic'`)\n *\n * @returns {string} The generated random string\n *\n * @throws {Error} If the length is not a positive integer or the mode is unsupported\n *\n * @example\n * ```typescript\n * import { randomString } from '@kikiutils/shared/string';\n *\n * randomString(8); // e.g. 'aZbXwTyQ'\n * randomString(6, 'numeric'); // e.g. '402398'\n * randomString(10, 'alphanumeric'); // e.g. 'a9Z4pQ8xY2'\n * ```\n */\nexport function randomString(length: number, mode: RandomStringMode = 'alphabetic') {\n if (!Number.isInteger(length) || length <= 0) {\n throw new Error(`Invalid length: ${length}. Must be a positive integer`);\n }\n\n const charset = CHARSETS[mode];\n if (!charset) throw new Error(`Unsupported mode: ${mode}`);\n return Array.from({ length }, () => charset[Math.floor(Math.random() * charset.length)]).join('');\n}\n"],"mappings":";AAYA,MAAM,SAAS;AACf,MAAM,YAAY;AAClB,MAAM,YAAY;AAClB,MAAM,WAA6C;CAC/C,cAAc,YAAY;CAC1B,gBAAgB,SAAS,YAAY;CACrC,aAAa;CACb,qBAAqB,SAAS;CAC9B,WAAW;CACX,aAAa;CACb,qBAAqB,SAAS;AAClC;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,aAAa,QAAgB,OAAyB,cAAc;CAChF,IAAI,CAAC,OAAO,UAAU,MAAM,KAAK,UAAU,GACvC,MAAM,IAAI,MAAM,mBAAmB,OAAO,6BAA6B;CAG3E,MAAM,UAAU,SAAS;CACzB,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,qBAAqB,MAAM;CACzD,OAAO,MAAM,KAAK,EAAE,OAAO,SAAS,QAAQ,KAAK,MAAM,KAAK,OAAO,IAAI,QAAQ,MAAM,EAAE,EAAE,KAAK,EAAE;AACpG"}
@@ -1 +1 @@
1
- {"version":3,"file":"time.d.ts","names":[],"sources":["../src/time.ts"],"mappings":";;AAiBA;;;;;;;;;;;;;;;;iBAAgB,cAAA,CAAe,EAAA,UAAY,MAAA,GAAS,WAAA,GAAW,OAAA"}
1
+ {"version":3,"file":"time.d.ts","names":[],"sources":["../src/time.ts"],"mappings":";;AAiBA;;;;;;;;;AAA+D;;;;;;;iBAA/C,cAAA,CAAe,EAAA,UAAY,MAAA,GAAS,WAAA,GAAW,OAAA"}
package/dist/time.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"time.js","names":[],"sources":["../src/time.ts"],"sourcesContent":["/**\n * Creates a delay that can be aborted via AbortSignal.\n *\n * @param {number} ms - Delay duration in milliseconds\n * @param {AbortSignal} [signal] - Optional AbortSignal to cancel the delay\n *\n * @returns {Promise<undefined>} A promise that resolves after ms or resolves immediately on abort\n *\n * @example\n * ```typescript\n * import { abortableDelay } from '@kikiutils/shared/time';\n *\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 1000);\n * await abortableDelay(5000, controller.signal); // resolves after ~1s when aborted\n * ```\n */\nexport function abortableDelay(ms: number, signal?: AbortSignal) {\n return new Promise((resolve) => {\n const timeout = setTimeout(resolve, ms);\n if (signal) {\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timeout);\n resolve(undefined);\n },\n );\n }\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiBA,SAAgB,eAAe,IAAY,QAAsB;CAC7D,OAAO,IAAI,SAAS,YAAY;EAC5B,MAAM,UAAU,WAAW,SAAS,GAAG;EACvC,IAAI,QACA,OAAO,iBACH,eACM;GACF,aAAa,QAAQ;GACrB,QAAQ,KAAA,EAAU;IAEzB;GAEP"}
1
+ {"version":3,"file":"time.js","names":[],"sources":["../src/time.ts"],"sourcesContent":["/**\n * Creates a delay that can be aborted via AbortSignal.\n *\n * @param {number} ms - Delay duration in milliseconds\n * @param {AbortSignal} [signal] - Optional AbortSignal to cancel the delay\n *\n * @returns {Promise<undefined>} A promise that resolves after ms or resolves immediately on abort\n *\n * @example\n * ```typescript\n * import { abortableDelay } from '@kikiutils/shared/time';\n *\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 1000);\n * await abortableDelay(5000, controller.signal); // resolves after ~1s when aborted\n * ```\n */\nexport function abortableDelay(ms: number, signal?: AbortSignal) {\n return new Promise((resolve) => {\n const timeout = setTimeout(resolve, ms);\n if (signal) {\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timeout);\n resolve(undefined);\n },\n );\n }\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiBA,SAAgB,eAAe,IAAY,QAAsB;CAC7D,OAAO,IAAI,SAAS,YAAY;EAC5B,MAAM,UAAU,WAAW,SAAS,EAAE;EACtC,IAAI,QACA,OAAO,iBACH,eACM;GACF,aAAa,OAAO;GACpB,QAAQ,KAAA,CAAS;EACrB,CACJ;CAER,CAAC;AACL"}
@@ -1 +1 @@
1
- {"version":3,"file":"filtered-key-path.d.ts","names":[],"sources":["../../src/types/filtered-key-path.ts"],"mappings":";;;;;AAAqC;;;;;;KAWhC,eAAA,oCAAmD,CAAA,SAAU,CAAA,MAAO,CAAA,KAAM,WAAA,CAAY,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA,KAC5F,WAAA,kDAIO,CAAA,MACR,CAAA,SAAU,YAAA,GAAe,EAAA,MAAQ,CAAA,IAAK,eAAA,CAAgB,CAAA,EAAG,CAAA;;;;;;;;;KAWjD,eAAA,iBAAgC,CAAA,SAAU,aAAA,aAA0B,OAAA,CAAQ,CAAA,yBAA0B,QAAA,CAAS,CAAA,MAAO,QAAA,CAAS,OAAA,CAAQ,CAAA,WAAY,CAAA,CAAE,CAAA,GAAI,CAAA,IAAK,QAAA,CAAS,CAAA,KAAM,QAAA,SAAiB,CAAA,EAAG,CAAA,mBAAoB,CAAA,KAAM,QAAA,CAAS,OAAA,CAAQ,CAAA,WAAY,CAAA,CAAE,CAAA,GAAI,CAAA,UAAW,CAAA;AAAA,KAChR,OAAA,WAAkB,aAAA,wBAAqC,CAAA;AAAA,KACvD,QAAA,qCAA6C,CAAA,oBAAqB,WAAA,CAAY,CAAA,EAAG,CAAA,IAAK,eAAA,CAAgB,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA,KAC5G,YAAA,YAED,IAAA,aAEA,IAAA,GACA,IAAA,mBAGA,QAAA,GACA,MAAA;AAAA,KAKC,QAAA,WAAmB,aAAA,SAAsB,OAAA,OAAc,CAAA"}
1
+ {"version":3,"file":"filtered-key-path.d.ts","names":[],"sources":["../../src/types/filtered-key-path.ts"],"mappings":";;;;;AAAqC;;;;;;KAWhC,eAAA,oCAAmD,CAAA,SAAU,CAAA,MAAO,CAAA,KAAM,WAAA,CAAY,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA,KAC5F,WAAA,kDAIO,CAAA,MACR,CAAA,SAAU,YAAA,GAAe,EAAA,MAAQ,CAAA,IAAK,eAAA,CAAgB,CAAA,EAAG,CAAA;;;;;;;;;KAWjD,eAAA,iBAAgC,CAAA,SAAU,aAAA,aAA0B,OAAA,CAAQ,CAAA,yBAA0B,QAAA,CAAS,CAAA,MAAO,QAAA,CAAS,OAAA,CAAQ,CAAA,WAAY,CAAA,CAAE,CAAA,GAAI,CAAA,IAAK,QAAA,CAAS,CAAA,KAAM,QAAA,SAAiB,CAAA,EAAG,CAAA,mBAAoB,CAAA,KAAM,QAAA,CAAS,OAAA,CAAQ,CAAA,WAAY,CAAA,CAAE,CAAA,GAAI,CAAA,UAAW,CAAA;AAAA,KAChR,OAAA,WAAkB,aAAA,wBAAqC,CAAC;AAAA,KACxD,QAAA,qCAA6C,CAAA,oBAAqB,WAAA,CAAY,CAAA,EAAG,CAAA,IAAK,eAAA,CAAgB,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA,KAC5G,YAAA,YAED,IAAA,aAEA,IAAA,GACA,IAAA,mBAGA,QAAA,GACA,MAAA;AAAA,KAKC,QAAA,WAAmB,aAAA,SAAsB,OAAA,OAAc,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/types/index.ts"],"mappings":";;;;;;AAWA;KAAY,SAAA,GAAY,MAAA;;;;KAKZ,WAAA,GAAc,WAAA,GAAc,IAAA,GAAO,MAAA,GAAS,IAAA,GAAO,MAAA,GAAW,MAAA,GAAW,UAAA;;;;KAKzE,UAAA;;;;KAKA,YAAA,MAAkB,OAAA,CAAQ,CAAA,IAAK,CAAA;;;;KAK/B,aAAA,MAAmB,QAAA,CAAS,CAAA,IAAK,CAAA;;;;KAKjC,QAAA,aAAqB,CAAA;;;;KAKrB,SAAA;AApBZ;;;AAAA,KAyBY,aAAA,2BAAwC,OAAA,CAAQ,MAAA,CAAO,CAAA,EAAG,CAAA;;AApBtE;;KAyBY,qBAAA,2BAAgD,QAAA,CAAS,aAAA,CAAc,CAAA,EAAG,CAAA;;;;KAK1E,cAAA,2BAAyC,QAAA,CAAS,MAAA,CAAO,CAAA,EAAG,CAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/types/index.ts"],"mappings":";;;;;;AAWA;KAAY,SAAA,GAAY,MAAM;;;AAAA;KAKlB,WAAA,GAAc,WAAA,GAAc,IAAA,GAAO,MAAA,GAAS,IAAA,GAAO,MAAA,GAAW,MAAA,GAAW,UAAA;;;;KAKzE,UAAA;;;;KAKA,YAAA,MAAkB,OAAA,CAAQ,CAAA,IAAK,CAAA;;;;KAK/B,aAAA,MAAmB,QAAA,CAAS,CAAA,IAAK,CAAA;;;;KAKjC,QAAA,aAAqB,CAAC;;;;KAKtB,SAAA;AApBZ;;;AAAA,KAyBY,aAAA,2BAAwC,OAAA,CAAQ,MAAA,CAAO,CAAA,EAAG,CAAA;AAzBhD;AAKtB;;AALsB,KA8BV,qBAAA,2BAAgD,QAAA,CAAS,aAAA,CAAc,CAAA,EAAG,CAAA;;;;KAK1E,cAAA,2BAAyC,QAAA,CAAS,MAAA,CAAO,CAAA,EAAG,CAAA"}
package/dist/url.d.ts CHANGED
@@ -6,13 +6,37 @@
6
6
  *
7
7
  * @param {string} url - The target URL to modify
8
8
  * @param {string} redirectPath - The path to use as the redirect destination
9
- * (must be an absolute path starting with '/')
9
+ * (must be a safe same-origin application path starting with `/`)
10
10
  *
11
11
  * @returns {string} A new URL string with the `redirect` query parameter
12
12
  *
13
- * @throws {Error} If redirectPath is not a valid relative path (must start with '/')
13
+ * @throws {Error} If redirectPath is not a safe same-origin application path
14
14
  */
15
15
  declare function appendRedirectParamToUrl(url: string, redirectPath: string): string;
16
+ /**
17
+ * Returns whether a value is a safe same-origin redirect path.
18
+ *
19
+ * Safe redirect paths are absolute application paths such as `/dashboard`.
20
+ * Protocol-relative URLs (`//example.com`), absolute URLs, backslash paths,
21
+ * and non-string values are rejected.
22
+ *
23
+ * @param {unknown} value - The value to check
24
+ *
25
+ * @returns {boolean} Whether the value is safe to use as an application redirect path
26
+ */
27
+ declare function isSafeRedirectPath(value: unknown): value is string;
28
+ /**
29
+ * Normalizes a redirect value into a safe same-origin application path.
30
+ *
31
+ * If an array is provided, the first value is checked. Unsafe values fall back
32
+ * to the provided fallback path.
33
+ *
34
+ * @param {unknown} value - The redirect value to normalize
35
+ * @param {string} fallback - The safe fallback path
36
+ *
37
+ * @returns {string} A safe redirect path
38
+ */
39
+ declare function normalizeRedirectPath(value: unknown, fallback?: string): string;
16
40
  //#endregion
17
- export { appendRedirectParamToUrl };
41
+ export { appendRedirectParamToUrl, isSafeRedirectPath, normalizeRedirectPath };
18
42
  //# sourceMappingURL=url.d.ts.map
package/dist/url.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"url.d.ts","names":[],"sources":["../src/url.ts"],"mappings":";;AAaA;;;;;;;;;;;;iBAAgB,wBAAA,CAAyB,GAAA,UAAa,YAAA"}
1
+ {"version":3,"file":"url.d.ts","names":[],"sources":["../src/url.ts"],"mappings":";;AAaA;;;;AAA0E;AAuB1E;;;;AAAyD;AAmBzD;;iBA1CgB,wBAAA,CAAyB,GAAA,UAAa,YAAoB;;AA0CN;;;;;;;;;;iBAnBpD,kBAAA,CAAmB,KAAA,YAAiB,KAAK;;;;;;;;;;;;iBAmBzC,qBAAA,CAAsB,KAAA,WAAgB,QAAc"}
package/dist/url.js CHANGED
@@ -6,14 +6,14 @@
6
6
  *
7
7
  * @param {string} url - The target URL to modify
8
8
  * @param {string} redirectPath - The path to use as the redirect destination
9
- * (must be an absolute path starting with '/')
9
+ * (must be a safe same-origin application path starting with `/`)
10
10
  *
11
11
  * @returns {string} A new URL string with the `redirect` query parameter
12
12
  *
13
- * @throws {Error} If redirectPath is not a valid relative path (must start with '/')
13
+ * @throws {Error} If redirectPath is not a safe same-origin application path
14
14
  */
15
15
  function appendRedirectParamToUrl(url, redirectPath) {
16
- if (!redirectPath.startsWith("/")) throw new Error(`Invalid redirect path: "${redirectPath}". Redirect paths must be absolute paths starting with '/'.`);
16
+ if (!isSafeRedirectPath(redirectPath)) throw new Error(`Invalid redirect path: "${redirectPath}". Redirect paths must be safe same-origin paths starting with '/'.`);
17
17
  const [baseAndHash, rawQuery = ""] = url.split("?");
18
18
  const [base, hash] = (baseAndHash || "").split("#");
19
19
  const searchParams = new URLSearchParams(rawQuery);
@@ -21,7 +21,40 @@ function appendRedirectParamToUrl(url, redirectPath) {
21
21
  const queryString = searchParams.toString();
22
22
  return hash ? `${base}?${queryString}#${hash}` : `${base}?${queryString}`;
23
23
  }
24
+ /**
25
+ * Returns whether a value is a safe same-origin redirect path.
26
+ *
27
+ * Safe redirect paths are absolute application paths such as `/dashboard`.
28
+ * Protocol-relative URLs (`//example.com`), absolute URLs, backslash paths,
29
+ * and non-string values are rejected.
30
+ *
31
+ * @param {unknown} value - The value to check
32
+ *
33
+ * @returns {boolean} Whether the value is safe to use as an application redirect path
34
+ */
35
+ function isSafeRedirectPath(value) {
36
+ if (typeof value !== "string") return false;
37
+ if (!value.startsWith("/")) return false;
38
+ if (value.startsWith("//")) return false;
39
+ if (value.includes("\\")) return false;
40
+ return true;
41
+ }
42
+ /**
43
+ * Normalizes a redirect value into a safe same-origin application path.
44
+ *
45
+ * If an array is provided, the first value is checked. Unsafe values fall back
46
+ * to the provided fallback path.
47
+ *
48
+ * @param {unknown} value - The redirect value to normalize
49
+ * @param {string} fallback - The safe fallback path
50
+ *
51
+ * @returns {string} A safe redirect path
52
+ */
53
+ function normalizeRedirectPath(value, fallback = "/") {
54
+ const redirectPath = Array.isArray(value) ? value[0] : value;
55
+ return isSafeRedirectPath(redirectPath) ? redirectPath : fallback;
56
+ }
24
57
  //#endregion
25
- export { appendRedirectParamToUrl };
58
+ export { appendRedirectParamToUrl, isSafeRedirectPath, normalizeRedirectPath };
26
59
 
27
60
  //# sourceMappingURL=url.js.map
package/dist/url.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"url.js","names":[],"sources":["../src/url.ts"],"sourcesContent":["/**\n * Appends or updates the `redirect` query parameter on a given URL.\n *\n * Typically used to preserve the user's current path for post-login navigation.\n *\n * @param {string} url - The target URL to modify\n * @param {string} redirectPath - The path to use as the redirect destination\n * (must be an absolute path starting with '/')\n *\n * @returns {string} A new URL string with the `redirect` query parameter\n *\n * @throws {Error} If redirectPath is not a valid relative path (must start with '/')\n */\nexport function appendRedirectParamToUrl(url: string, redirectPath: string) {\n if (!redirectPath.startsWith('/')) {\n throw new Error(\n `Invalid redirect path: \"${redirectPath}\". Redirect paths must be absolute paths starting with '/'.`,\n );\n }\n\n const [baseAndHash, rawQuery = ''] = url.split('?');\n const [base, hash] = (baseAndHash || '').split('#');\n const searchParams = new URLSearchParams(rawQuery);\n searchParams.set('redirect', redirectPath);\n const queryString = searchParams.toString();\n return hash ? `${base}?${queryString}#${hash}` : `${base}?${queryString}`;\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,SAAgB,yBAAyB,KAAa,cAAsB;CACxE,IAAI,CAAC,aAAa,WAAW,IAAI,EAC7B,MAAM,IAAI,MACN,2BAA2B,aAAa,6DAC3C;CAGL,MAAM,CAAC,aAAa,WAAW,MAAM,IAAI,MAAM,IAAI;CACnD,MAAM,CAAC,MAAM,SAAS,eAAe,IAAI,MAAM,IAAI;CACnD,MAAM,eAAe,IAAI,gBAAgB,SAAS;CAClD,aAAa,IAAI,YAAY,aAAa;CAC1C,MAAM,cAAc,aAAa,UAAU;CAC3C,OAAO,OAAO,GAAG,KAAK,GAAG,YAAY,GAAG,SAAS,GAAG,KAAK,GAAG"}
1
+ {"version":3,"file":"url.js","names":[],"sources":["../src/url.ts"],"sourcesContent":["/**\n * Appends or updates the `redirect` query parameter on a given URL.\n *\n * Typically used to preserve the user's current path for post-login navigation.\n *\n * @param {string} url - The target URL to modify\n * @param {string} redirectPath - The path to use as the redirect destination\n * (must be a safe same-origin application path starting with `/`)\n *\n * @returns {string} A new URL string with the `redirect` query parameter\n *\n * @throws {Error} If redirectPath is not a safe same-origin application path\n */\nexport function appendRedirectParamToUrl(url: string, redirectPath: string) {\n // eslint-disable-next-line style/max-len\n if (!isSafeRedirectPath(redirectPath)) throw new Error(`Invalid redirect path: \"${redirectPath}\". Redirect paths must be safe same-origin paths starting with '/'.`);\n\n const [baseAndHash, rawQuery = ''] = url.split('?');\n const [base, hash] = (baseAndHash || '').split('#');\n const searchParams = new URLSearchParams(rawQuery);\n searchParams.set('redirect', redirectPath);\n const queryString = searchParams.toString();\n return hash ? `${base}?${queryString}#${hash}` : `${base}?${queryString}`;\n}\n\n/**\n * Returns whether a value is a safe same-origin redirect path.\n *\n * Safe redirect paths are absolute application paths such as `/dashboard`.\n * Protocol-relative URLs (`//example.com`), absolute URLs, backslash paths,\n * and non-string values are rejected.\n *\n * @param {unknown} value - The value to check\n *\n * @returns {boolean} Whether the value is safe to use as an application redirect path\n */\nexport function isSafeRedirectPath(value: unknown): value is string {\n if (typeof value !== 'string') return false;\n if (!value.startsWith('/')) return false;\n if (value.startsWith('//')) return false;\n if (value.includes('\\\\')) return false;\n return true;\n}\n\n/**\n * Normalizes a redirect value into a safe same-origin application path.\n *\n * If an array is provided, the first value is checked. Unsafe values fall back\n * to the provided fallback path.\n *\n * @param {unknown} value - The redirect value to normalize\n * @param {string} fallback - The safe fallback path\n *\n * @returns {string} A safe redirect path\n */\nexport function normalizeRedirectPath(value: unknown, fallback = '/') {\n const redirectPath = Array.isArray(value) ? value[0] : value;\n return isSafeRedirectPath(redirectPath) ? redirectPath : fallback;\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,SAAgB,yBAAyB,KAAa,cAAsB;CAExE,IAAI,CAAC,mBAAmB,YAAY,GAAG,MAAM,IAAI,MAAM,2BAA2B,aAAa,oEAAoE;CAEnK,MAAM,CAAC,aAAa,WAAW,MAAM,IAAI,MAAM,GAAG;CAClD,MAAM,CAAC,MAAM,SAAS,eAAe,IAAI,MAAM,GAAG;CAClD,MAAM,eAAe,IAAI,gBAAgB,QAAQ;CACjD,aAAa,IAAI,YAAY,YAAY;CACzC,MAAM,cAAc,aAAa,SAAS;CAC1C,OAAO,OAAO,GAAG,KAAK,GAAG,YAAY,GAAG,SAAS,GAAG,KAAK,GAAG;AAChE;;;;;;;;;;;;AAaA,SAAgB,mBAAmB,OAAiC;CAChE,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,CAAC,MAAM,WAAW,GAAG,GAAG,OAAO;CACnC,IAAI,MAAM,WAAW,IAAI,GAAG,OAAO;CACnC,IAAI,MAAM,SAAS,IAAI,GAAG,OAAO;CACjC,OAAO;AACX;;;;;;;;;;;;AAaA,SAAgB,sBAAsB,OAAgB,WAAW,KAAK;CAClE,MAAM,eAAe,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK;CACvD,OAAO,mBAAmB,YAAY,IAAI,eAAe;AAC7D"}
package/dist/vue.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vue.d.ts","names":[],"sources":["../src/vue.ts"],"mappings":";;;;;;AAiBA;;;;;iBAAgB,wCAAA,CAAyC,GAAA;;;;;;iBASzC,gBAAA,CAAiB,WAAA,EAAa,GAAA,CAAI,QAAA,CAAS,UAAA,QAAkB,WAAA;;;;;;iBAU7D,eAAA,CAAgB,UAAA,EAAY,GAAA,CAAI,QAAA,CAAS,UAAA,QAAkB,UAAA;;;;AAA3E;;;;;;;;;;;iBAmBgB,iBAAA,WAA4B,OAAA,GAAU,WAAA,CAAA,CAAa,YAAA,EAAc,GAAA,CAAI,QAAA,CAAS,CAAA"}
1
+ {"version":3,"file":"vue.d.ts","names":[],"sources":["../src/vue.ts"],"mappings":";;;;;;AAiBA;;;;AAAoE;iBAApD,wCAAA,CAAyC,GAAW;;;;;;iBASpD,gBAAA,CAAiB,WAAA,EAAa,GAAA,CAAI,QAAA,CAAS,UAAA,QAAkB,WAAA;;;;;;iBAU7D,eAAA,CAAgB,UAAA,EAAY,GAAA,CAAI,QAAA,CAAS,UAAA,QAAkB,UAAA;;;AAVgB;AAU3F;;;;;;;;;;;iBAmBgB,iBAAA,WAA4B,OAAA,GAAU,WAAA,CAAA,CAAa,YAAA,EAAc,GAAA,CAAI,QAAA,CAAS,CAAA"}
package/dist/vue.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vue.js","names":[],"sources":["../src/vue.ts"],"sourcesContent":["import { onActivated } from 'vue';\nimport type { Ref } from 'vue';\nimport {\n onBeforeRouteLeave,\n useRoute,\n} from 'vue-router';\n\nimport type { Nullable } from './types';\nimport { appendRedirectParamToUrl } from './url';\n\n/**\n * Appends the current Vue Router route's fullPath as the `redirect` query parameter to the given URL.\n *\n * @param {string} url - The base URL to modify\n *\n * @returns {string} A new URL with the current route fullPath as the `redirect` parameter\n */\nexport function appendRedirectParamFromCurrentRouteToUrl(url: string) {\n return appendRedirectParamToUrl(url, useRoute().fullPath);\n}\n\n/**\n * Clears an interval referenced by a Vue ref and sets it to null.\n *\n * @param {Ref<Nullable<ReturnType<typeof setInterval>>>} intervalRef - A Vue ref holding a NodeJS.Timeout or null\n */\nexport function clearIntervalRef(intervalRef: Ref<Nullable<ReturnType<typeof setInterval>>>) {\n if (intervalRef.value) clearInterval(intervalRef.value);\n intervalRef.value = null;\n}\n\n/**\n * Clears a timeout referenced by a Vue ref and sets it to null.\n *\n * @param {Ref<Nullable<ReturnType<typeof setTimeout>>>} timeoutRef - A Vue ref holding a NodeJS.Timeout or null\n */\nexport function clearTimeoutRef(timeoutRef: Ref<Nullable<ReturnType<typeof setTimeout>>>) {\n if (timeoutRef.value) clearTimeout(timeoutRef.value);\n timeoutRef.value = null;\n}\n\n/**\n * A Vue composition function that remembers and restores scroll position\n * of a scrollable container across route changes and keep-alive activation.\n *\n * Designed for use with `<KeepAlive>` components. Scroll state is saved on\n * route leave and restored when the component is activated again.\n *\n * Note: Without `<KeepAlive>`, the component state is destroyed on unmount,\n * so scroll position will not be preserved.\n *\n * @template T - The type of the scrollable element (defaults to HTMLElement)\n *\n * @param {Ref<Nullable<T>>} containerRef - A ref to the scrollable HTML element\n */\nexport function usePreserveScroll<T extends Element = HTMLElement>(containerRef: Ref<Nullable<T>>) {\n let scrollLeft = 0;\n let scrollTop = 0;\n onActivated(() => {\n if (!containerRef.value) return;\n containerRef.value.scrollLeft = scrollLeft;\n containerRef.value.scrollTop = scrollTop;\n });\n\n onBeforeRouteLeave(() => {\n scrollLeft = containerRef.value?.scrollLeft || 0;\n scrollTop = containerRef.value?.scrollTop || 0;\n });\n}\n"],"mappings":";;;;;;;;;;;AAiBA,SAAgB,yCAAyC,KAAa;CAClE,OAAO,yBAAyB,KAAK,UAAU,CAAC,SAAS;;;;;;;AAQ7D,SAAgB,iBAAiB,aAA4D;CACzF,IAAI,YAAY,OAAO,cAAc,YAAY,MAAM;CACvD,YAAY,QAAQ;;;;;;;AAQxB,SAAgB,gBAAgB,YAA0D;CACtF,IAAI,WAAW,OAAO,aAAa,WAAW,MAAM;CACpD,WAAW,QAAQ;;;;;;;;;;;;;;;;AAiBvB,SAAgB,kBAAmD,cAAgC;CAC/F,IAAI,aAAa;CACjB,IAAI,YAAY;CAChB,kBAAkB;EACd,IAAI,CAAC,aAAa,OAAO;EACzB,aAAa,MAAM,aAAa;EAChC,aAAa,MAAM,YAAY;GACjC;CAEF,yBAAyB;EACrB,aAAa,aAAa,OAAO,cAAc;EAC/C,YAAY,aAAa,OAAO,aAAa;GAC/C"}
1
+ {"version":3,"file":"vue.js","names":[],"sources":["../src/vue.ts"],"sourcesContent":["import { onActivated } from 'vue';\nimport type { Ref } from 'vue';\nimport {\n onBeforeRouteLeave,\n useRoute,\n} from 'vue-router';\n\nimport type { Nullable } from './types';\nimport { appendRedirectParamToUrl } from './url';\n\n/**\n * Appends the current Vue Router route's fullPath as the `redirect` query parameter to the given URL.\n *\n * @param {string} url - The base URL to modify\n *\n * @returns {string} A new URL with the current route fullPath as the `redirect` parameter\n */\nexport function appendRedirectParamFromCurrentRouteToUrl(url: string) {\n return appendRedirectParamToUrl(url, useRoute().fullPath);\n}\n\n/**\n * Clears an interval referenced by a Vue ref and sets it to null.\n *\n * @param {Ref<Nullable<ReturnType<typeof setInterval>>>} intervalRef - A Vue ref holding a NodeJS.Timeout or null\n */\nexport function clearIntervalRef(intervalRef: Ref<Nullable<ReturnType<typeof setInterval>>>) {\n if (intervalRef.value) clearInterval(intervalRef.value);\n intervalRef.value = null;\n}\n\n/**\n * Clears a timeout referenced by a Vue ref and sets it to null.\n *\n * @param {Ref<Nullable<ReturnType<typeof setTimeout>>>} timeoutRef - A Vue ref holding a NodeJS.Timeout or null\n */\nexport function clearTimeoutRef(timeoutRef: Ref<Nullable<ReturnType<typeof setTimeout>>>) {\n if (timeoutRef.value) clearTimeout(timeoutRef.value);\n timeoutRef.value = null;\n}\n\n/**\n * A Vue composition function that remembers and restores scroll position\n * of a scrollable container across route changes and keep-alive activation.\n *\n * Designed for use with `<KeepAlive>` components. Scroll state is saved on\n * route leave and restored when the component is activated again.\n *\n * Note: Without `<KeepAlive>`, the component state is destroyed on unmount,\n * so scroll position will not be preserved.\n *\n * @template T - The type of the scrollable element (defaults to HTMLElement)\n *\n * @param {Ref<Nullable<T>>} containerRef - A ref to the scrollable HTML element\n */\nexport function usePreserveScroll<T extends Element = HTMLElement>(containerRef: Ref<Nullable<T>>) {\n let scrollLeft = 0;\n let scrollTop = 0;\n onActivated(() => {\n if (!containerRef.value) return;\n containerRef.value.scrollLeft = scrollLeft;\n containerRef.value.scrollTop = scrollTop;\n });\n\n onBeforeRouteLeave(() => {\n scrollLeft = containerRef.value?.scrollLeft || 0;\n scrollTop = containerRef.value?.scrollTop || 0;\n });\n}\n"],"mappings":";;;;;;;;;;;AAiBA,SAAgB,yCAAyC,KAAa;CAClE,OAAO,yBAAyB,KAAK,SAAS,EAAE,QAAQ;AAC5D;;;;;;AAOA,SAAgB,iBAAiB,aAA4D;CACzF,IAAI,YAAY,OAAO,cAAc,YAAY,KAAK;CACtD,YAAY,QAAQ;AACxB;;;;;;AAOA,SAAgB,gBAAgB,YAA0D;CACtF,IAAI,WAAW,OAAO,aAAa,WAAW,KAAK;CACnD,WAAW,QAAQ;AACvB;;;;;;;;;;;;;;;AAgBA,SAAgB,kBAAmD,cAAgC;CAC/F,IAAI,aAAa;CACjB,IAAI,YAAY;CAChB,kBAAkB;EACd,IAAI,CAAC,aAAa,OAAO;EACzB,aAAa,MAAM,aAAa;EAChC,aAAa,MAAM,YAAY;CACnC,CAAC;CAED,yBAAyB;EACrB,aAAa,aAAa,OAAO,cAAc;EAC/C,YAAY,aAAa,OAAO,aAAa;CACjD,CAAC;AACL"}
package/dist/web.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"web.d.ts","names":[],"sources":["../src/web.ts"],"mappings":";;AASA;;;;;AAeA;iBAfgB,2CAAA,CAA4C,GAAA;;;;;;;;;;;iBAe5C,6CAAA,CAA8C,GAAA,UAAa,OAAA,YAAgB,MAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"web.d.ts","names":[],"sources":["../src/web.ts"],"mappings":";;AASA;;;;AAAuE;AAevE;iBAfgB,2CAAA,CAA4C,GAAW;;;;;;;;AAeoB;;;iBAA3E,6CAAA,CAA8C,GAAA,UAAa,OAAA,YAAgB,MAAA,CAAA,OAAA"}
package/dist/web.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","names":[],"sources":["../src/web.ts"],"sourcesContent":["import { appendRedirectParamToUrl } from './url';\n\n/**\n * Appends the current browser URL (including path, query, and hash) as the `redirect` query parameter to the given URL.\n *\n * @param {string} url - The base URL to modify\n *\n * @returns {string} A new URL with the current location as the `redirect` parameter\n */\nexport function appendRedirectParamFromCurrentLocationToUrl(url: string) {\n const currentPath = `${window.location.pathname}${window.location.search}${window.location.hash}`;\n return appendRedirectParamToUrl(url, currentPath);\n}\n\n/**\n * Navigates to the given URL, appending the current browser location\n * (path, query, and hash) as the `redirect` query parameter.\n *\n * Useful for redirecting to login or other gateways while preserving\n * the current location for post-auth navigation.\n *\n * @param {string} url - The destination URL to navigate to\n * @param {number} [delayMs] - Optional delay in milliseconds before navigation\n */\nexport function assignUrlWithRedirectParamFromCurrentLocation(url: string, delayMs?: number) {\n if (delayMs === undefined) window.location.assign(appendRedirectParamFromCurrentLocationToUrl(url));\n else return setTimeout(() => window.location.assign(appendRedirectParamFromCurrentLocationToUrl(url)), delayMs);\n}\n"],"mappings":";;;;;;;;;AASA,SAAgB,4CAA4C,KAAa;CAErE,OAAO,yBAAyB,KAAK,GADd,OAAO,SAAS,WAAW,OAAO,SAAS,SAAS,OAAO,SAAS,OAC1C;;;;;;;;;;;;AAarD,SAAgB,8CAA8C,KAAa,SAAkB;CACzF,IAAI,YAAY,KAAA,GAAW,OAAO,SAAS,OAAO,4CAA4C,IAAI,CAAC;MAC9F,OAAO,iBAAiB,OAAO,SAAS,OAAO,4CAA4C,IAAI,CAAC,EAAE,QAAQ"}
1
+ {"version":3,"file":"web.js","names":[],"sources":["../src/web.ts"],"sourcesContent":["import { appendRedirectParamToUrl } from './url';\n\n/**\n * Appends the current browser URL (including path, query, and hash) as the `redirect` query parameter to the given URL.\n *\n * @param {string} url - The base URL to modify\n *\n * @returns {string} A new URL with the current location as the `redirect` parameter\n */\nexport function appendRedirectParamFromCurrentLocationToUrl(url: string) {\n const currentPath = `${window.location.pathname}${window.location.search}${window.location.hash}`;\n return appendRedirectParamToUrl(url, currentPath);\n}\n\n/**\n * Navigates to the given URL, appending the current browser location\n * (path, query, and hash) as the `redirect` query parameter.\n *\n * Useful for redirecting to login or other gateways while preserving\n * the current location for post-auth navigation.\n *\n * @param {string} url - The destination URL to navigate to\n * @param {number} [delayMs] - Optional delay in milliseconds before navigation\n */\nexport function assignUrlWithRedirectParamFromCurrentLocation(url: string, delayMs?: number) {\n if (delayMs === undefined) window.location.assign(appendRedirectParamFromCurrentLocationToUrl(url));\n else return setTimeout(() => window.location.assign(appendRedirectParamFromCurrentLocationToUrl(url)), delayMs);\n}\n"],"mappings":";;;;;;;;;AASA,SAAgB,4CAA4C,KAAa;CAErE,OAAO,yBAAyB,KAAK,GADd,OAAO,SAAS,WAAW,OAAO,SAAS,SAAS,OAAO,SAAS,MAC3C;AACpD;;;;;;;;;;;AAYA,SAAgB,8CAA8C,KAAa,SAAkB;CACzF,IAAI,YAAY,KAAA,GAAW,OAAO,SAAS,OAAO,4CAA4C,GAAG,CAAC;MAC7F,OAAO,iBAAiB,OAAO,SAAS,OAAO,4CAA4C,GAAG,CAAC,GAAG,OAAO;AAClH"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kikiutils/shared",
3
3
  "type": "module",
4
- "version": "15.1.0",
4
+ "version": "15.1.1",
5
5
  "description": "A lightweight and modular utility library for modern JavaScript and TypeScript — includes secure hashing, flexible logging, datetime tools, Vue/web helpers, storage abstraction, and more.",
6
6
  "author": "kiki-kanri",
7
7
  "license": "MIT",
@@ -135,13 +135,13 @@
135
135
  }
136
136
  },
137
137
  "devDependencies": {
138
- "@antfu/eslint-config": "^8.2.0",
138
+ "@antfu/eslint-config": "^9.0.0",
139
139
  "@kikiutils/eslint-config": "^9.1.2",
140
140
  "@kikiutils/tsconfigs": "^6.0.0",
141
141
  "@noble/hashes": "^2.2.0",
142
- "@types/node": "^25.6.2",
142
+ "@types/node": "^25.7.0",
143
143
  "@types/ssh2": "^1.15.5",
144
- "@vitest/coverage-v8": "^4.1.5",
144
+ "@vitest/coverage-v8": "^4.1.6",
145
145
  "async-validator": "^4.2.5",
146
146
  "bson": "^7.2.0",
147
147
  "changelogen": "^0.6.2",
@@ -151,19 +151,19 @@
151
151
  "decimal.js": "^10.6.0",
152
152
  "element-plus": "^2.14.0",
153
153
  "jsdom": "^29.1.1",
154
- "knip": "^6.12.2",
154
+ "knip": "^6.13.1",
155
155
  "lru-cache": "^11.3.6",
156
156
  "millify": "^6.1.0",
157
157
  "msgpackr": "^2.0.1",
158
158
  "node-ssh": "^13.2.1",
159
159
  "pino": "^10.3.1",
160
160
  "pino-pretty": "^13.1.3",
161
- "publint": "^0.3.20",
161
+ "publint": "^0.3.21",
162
162
  "tsdown": "^0.22.0",
163
163
  "typescript": "^6.0.3",
164
164
  "unplugin-unused": "^0.5.7",
165
- "vitest": "^4.1.5",
165
+ "vitest": "^4.1.6",
166
166
  "vue": "^3.5.34",
167
- "vue-router": "^5.0.6"
167
+ "vue-router": "^5.0.7"
168
168
  }
169
169
  }
package/src/url.ts CHANGED
@@ -5,18 +5,15 @@
5
5
  *
6
6
  * @param {string} url - The target URL to modify
7
7
  * @param {string} redirectPath - The path to use as the redirect destination
8
- * (must be an absolute path starting with '/')
8
+ * (must be a safe same-origin application path starting with `/`)
9
9
  *
10
10
  * @returns {string} A new URL string with the `redirect` query parameter
11
11
  *
12
- * @throws {Error} If redirectPath is not a valid relative path (must start with '/')
12
+ * @throws {Error} If redirectPath is not a safe same-origin application path
13
13
  */
14
14
  export function appendRedirectParamToUrl(url: string, redirectPath: string) {
15
- if (!redirectPath.startsWith('/')) {
16
- throw new Error(
17
- `Invalid redirect path: "${redirectPath}". Redirect paths must be absolute paths starting with '/'.`,
18
- );
19
- }
15
+ // eslint-disable-next-line style/max-len
16
+ if (!isSafeRedirectPath(redirectPath)) throw new Error(`Invalid redirect path: "${redirectPath}". Redirect paths must be safe same-origin paths starting with '/'.`);
20
17
 
21
18
  const [baseAndHash, rawQuery = ''] = url.split('?');
22
19
  const [base, hash] = (baseAndHash || '').split('#');
@@ -25,3 +22,38 @@ export function appendRedirectParamToUrl(url: string, redirectPath: string) {
25
22
  const queryString = searchParams.toString();
26
23
  return hash ? `${base}?${queryString}#${hash}` : `${base}?${queryString}`;
27
24
  }
25
+
26
+ /**
27
+ * Returns whether a value is a safe same-origin redirect path.
28
+ *
29
+ * Safe redirect paths are absolute application paths such as `/dashboard`.
30
+ * Protocol-relative URLs (`//example.com`), absolute URLs, backslash paths,
31
+ * and non-string values are rejected.
32
+ *
33
+ * @param {unknown} value - The value to check
34
+ *
35
+ * @returns {boolean} Whether the value is safe to use as an application redirect path
36
+ */
37
+ export function isSafeRedirectPath(value: unknown): value is string {
38
+ if (typeof value !== 'string') return false;
39
+ if (!value.startsWith('/')) return false;
40
+ if (value.startsWith('//')) return false;
41
+ if (value.includes('\\')) return false;
42
+ return true;
43
+ }
44
+
45
+ /**
46
+ * Normalizes a redirect value into a safe same-origin application path.
47
+ *
48
+ * If an array is provided, the first value is checked. Unsafe values fall back
49
+ * to the provided fallback path.
50
+ *
51
+ * @param {unknown} value - The redirect value to normalize
52
+ * @param {string} fallback - The safe fallback path
53
+ *
54
+ * @returns {string} A safe redirect path
55
+ */
56
+ export function normalizeRedirectPath(value: unknown, fallback = '/') {
57
+ const redirectPath = Array.isArray(value) ? value[0] : value;
58
+ return isSafeRedirectPath(redirectPath) ? redirectPath : fallback;
59
+ }