@catbee/utils 0.0.2 → 0.0.3

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 (169) hide show
  1. package/build/esm/config.d.ts +1 -1
  2. package/build/esm/config.js +7 -7
  3. package/build/esm/config.js.map +1 -1
  4. package/build/esm/index.d.ts +20 -19
  5. package/build/esm/index.js +20 -19
  6. package/build/esm/index.js.map +1 -1
  7. package/build/esm/types/api-response.d.ts +2 -2
  8. package/build/esm/types/api-response.js.map +1 -1
  9. package/build/esm/utils/array.utils.d.ts +1 -1
  10. package/build/esm/utils/array.utils.js +17 -27
  11. package/build/esm/utils/array.utils.js.map +1 -1
  12. package/build/esm/utils/async.utils.d.ts +1 -5
  13. package/build/esm/utils/async.utils.js +17 -20
  14. package/build/esm/utils/async.utils.js.map +1 -1
  15. package/build/esm/utils/cache.utils.js +2 -2
  16. package/build/esm/utils/cache.utils.js.map +1 -1
  17. package/build/esm/utils/context-store.utils.d.ts +1 -1
  18. package/build/esm/utils/context-store.utils.js +8 -8
  19. package/build/esm/utils/context-store.utils.js.map +1 -1
  20. package/build/esm/utils/crypto.utils.d.ts +2 -2
  21. package/build/esm/utils/crypto.utils.js +37 -45
  22. package/build/esm/utils/crypto.utils.js.map +1 -1
  23. package/build/esm/utils/decorators.utils.d.ts +7 -7
  24. package/build/esm/utils/decorators.utils.js +31 -31
  25. package/build/esm/utils/decorators.utils.js.map +1 -1
  26. package/build/esm/utils/dir.utils.d.ts +4 -4
  27. package/build/esm/utils/dir.utils.js +18 -20
  28. package/build/esm/utils/dir.utils.js.map +1 -1
  29. package/build/esm/utils/env.utils.js +22 -26
  30. package/build/esm/utils/env.utils.js.map +1 -1
  31. package/build/esm/utils/exception.utils.d.ts +1 -1
  32. package/build/esm/utils/exception.utils.js +26 -29
  33. package/build/esm/utils/exception.utils.js.map +1 -1
  34. package/build/esm/utils/fs.utils.d.ts +3 -3
  35. package/build/esm/utils/fs.utils.js +19 -23
  36. package/build/esm/utils/fs.utils.js.map +1 -1
  37. package/build/esm/utils/http-status-codes.js.map +1 -1
  38. package/build/esm/utils/id.utils.js +8 -8
  39. package/build/esm/utils/id.utils.js.map +1 -1
  40. package/build/esm/utils/logger.utils.d.ts +13 -4
  41. package/build/esm/utils/logger.utils.js +15 -15
  42. package/build/esm/utils/logger.utils.js.map +1 -1
  43. package/build/esm/utils/middleware.utils.d.ts +5 -4
  44. package/build/esm/utils/middleware.utils.js +19 -19
  45. package/build/esm/utils/middleware.utils.js.map +1 -1
  46. package/build/esm/utils/obj.utils.js +16 -27
  47. package/build/esm/utils/obj.utils.js.map +1 -1
  48. package/build/esm/utils/response.utils.d.ts +2 -2
  49. package/build/esm/utils/response.utils.js +11 -11
  50. package/build/esm/utils/response.utils.js.map +1 -1
  51. package/build/esm/utils/string.utils.js +17 -17
  52. package/build/esm/utils/string.utils.js.map +1 -1
  53. package/build/esm/utils/url.utils.js +20 -22
  54. package/build/esm/utils/url.utils.js.map +1 -1
  55. package/build/esm/utils/validate.utils.js +11 -15
  56. package/build/esm/utils/validate.utils.js.map +1 -1
  57. package/build/esnext/config.d.ts +1 -1
  58. package/build/esnext/config.js +7 -7
  59. package/build/esnext/config.js.map +1 -1
  60. package/build/esnext/index.d.ts +20 -19
  61. package/build/esnext/index.js +20 -19
  62. package/build/esnext/index.js.map +1 -1
  63. package/build/esnext/types/api-response.d.ts +2 -2
  64. package/build/esnext/types/api-response.js.map +1 -1
  65. package/build/esnext/utils/array.utils.d.ts +1 -1
  66. package/build/esnext/utils/array.utils.js +23 -31
  67. package/build/esnext/utils/array.utils.js.map +1 -1
  68. package/build/esnext/utils/async.utils.d.ts +1 -5
  69. package/build/esnext/utils/async.utils.js +22 -22
  70. package/build/esnext/utils/async.utils.js.map +1 -1
  71. package/build/esnext/utils/cache.utils.js +3 -3
  72. package/build/esnext/utils/cache.utils.js.map +1 -1
  73. package/build/esnext/utils/context-store.utils.d.ts +1 -1
  74. package/build/esnext/utils/context-store.utils.js +10 -10
  75. package/build/esnext/utils/context-store.utils.js.map +1 -1
  76. package/build/esnext/utils/crypto.utils.d.ts +2 -2
  77. package/build/esnext/utils/crypto.utils.js +37 -47
  78. package/build/esnext/utils/crypto.utils.js.map +1 -1
  79. package/build/esnext/utils/decorators.utils.d.ts +7 -7
  80. package/build/esnext/utils/decorators.utils.js +33 -33
  81. package/build/esnext/utils/decorators.utils.js.map +1 -1
  82. package/build/esnext/utils/dir.utils.d.ts +4 -4
  83. package/build/esnext/utils/dir.utils.js +22 -24
  84. package/build/esnext/utils/dir.utils.js.map +1 -1
  85. package/build/esnext/utils/env.utils.js +24 -26
  86. package/build/esnext/utils/env.utils.js.map +1 -1
  87. package/build/esnext/utils/exception.utils.d.ts +1 -1
  88. package/build/esnext/utils/exception.utils.js +26 -29
  89. package/build/esnext/utils/exception.utils.js.map +1 -1
  90. package/build/esnext/utils/fs.utils.d.ts +3 -3
  91. package/build/esnext/utils/fs.utils.js +21 -25
  92. package/build/esnext/utils/fs.utils.js.map +1 -1
  93. package/build/esnext/utils/http-status-codes.js.map +1 -1
  94. package/build/esnext/utils/id.utils.js +8 -8
  95. package/build/esnext/utils/id.utils.js.map +1 -1
  96. package/build/esnext/utils/logger.utils.d.ts +13 -4
  97. package/build/esnext/utils/logger.utils.js +15 -15
  98. package/build/esnext/utils/logger.utils.js.map +1 -1
  99. package/build/esnext/utils/middleware.utils.d.ts +5 -4
  100. package/build/esnext/utils/middleware.utils.js +19 -19
  101. package/build/esnext/utils/middleware.utils.js.map +1 -1
  102. package/build/esnext/utils/obj.utils.js +17 -26
  103. package/build/esnext/utils/obj.utils.js.map +1 -1
  104. package/build/esnext/utils/response.utils.d.ts +2 -2
  105. package/build/esnext/utils/response.utils.js +11 -11
  106. package/build/esnext/utils/response.utils.js.map +1 -1
  107. package/build/esnext/utils/string.utils.js +17 -17
  108. package/build/esnext/utils/string.utils.js.map +1 -1
  109. package/build/esnext/utils/url.utils.js +21 -23
  110. package/build/esnext/utils/url.utils.js.map +1 -1
  111. package/build/esnext/utils/validate.utils.js +14 -16
  112. package/build/esnext/utils/validate.utils.js.map +1 -1
  113. package/build/src/config.d.ts +1 -1
  114. package/build/src/config.js +6 -6
  115. package/build/src/config.js.map +1 -1
  116. package/build/src/index.d.ts +20 -19
  117. package/build/src/index.js +1 -0
  118. package/build/src/index.js.map +1 -1
  119. package/build/src/types/api-response.d.ts +2 -2
  120. package/build/src/types/api-response.js.map +1 -1
  121. package/build/src/utils/array.utils.d.ts +1 -1
  122. package/build/src/utils/array.utils.js +22 -30
  123. package/build/src/utils/array.utils.js.map +1 -1
  124. package/build/src/utils/async.utils.d.ts +1 -5
  125. package/build/src/utils/async.utils.js +22 -22
  126. package/build/src/utils/async.utils.js.map +1 -1
  127. package/build/src/utils/cache.utils.js +2 -2
  128. package/build/src/utils/cache.utils.js.map +1 -1
  129. package/build/src/utils/context-store.utils.d.ts +1 -1
  130. package/build/src/utils/context-store.utils.js +9 -9
  131. package/build/src/utils/context-store.utils.js.map +1 -1
  132. package/build/src/utils/crypto.utils.d.ts +2 -2
  133. package/build/src/utils/crypto.utils.js +35 -45
  134. package/build/src/utils/crypto.utils.js.map +1 -1
  135. package/build/src/utils/decorators.utils.d.ts +7 -7
  136. package/build/src/utils/decorators.utils.js +32 -32
  137. package/build/src/utils/decorators.utils.js.map +1 -1
  138. package/build/src/utils/dir.utils.d.ts +4 -4
  139. package/build/src/utils/dir.utils.js +16 -18
  140. package/build/src/utils/dir.utils.js.map +1 -1
  141. package/build/src/utils/env.utils.js +22 -24
  142. package/build/src/utils/env.utils.js.map +1 -1
  143. package/build/src/utils/exception.utils.d.ts +1 -1
  144. package/build/src/utils/exception.utils.js +23 -26
  145. package/build/src/utils/exception.utils.js.map +1 -1
  146. package/build/src/utils/fs.utils.d.ts +3 -3
  147. package/build/src/utils/fs.utils.js +15 -19
  148. package/build/src/utils/fs.utils.js.map +1 -1
  149. package/build/src/utils/http-status-codes.js.map +1 -1
  150. package/build/src/utils/id.utils.js +7 -7
  151. package/build/src/utils/id.utils.js.map +1 -1
  152. package/build/src/utils/logger.utils.d.ts +13 -4
  153. package/build/src/utils/logger.utils.js +12 -12
  154. package/build/src/utils/logger.utils.js.map +1 -1
  155. package/build/src/utils/middleware.utils.d.ts +5 -4
  156. package/build/src/utils/middleware.utils.js +12 -12
  157. package/build/src/utils/middleware.utils.js.map +1 -1
  158. package/build/src/utils/obj.utils.js +17 -26
  159. package/build/src/utils/obj.utils.js.map +1 -1
  160. package/build/src/utils/response.utils.d.ts +2 -2
  161. package/build/src/utils/response.utils.js +9 -9
  162. package/build/src/utils/response.utils.js.map +1 -1
  163. package/build/src/utils/string.utils.js +17 -17
  164. package/build/src/utils/string.utils.js.map +1 -1
  165. package/build/src/utils/url.utils.js +20 -22
  166. package/build/src/utils/url.utils.js.map +1 -1
  167. package/build/src/utils/validate.utils.js +14 -16
  168. package/build/src/utils/validate.utils.js.map +1 -1
  169. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"async.utils.js","sourceRoot":"","sources":["../../../src/utils/async.utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Delays execution for a specified number of milliseconds.\n *\n * @param {number} ms - The number of milliseconds to sleep.\n * @returns {Promise<void>} A Promise that resolves after the given time.\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Creates a debounced version of a function that delays its execution.\n * Provides `.cancel()` and `.flush()` methods.\n *\n * @template T\n * @param {T} fn - The function to debounce.\n * @param {number} delay - Delay in milliseconds.\n * @returns {T & { cancel: () => void; flush: () => void }} A debounced function.\n */\nexport function debounce<T extends (...args: any[]) => void>(\n fn: T,\n delay: number,\n) {\n let timer: NodeJS.Timeout | null = null;\n let pendingArgs: Parameters<T> | null = null;\n\n function debounced(...args: Parameters<T>) {\n pendingArgs = args;\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n fn(...(pendingArgs as Parameters<T>));\n timer = null;\n }, delay);\n }\n\n debounced.cancel = () => {\n if (timer) clearTimeout(timer);\n timer = null;\n pendingArgs = null;\n };\n\n debounced.flush = () => {\n if (timer) {\n clearTimeout(timer);\n fn(...(pendingArgs as Parameters<T>));\n timer = null;\n pendingArgs = null;\n }\n };\n\n return debounced as typeof debounced & {\n cancel: () => void;\n flush: () => void;\n };\n}\n\n/**\n * Creates a throttled version of a function that limits its execution rate.\n * Allows control over leading/trailing invocation.\n *\n * @template T\n * @param {T} fn - The function to throttle.\n * @param {number} limit - Minimum time between calls in milliseconds.\n * @param {{ leading?: boolean, trailing?: boolean }} [opts] - Options for leading/trailing edge throttling.\n * @returns {(...args: Parameters<T>) => void} A throttled function.\n */\nexport function throttle<T extends (...args: any[]) => void>(\n fn: T,\n limit: number,\n opts: { leading?: boolean; trailing?: boolean } = {\n leading: true,\n trailing: false,\n },\n): (...args: Parameters<T>) => void {\n let lastCall = 0;\n let timer: NodeJS.Timeout | null = null;\n let savedArgs: Parameters<T> | null = null;\n\n return function (...args: Parameters<T>) {\n const now = Date.now();\n const { leading = true, trailing = false } = opts;\n\n if (!lastCall && !leading) lastCall = now;\n\n const remaining = limit - (now - lastCall);\n\n if (remaining <= 0) {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n lastCall = now;\n fn(...args);\n } else if (trailing) {\n savedArgs = args;\n if (!timer) {\n timer = setTimeout(() => {\n lastCall = leading ? Date.now() : 0;\n timer = null;\n if (savedArgs) fn(...savedArgs);\n }, remaining);\n }\n }\n };\n}\n\n/**\n * Retries an asynchronous function a given number of times with optional delay/backoff.\n *\n * @template T\n * @param {() => Promise<T>} fn - The async function to retry.\n * @param {number} [retries=3] - Number of retry attempts.\n * @param {number} [delay=500] - Delay in milliseconds between retries.\n * @param {boolean} [backoff=false] - Use exponential backoff between attempts.\n * @param {(error: unknown, attempt: number) => void} [onRetry] - Callback for each retry attempt.\n * @returns {Promise<T>} The result of the async function if successful.\n * @throws {*} The last encountered error if all retries fail.\n */\nexport async function retry<T>(\n fn: () => Promise<T>,\n retries = 3,\n delay = 500,\n backoff = false,\n onRetry?: (error: unknown, attempt: number) => void,\n): Promise<T> {\n for (let i = 0; i < retries; i++) {\n try {\n return await fn();\n } catch (e) {\n if (i === retries - 1) throw e;\n if (onRetry) onRetry(e, i + 1);\n await sleep(backoff ? delay * Math.pow(2, i) : delay);\n }\n }\n throw new Error(\"Retry failed\"); // should never reach here\n}\n\n/**\n * Wraps a promise and rejects it if it doesn't resolve within the specified timeout.\n *\n * @template T\n * @param {Promise<T>} promise - The original promise.\n * @param {number} ms - Timeout in milliseconds.\n * @param {string} [message=\"Operation timed out\"] - Optional timeout message.\n * @returns {Promise<T>} A promise that resolves or rejects within the timeout.\n */\nexport function withTimeout<T>(\n promise: Promise<T>,\n ms: number,\n message = \"Operation timed out\",\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timeoutHandle = setTimeout(() => reject(new Error(message)), ms);\n promise\n .then((result) => {\n clearTimeout(timeoutHandle);\n resolve(result);\n })\n .catch((err) => {\n clearTimeout(timeoutHandle);\n reject(err);\n });\n });\n}\n\n/**\n * Executes async tasks in true batches.\n * Each batch runs in parallel, but batches run sequentially.\n * All tasks in a batch start at the same time, next batch waits for full completion.\n * NOTE: For more granular concurrency, use a \"queue\" or \"pooled\" approach.\n *\n * @template T\n * @param {Array<() => Promise<T>>} tasks - An array of functions that return Promises.\n * @param {number} limit - Number of tasks to run in parallel per batch.\n * @returns {Promise<T[]>} A promise that resolves to an array of resolved values.\n */\nexport async function runInBatches<T>(\n tasks: (() => Promise<T>)[],\n limit: number,\n): Promise<T[]> {\n const results: T[] = [];\n for (let i = 0; i < tasks.length; i += limit) {\n const batch = tasks.slice(i, i + limit);\n const batchResults = await Promise.all(batch.map((fn) => fn()));\n results.push(...batchResults);\n }\n return results;\n}\n\n/**\n * Wraps a function and ensures it is only called once at a time.\n * Calls made while one is in progress will wait for the same Promise.\n * Optionally, new calls can be dropped while in progress (drop=true).\n *\n * @template TArgs\n * @template TResult\n * @param {(...args: TArgs) => Promise<TResult>} fn - The async function to wrap.\n * @param {boolean} [drop=false] - If true, new calls while one is pending are rejected.\n * @returns {(...args: TArgs) => Promise<TResult>} A wrapped function with singleton behavior.\n */\nexport function singletonAsync<TArgs extends unknown[], TResult>(\n fn: (...args: TArgs) => Promise<TResult>,\n drop: boolean = false,\n): (...args: TArgs) => Promise<TResult> {\n let promise: Promise<TResult> | null = null;\n\n return async (...args: TArgs) => {\n if (!promise) {\n promise = fn(...args).finally(() => {\n promise = null;\n });\n } else if (drop) {\n return Promise.reject(new Error(\"Busy: function already running\"));\n }\n return promise;\n };\n}\n\n/**\n * Resolves a list of async tasks in parallel, returning both resolved and rejected results.\n *\n * @template T\n * @param {Array<() => Promise<T>>} tasks - Array of promise-returning functions.\n * @returns {Promise<PromiseSettledResult<T>[]>} Results including status and value/reason.\n */\nexport async function settleAll<T>(\n tasks: (() => Promise<T>)[],\n): Promise<PromiseSettledResult<T>[]> {\n return Promise.allSettled(tasks.map((task) => task()));\n}\n\nexport interface TaskQueue {\n <T>(taskFn: () => Promise<T>): Promise<T>;\n pause: () => void;\n resume: () => void;\n readonly length: number;\n readonly isPaused: boolean;\n}\n\n/**\n * A simple task queue that executes async tasks with a concurrency limit.\n * Exposes pause, resume, and queue length getters.\n *\n * @param {number} limit - Maximum number of concurrent tasks.\n * @returns {function & { pause: () => void, resume: () => void, length: number, isPaused: boolean }}\n * Enqueue function plus queue controls.\n */\nexport function createTaskQueue(limit: number): TaskQueue {\n const queue: (() => Promise<void>)[] = [];\n let activeCount = 0;\n let paused = false;\n\n const state = {\n /**\n * Pause task processing.\n */\n pause() {\n paused = true;\n },\n /**\n * Resume task processing.\n */\n resume() {\n paused = false;\n next();\n },\n /**\n * The current length of the queue.\n * @type {number}\n */\n get length() {\n return queue.length;\n },\n /**\n * Whether the queue is currently paused.\n * @type {boolean}\n */\n get isPaused() {\n return paused;\n },\n };\n\n const next = () => {\n if (paused || queue.length === 0 || activeCount >= limit) return;\n const task = queue.shift()!;\n activeCount++;\n task().finally(() => {\n activeCount--;\n next();\n });\n };\n\n /**\n * Enqueues a new async task to the queue.\n *\n * @template T\n * @param {() => Promise<T>} taskFn - The async task function.\n * @returns {Promise<T>} Promise resolving when task completes.\n */\n const enqueue = async function <T>(taskFn: () => Promise<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n queue.push(async () => {\n try {\n const result = await taskFn();\n resolve(result);\n } catch (err) {\n reject(err);\n }\n });\n next();\n });\n };\n\n enqueue.pause = state.pause;\n enqueue.resume = state.resume;\n Object.defineProperty(enqueue, \"length\", {\n get: () => queue.length,\n });\n Object.defineProperty(enqueue, \"isPaused\", {\n get: () => paused,\n });\n\n return enqueue as TaskQueue;\n}\n\n/**\n * Executes async functions sequentially and collects results.\n * Useful when order matters or tasks depend on each other.\n *\n * @template T\n * @param {Array<() => Promise<T>>} tasks - Array of promise-returning functions.\n * @returns {Promise<T[]>} Array of resolved values.\n */\nexport async function runInSeries<T>(\n tasks: (() => Promise<T>)[],\n): Promise<T[]> {\n const results: T[] = [];\n for (const task of tasks) {\n results.push(await task());\n }\n return results;\n}\n\n/**\n * Memoizes an async function, caching results for repeated calls with identical arguments.\n * Optional TTL (time-to-live) for cached entries.\n *\n * @template T Function return type\n * @template Args Function arguments types\n * @param {(...args: Args) => Promise<T>} fn - The async function to memoize\n * @param {object} [options] - Memoization options\n * @param {number} [options.ttl] - Cache TTL in milliseconds (optional)\n * @param {(args: Args) => string} [options.keyFn] - Custom key generator function\n * @returns {(...args: Args) => Promise<T>} Memoized function\n */\nexport function memoizeAsync<T, Args extends any[]>(\n fn: (...args: Args) => Promise<T>,\n options: {\n ttl?: number;\n keyFn?: (args: Args) => string;\n } = {},\n): (...args: Args) => Promise<T> {\n const cache = new Map<string, { value: T; expires: number }>();\n const { ttl, keyFn = JSON.stringify } = options;\n\n return async function (...args: Args): Promise<T> {\n const key = keyFn(args);\n const cached = cache.get(key);\n\n if (cached && (!ttl || Date.now() < cached.expires)) {\n return cached.value;\n }\n\n const result = await fn(...args);\n cache.set(key, {\n value: result,\n expires: ttl ? Date.now() + ttl : Infinity,\n });\n\n return result;\n };\n}\n\n/**\n * Creates an abortable version of a promise that can be cancelled using an AbortController.\n *\n * @template T\n * @param {Promise<T>} promise - The promise to make abortable\n * @param {AbortSignal} signal - AbortSignal from AbortController\n * @param {any} [abortValue] - Value to use when rejecting on abort\n * @returns {Promise<T>} Promise that rejects if the signal is aborted\n */\nexport function abortable<T>(\n promise: Promise<T>,\n signal: AbortSignal,\n abortValue: any = new Error(\"Operation aborted\"),\n): Promise<T> {\n if (signal.aborted) {\n return Promise.reject(abortValue);\n }\n\n return Promise.race([\n promise,\n new Promise<T>((_, reject) => {\n const abort = () => reject(abortValue);\n signal.addEventListener(\"abort\", abort, { once: true });\n promise.finally(() => signal.removeEventListener(\"abort\", abort));\n }),\n ]);\n}\n\n/**\n * Creates a promise with external resolve/reject functions.\n * Useful for creating promises that can be resolved or rejected from outside.\n *\n * @template T\n * @returns {[Promise<T>, (value: T | PromiseLike<T>) => void, (reason?: any) => void]}\n * Tuple of [promise, resolve, reject]\n */\nexport function createDeferred<T>(): [\n Promise<T>,\n (value: T | PromiseLike<T>) => void,\n (reason?: any) => void,\n] {\n let resolve!: (value: T | PromiseLike<T>) => void;\n let reject!: (reason?: any) => void;\n\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n return [promise, resolve, reject];\n}\n\n/**\n * Chains a series of async functions, passing the result of each to the next.\n * Similar to function composition but for async functions.\n *\n * @template T\n * @param {Array<(input: any) => Promise<any>>} fns - Array of async functions to compose\n * @returns {(input: any) => Promise<T>} Composed function\n */\nexport function waterfall<T>(\n fns: Array<(input: any) => Promise<any>>,\n): (initialValue: any) => Promise<T> {\n return async (initialValue: any): Promise<T> => {\n return fns.reduce(\n async (acc, fn) => fn(await acc),\n Promise.resolve(initialValue),\n ) as Promise<T>;\n };\n}\n\n/**\n * Creates a rate limiter that ensures functions aren't called more than\n * a specified number of times per interval.\n *\n * @template T\n * @param {(...args: any[]) => Promise<T>} fn - Function to rate limit\n * @param {number} maxCalls - Maximum calls allowed per interval\n * @param {number} interval - Time interval in milliseconds\n * @returns {(...args: any[]) => Promise<T>} Rate limited function\n */\nexport function rateLimit<T>(\n fn: (...args: any[]) => Promise<T>,\n maxCalls: number,\n interval: number,\n): (...args: any[]) => Promise<T> {\n const calls: number[] = [];\n\n return async function (...args: any[]): Promise<T> {\n const now = Date.now();\n calls.splice(\n 0,\n calls.length,\n ...calls.filter((time) => now - time < interval),\n );\n\n if (calls.length >= maxCalls) {\n const oldestCall = calls[0];\n const delay = interval - (now - oldestCall);\n await sleep(Math.max(1, delay));\n // Remove potentially stale entries after sleep\n const currentTime = Date.now();\n calls.splice(\n 0,\n calls.length,\n ...calls.filter((time) => currentTime - time < interval),\n );\n\n // If still at limit after sleep, wait for another cycle\n if (calls.length >= maxCalls) {\n const nextDelay = interval - (currentTime - calls[0]);\n await sleep(Math.max(1, nextDelay));\n calls.splice(\n 0,\n calls.length,\n ...calls.filter((time) => Date.now() - time < interval),\n );\n }\n }\n\n calls.push(Date.now());\n return fn(...args);\n };\n}\n"]}
1
+ {"version":3,"file":"async.utils.js","sourceRoot":"","sources":["../../../src/utils/async.utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Delays execution for a specified number of milliseconds.\n *\n * @param {number} ms - The number of milliseconds to sleep.\n * @returns {Promise<void>} A Promise that resolves after the given time.\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Creates a debounced version of a function that delays its execution.\n * Provides `.cancel()` and `.flush()` methods.\n *\n * @template T\n * @param {T} fn - The function to debounce.\n * @param {number} delay - Delay in milliseconds.\n * @returns {T & { cancel: () => void; flush: () => void }} A debounced function.\n */\nexport function debounce<T extends (...args: any[]) => void>(fn: T, delay: number) {\n let timer: NodeJS.Timeout | null = null;\n let pendingArgs: Parameters<T> | null = null;\n\n function debounced(...args: Parameters<T>) {\n pendingArgs = args;\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n fn(...(pendingArgs as Parameters<T>));\n timer = null;\n }, delay);\n }\n\n debounced.cancel = () => {\n if (timer) clearTimeout(timer);\n timer = null;\n pendingArgs = null;\n };\n\n debounced.flush = () => {\n if (timer) {\n clearTimeout(timer);\n fn(...(pendingArgs as Parameters<T>));\n timer = null;\n pendingArgs = null;\n }\n };\n\n return debounced as typeof debounced & {\n cancel: () => void;\n flush: () => void;\n };\n}\n\n/**\n * Creates a throttled version of a function that limits its execution rate.\n * Allows control over leading/trailing invocation.\n *\n * @template T\n * @param {T} fn - The function to throttle.\n * @param {number} limit - Minimum time between calls in milliseconds.\n * @param {{ leading?: boolean, trailing?: boolean }} [opts] - Options for leading/trailing edge throttling.\n * @returns {(...args: Parameters<T>) => void} A throttled function.\n */\nexport function throttle<T extends (...args: any[]) => void>(\n fn: T,\n limit: number,\n opts: { leading?: boolean; trailing?: boolean } = {\n leading: true,\n trailing: false\n }\n): (...args: Parameters<T>) => void {\n let lastCall = 0;\n let timer: NodeJS.Timeout | null = null;\n let savedArgs: Parameters<T> | null = null;\n\n return function (...args: Parameters<T>) {\n const now = Date.now();\n const { leading = true, trailing = false } = opts;\n\n if (!lastCall && !leading) lastCall = now;\n\n const remaining = limit - (now - lastCall);\n\n if (remaining <= 0) {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n lastCall = now;\n fn(...args);\n } else if (trailing) {\n savedArgs = args;\n if (!timer) {\n timer = setTimeout(() => {\n lastCall = leading ? Date.now() : 0;\n timer = null;\n if (savedArgs) fn(...savedArgs);\n }, remaining);\n }\n }\n };\n}\n\n/**\n * Retries an asynchronous function a given number of times with optional delay/backoff.\n *\n * @template T\n * @param {() => Promise<T>} fn - The async function to retry.\n * @param {number} [retries=3] - Number of retry attempts.\n * @param {number} [delay=500] - Delay in milliseconds between retries.\n * @param {boolean} [backoff=false] - Use exponential backoff between attempts.\n * @param {(error: unknown, attempt: number) => void} [onRetry] - Callback for each retry attempt.\n * @returns {Promise<T>} The result of the async function if successful.\n * @throws {*} The last encountered error if all retries fail.\n */\nexport async function retry<T>(\n fn: () => Promise<T>,\n retries = 3,\n delay = 500,\n backoff = false,\n onRetry?: (error: unknown, attempt: number) => void\n): Promise<T> {\n for (let i = 0; i < retries; i++) {\n try {\n return await fn();\n } catch (e) {\n if (i === retries - 1) throw e;\n if (onRetry) onRetry(e, i + 1);\n await sleep(backoff ? delay * Math.pow(2, i) : delay);\n }\n }\n throw new Error('Retry failed'); // should never reach here\n}\n\n/**\n * Wraps a promise and rejects it if it doesn't resolve within the specified timeout.\n *\n * @template T\n * @param {Promise<T>} promise - The original promise.\n * @param {number} ms - Timeout in milliseconds.\n * @param {string} [message=\"Operation timed out\"] - Optional timeout message.\n * @returns {Promise<T>} A promise that resolves or rejects within the timeout.\n */\nexport function withTimeout<T>(promise: Promise<T>, ms: number, message = 'Operation timed out'): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timeoutHandle = setTimeout(() => reject(new Error(message)), ms);\n promise\n .then(result => {\n clearTimeout(timeoutHandle);\n resolve(result);\n })\n .catch(err => {\n clearTimeout(timeoutHandle);\n reject(err);\n });\n });\n}\n\n/**\n * Executes async tasks in true batches.\n * Each batch runs in parallel, but batches run sequentially.\n * All tasks in a batch start at the same time, next batch waits for full completion.\n * NOTE: For more granular concurrency, use a \"queue\" or \"pooled\" approach.\n *\n * @template T\n * @param {Array<() => Promise<T>>} tasks - An array of functions that return Promises.\n * @param {number} limit - Number of tasks to run in parallel per batch.\n * @returns {Promise<T[]>} A promise that resolves to an array of resolved values.\n */\nexport async function runInBatches<T>(tasks: (() => Promise<T>)[], limit: number): Promise<T[]> {\n const results: T[] = [];\n for (let i = 0; i < tasks.length; i += limit) {\n const batch = tasks.slice(i, i + limit);\n const batchResults = await Promise.all(batch.map(fn => fn()));\n results.push(...batchResults);\n }\n return results;\n}\n\n/**\n * Wraps a function and ensures it is only called once at a time.\n * Calls made while one is in progress will wait for the same Promise.\n * Optionally, new calls can be dropped while in progress (drop=true).\n *\n * @template TArgs\n * @template TResult\n * @param {(...args: TArgs) => Promise<TResult>} fn - The async function to wrap.\n * @param {boolean} [drop=false] - If true, new calls while one is pending are rejected.\n * @returns {(...args: TArgs) => Promise<TResult>} A wrapped function with singleton behavior.\n */\nexport function singletonAsync<TArgs extends unknown[], TResult>(\n fn: (...args: TArgs) => Promise<TResult>,\n drop: boolean = false\n): (...args: TArgs) => Promise<TResult> {\n let promise: Promise<TResult> | null = null;\n\n return async (...args: TArgs) => {\n if (!promise) {\n promise = fn(...args).finally(() => {\n promise = null;\n });\n } else if (drop) {\n return Promise.reject(new Error('Busy: function already running'));\n }\n return promise;\n };\n}\n\n/**\n * Resolves a list of async tasks in parallel, returning both resolved and rejected results.\n *\n * @template T\n * @param {Array<() => Promise<T>>} tasks - Array of promise-returning functions.\n * @returns {Promise<PromiseSettledResult<T>[]>} Results including status and value/reason.\n */\nexport async function settleAll<T>(tasks: (() => Promise<T>)[]): Promise<PromiseSettledResult<T>[]> {\n return Promise.allSettled(tasks.map(task => task()));\n}\n\nexport interface TaskQueue {\n <T>(taskFn: () => Promise<T>): Promise<T>;\n pause: () => void;\n resume: () => void;\n readonly length: number;\n readonly isPaused: boolean;\n}\n\n/**\n * A simple task queue that executes async tasks with a concurrency limit.\n * Exposes pause, resume, and queue length getters.\n *\n * @param {number} limit - Maximum number of concurrent tasks.\n * @returns {function & { pause: () => void, resume: () => void, length: number, isPaused: boolean }}\n * Enqueue function plus queue controls.\n */\nexport function createTaskQueue(limit: number): TaskQueue {\n const queue: (() => Promise<void>)[] = [];\n let activeCount = 0;\n let paused = false;\n\n const state = {\n /**\n * Pause task processing.\n */\n pause() {\n paused = true;\n },\n /**\n * Resume task processing.\n */\n resume() {\n paused = false;\n next();\n },\n /**\n * The current length of the queue.\n * @type {number}\n */\n get length() {\n return queue.length;\n },\n /**\n * Whether the queue is currently paused.\n * @type {boolean}\n */\n get isPaused() {\n return paused;\n }\n };\n\n const next = () => {\n if (paused || queue.length === 0 || activeCount >= limit) return;\n const task = queue.shift()!;\n activeCount++;\n task().finally(() => {\n activeCount--;\n next();\n });\n };\n\n /**\n * Enqueues a new async task to the queue.\n *\n * @template T\n * @param {() => Promise<T>} taskFn - The async task function.\n * @returns {Promise<T>} Promise resolving when task completes.\n */\n const enqueue = async function <T>(taskFn: () => Promise<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n queue.push(async () => {\n try {\n const result = await taskFn();\n resolve(result);\n } catch (err) {\n reject(err);\n }\n });\n next();\n });\n };\n\n enqueue.pause = state.pause;\n enqueue.resume = state.resume;\n Object.defineProperty(enqueue, 'length', {\n get: () => queue.length\n });\n Object.defineProperty(enqueue, 'isPaused', {\n get: () => paused\n });\n\n return enqueue as TaskQueue;\n}\n\n/**\n * Executes async functions sequentially and collects results.\n * Useful when order matters or tasks depend on each other.\n *\n * @template T\n * @param {Array<() => Promise<T>>} tasks - Array of promise-returning functions.\n * @returns {Promise<T[]>} Array of resolved values.\n */\nexport async function runInSeries<T>(tasks: (() => Promise<T>)[]): Promise<T[]> {\n const results: T[] = [];\n for (const task of tasks) {\n results.push(await task());\n }\n return results;\n}\n\n/**\n * Memoizes an async function, caching results for repeated calls with identical arguments.\n * Optional TTL (time-to-live) for cached entries.\n *\n * @template T Function return type\n * @template Args Function arguments types\n * @param {(...args: Args) => Promise<T>} fn - The async function to memoize\n * @param {object} [options] - Memoization options\n * @param {number} [options.ttl] - Cache TTL in milliseconds (optional)\n * @param {(args: Args) => string} [options.keyFn] - Custom key generator function\n * @returns {(...args: Args) => Promise<T>} Memoized function\n */\nexport function memoizeAsync<T, Args extends any[]>(\n fn: (...args: Args) => Promise<T>,\n options: {\n ttl?: number;\n keyFn?: (args: Args) => string;\n } = {}\n): (...args: Args) => Promise<T> {\n const cache = new Map<string, { value: T; expires: number }>();\n const { ttl, keyFn = JSON.stringify } = options;\n\n return async function (...args: Args): Promise<T> {\n const key = keyFn(args);\n const cached = cache.get(key);\n\n if (cached && (!ttl || Date.now() < cached.expires)) {\n return cached.value;\n }\n\n const result = await fn(...args);\n cache.set(key, {\n value: result,\n expires: ttl ? Date.now() + ttl : Infinity\n });\n\n return result;\n };\n}\n\n/**\n * Creates an abortable version of a promise that can be cancelled using an AbortController.\n *\n * @template T\n * @param {Promise<T>} promise - The promise to make abortable\n * @param {AbortSignal} signal - AbortSignal from AbortController\n * @param {any} [abortValue] - Value to use when rejecting on abort\n * @returns {Promise<T>} Promise that rejects if the signal is aborted\n */\nexport function abortable<T>(\n promise: Promise<T>,\n signal: AbortSignal,\n abortValue: any = new Error('Operation aborted')\n): Promise<T> {\n if (signal.aborted) {\n return Promise.reject(abortValue);\n }\n\n return Promise.race([\n promise,\n new Promise<T>((_, reject) => {\n const abort = () => reject(abortValue);\n signal.addEventListener('abort', abort, { once: true });\n promise.finally(() => signal.removeEventListener('abort', abort));\n })\n ]);\n}\n\n/**\n * Creates a promise with external resolve/reject functions.\n * Useful for creating promises that can be resolved or rejected from outside.\n *\n * @template T\n * @returns {[Promise<T>, (value: T | PromiseLike<T>) => void, (reason?: any) => void]}\n * Tuple of [promise, resolve, reject]\n */\nexport function createDeferred<T>(): [Promise<T>, (value: T | PromiseLike<T>) => void, (reason?: any) => void] {\n let resolve!: (value: T | PromiseLike<T>) => void;\n let reject!: (reason?: any) => void;\n\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n return [promise, resolve, reject];\n}\n\n/**\n * Chains a series of async functions, passing the result of each to the next.\n * Similar to function composition but for async functions.\n *\n * @template T\n * @param {Array<(input: any) => Promise<any>>} fns - Array of async functions to compose\n * @returns {(input: any) => Promise<T>} Composed function\n */\nexport function waterfall<T>(fns: Array<(input: any) => Promise<any>>): (initialValue: any) => Promise<T> {\n return async (initialValue: any): Promise<T> => {\n return fns.reduce(async (acc, fn) => fn(await acc), Promise.resolve(initialValue)) as Promise<T>;\n };\n}\n\n/**\n * Creates a rate limiter that ensures functions aren't called more than\n * a specified number of times per interval.\n *\n * @template T\n * @param {(...args: any[]) => Promise<T>} fn - Function to rate limit\n * @param {number} maxCalls - Maximum calls allowed per interval\n * @param {number} interval - Time interval in milliseconds\n * @returns {(...args: any[]) => Promise<T>} Rate limited function\n */\nexport function rateLimit<T>(\n fn: (...args: any[]) => Promise<T>,\n maxCalls: number,\n interval: number\n): (...args: any[]) => Promise<T> {\n const calls: number[] = [];\n\n return async function (...args: any[]): Promise<T> {\n const now = Date.now();\n calls.splice(0, calls.length, ...calls.filter(time => now - time < interval));\n\n if (calls.length >= maxCalls) {\n const oldestCall = calls[0];\n const delay = interval - (now - oldestCall);\n await sleep(Math.max(1, delay));\n // Remove potentially stale entries after sleep\n const currentTime = Date.now();\n calls.splice(0, calls.length, ...calls.filter(time => currentTime - time < interval));\n\n // If still at limit after sleep, wait for another cycle\n if (calls.length >= maxCalls) {\n const nextDelay = interval - (currentTime - calls[0]);\n await sleep(Math.max(1, nextDelay));\n calls.splice(0, calls.length, ...calls.filter(time => Date.now() - time < interval));\n }\n }\n\n calls.push(Date.now());\n return fn(...args);\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { Config } from "../config";
1
+ import { Config } from '../config';
2
2
  /**
3
3
  * An in-memory cache with time-to-live (TTL) support for each entry.
4
4
  *
@@ -136,7 +136,7 @@ export class TTLCache {
136
136
  * @returns Array of values (undefined for keys that don't exist or expired)
137
137
  */
138
138
  getMany(keys) {
139
- return keys.map((key) => this.get(key));
139
+ return keys.map(key => this.get(key));
140
140
  }
141
141
  /**
142
142
  * Removes all expired entries from the cache.
@@ -231,7 +231,7 @@ export class TTLCache {
231
231
  size: this.cache.size,
232
232
  validEntries: valid,
233
233
  expiredEntries: expired,
234
- maxSize: this.maxSize,
234
+ maxSize: this.maxSize
235
235
  };
236
236
  }
237
237
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"cache.utils.js","sourceRoot":"","sources":["../../../src/utils/cache.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAuBnC;;;;;;;;;;GAUG;AACH,MAAM,OAAO,QAAQ;IAMnB;;OAEG;IACH,YAAY,UAA2B,EAAE;;QARjC,UAAK,GAAG,IAAI,GAAG,EAAoB,CAAC;QAS1C,IAAI,CAAC,KAAK,GAAG,MAAA,OAAO,CAAC,KAAK,mCAAI,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC;QACtD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAE/B,gCAAgC;QAChC,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;QAC5C,IAAI,aAAa,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE;gBACtC,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,CAAC,EAAE,aAAa,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,GAAM,EAAE,KAAQ;QAClB,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,GAAM,EAAE,KAAQ,EAAE,KAAa;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,GAAG,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;QAE7D,uCAAuC;QACvC,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,GAAM;QACR,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAE7B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,2CAA2C;QAC3C,KAAK,CAAC,YAAY,GAAG,GAAG,CAAC;QACzB,OAAO,KAAK,CAAC,KAAK,CAAC;IACrB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,YAAY,CAChB,GAAM,EACN,QAA0B,EAC1B,KAAc;QAEd,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QAEtC,MAAM,QAAQ,GAAG,MAAM,QAAQ,EAAE,CAAC;QAClC,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QACpD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,GAAM;QACR,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;IACrC,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,GAAM;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACH,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACH,OAAO,CAAC,OAAiB;QACvB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,IAAS;QACf,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACH,OAAO;QACL,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAChD,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACvB,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACH,CAAC,OAAO;QACN,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAChD,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBAClC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,CAAC,IAAI;QACH,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAChD,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBAClC,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,CAAC,MAAM;QACL,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBAClC,MAAM,KAAK,CAAC,KAAK,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,GAAM,EAAE,KAAc;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QAEzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,KAAK,CAAC,SAAS,GAAG,GAAG,GAAG,CAAC,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9C,KAAK,CAAC,YAAY,GAAG,GAAG,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;gBAC1B,OAAO,EAAE,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,KAAK,EAAE,CAAC;YACV,CAAC;QACH,CAAC;QAED,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;YACrB,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,OAAO;YACvB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACpC,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QACnC,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,QAAQ;QACd,IAAI,SAAwB,CAAC;QAC7B,IAAI,YAAY,GAAG,QAAQ,CAAC;QAE5B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAChD,wCAAwC;YACxC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;gBACjC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACvB,OAAO;YACT,CAAC;YAED,iCAAiC;YACjC,IAAI,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,GAAG,YAAY,EAAE,CAAC;gBAC5D,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;gBAClC,SAAS,GAAG,GAAG,CAAC;YAClB,CAAC;QACH,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;CACF","sourcesContent":["import { Config } from \"../config\";\n\n/**\n * Represents a cached entry with a value and an expiration timestamp.\n */\ntype CacheEntry<T> = {\n value: T;\n expiresAt: number;\n lastAccessed?: number; // Track last access time for LRU functionality\n};\n\n/**\n * Options for configuring a TTLCache instance.\n */\nexport interface TTLCacheOptions {\n /** Default time-to-live in milliseconds for cache entries */\n ttlMs?: number;\n /** Maximum number of entries to keep in cache (uses LRU eviction policy) */\n maxSize?: number;\n /** Auto-cleanup interval in milliseconds (disabled if 0 or negative) */\n autoCleanupMs?: number;\n}\n\n/**\n * An in-memory cache with time-to-live (TTL) support for each entry.\n *\n * @typeParam K - Type of the key.\n * @typeParam V - Type of the value.\n *\n * @example\n * const cache = new TTLCache<string, number>({ ttlMs: 1000 });\n * cache.set(\"x\", 123);\n * const value = cache.get(\"x\"); // 123\n */\nexport class TTLCache<K, V> {\n private cache = new Map<K, CacheEntry<V>>();\n private ttlMs: number;\n private maxSize?: number;\n private cleanupInterval?: NodeJS.Timeout;\n\n /**\n * @param options - Configuration options for the cache\n */\n constructor(options: TTLCacheOptions = {}) {\n this.ttlMs = options.ttlMs ?? Config.Cache.defaultTtl;\n this.maxSize = options.maxSize;\n\n // Setup auto-cleanup if enabled\n const autoCleanupMs = options.autoCleanupMs;\n if (autoCleanupMs && autoCleanupMs > 0) {\n this.cleanupInterval = setInterval(() => {\n this.cleanup();\n }, autoCleanupMs);\n }\n }\n\n /**\n * Sets a key-value pair in the cache with the default TTL.\n *\n * @param key - The key to set.\n * @param value - The value to associate with the key.\n */\n set(key: K, value: V): void {\n this.setWithTTL(key, value, this.ttlMs);\n }\n\n /**\n * Sets a key-value pair in the cache with a custom TTL.\n *\n * @param key - The key to set.\n * @param value - The value to associate with the key.\n * @param ttlMs - Time-to-live in milliseconds.\n */\n setWithTTL(key: K, value: V, ttlMs: number): void {\n const now = Date.now();\n const expiresAt = now + ttlMs;\n this.cache.set(key, { value, expiresAt, lastAccessed: now });\n\n // Enforce max size limit if configured\n if (this.maxSize && this.cache.size > this.maxSize) {\n this.evictLRU();\n }\n }\n\n /**\n * Retrieves the value for a given key if it hasn't expired.\n *\n * @param key - The key to retrieve.\n * @returns The cached value, or undefined if not found or expired.\n */\n get(key: K): V | undefined {\n const entry = this.cache.get(key);\n if (!entry) return undefined;\n\n const now = Date.now();\n if (now > entry.expiresAt) {\n this.cache.delete(key);\n return undefined;\n }\n\n // Update last access time for LRU tracking\n entry.lastAccessed = now;\n return entry.value;\n }\n\n /**\n * Retrieves or computes a value if it's not in the cache or has expired.\n *\n * @param key - The key to retrieve\n * @param producer - Function to generate the value if not cached\n * @param ttlMs - Optional custom TTL for the computed value\n * @returns The cached or computed value\n */\n async getOrCompute(\n key: K,\n producer: () => Promise<V>,\n ttlMs?: number,\n ): Promise<V> {\n const value = this.get(key);\n if (value !== undefined) return value;\n\n const newValue = await producer();\n this.setWithTTL(key, newValue, ttlMs ?? this.ttlMs);\n return newValue;\n }\n\n /**\n * Checks if the key exists and hasn't expired.\n *\n * @param key - The key to check.\n * @returns `true` if key exists and is valid, otherwise `false`.\n */\n has(key: K): boolean {\n return this.get(key) !== undefined;\n }\n\n /**\n * Deletes a key from the cache.\n *\n * @param key - The key to delete.\n * @returns `true` if the key existed and was removed, `false` otherwise.\n */\n delete(key: K): boolean {\n return this.cache.delete(key);\n }\n\n /**\n * Clears all entries from the cache.\n */\n clear(): void {\n this.cache.clear();\n }\n\n /**\n * Returns the number of entries currently in the cache (includes expired entries until next access/cleanup).\n *\n * @returns Number of items in the cache (may include expired keys).\n */\n size(): number {\n return this.cache.size;\n }\n\n /**\n * Set multiple key-value pairs at once with the default TTL.\n *\n * @param entries - Array of [key, value] tuples to set\n */\n setMany(entries: [K, V][]): void {\n for (const [key, value] of entries) {\n this.set(key, value);\n }\n }\n\n /**\n * Get multiple values at once.\n *\n * @param keys - Array of keys to retrieve\n * @returns Array of values (undefined for keys that don't exist or expired)\n */\n getMany(keys: K[]): (V | undefined)[] {\n return keys.map((key) => this.get(key));\n }\n\n /**\n * Removes all expired entries from the cache.\n *\n * @returns Number of entries removed.\n */\n cleanup(): number {\n let removed = 0;\n const now = Date.now();\n for (const [key, entry] of this.cache.entries()) {\n if (now > entry.expiresAt) {\n this.cache.delete(key);\n removed++;\n }\n }\n return removed;\n }\n\n /**\n * Returns an iterator of all current valid [key, value] pairs.\n *\n * @returns IterableIterator<[K, V]>\n */\n *entries(): IterableIterator<[K, V]> {\n for (const [key, entry] of this.cache.entries()) {\n if (Date.now() <= entry.expiresAt) {\n yield [key, entry.value];\n }\n }\n }\n\n /**\n * Returns an iterator of all current valid keys.\n *\n * @returns IterableIterator<K>\n */\n *keys(): IterableIterator<K> {\n for (const [key, entry] of this.cache.entries()) {\n if (Date.now() <= entry.expiresAt) {\n yield key;\n }\n }\n }\n\n /**\n * Returns an iterator of all current valid values.\n *\n * @returns IterableIterator<V>\n */\n *values(): IterableIterator<V> {\n for (const entry of this.cache.values()) {\n if (Date.now() <= entry.expiresAt) {\n yield entry.value;\n }\n }\n }\n\n /**\n * Extends the expiration of a key by the specified time or default TTL.\n *\n * @param key - The key to refresh\n * @param ttlMs - Optional new TTL in milliseconds (uses default if not specified)\n * @returns true if the key was found and refreshed, false otherwise\n */\n refresh(key: K, ttlMs?: number): boolean {\n const entry = this.cache.get(key);\n if (!entry) return false;\n\n const now = Date.now();\n if (now > entry.expiresAt) {\n this.cache.delete(key);\n return false;\n }\n\n entry.expiresAt = now + (ttlMs ?? this.ttlMs);\n entry.lastAccessed = now;\n return true;\n }\n\n /**\n * Returns a snapshot of cache stats.\n *\n * @returns Object containing cache statistics\n */\n stats() {\n const now = Date.now();\n let expired = 0;\n let valid = 0;\n\n for (const entry of this.cache.values()) {\n if (now > entry.expiresAt) {\n expired++;\n } else {\n valid++;\n }\n }\n\n return {\n size: this.cache.size,\n validEntries: valid,\n expiredEntries: expired,\n maxSize: this.maxSize,\n };\n }\n\n /**\n * Stop the auto-cleanup interval if it's running.\n */\n destroy() {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = undefined;\n }\n }\n\n /**\n * Evict the least recently used entry from the cache.\n * @private\n */\n private evictLRU(): void {\n let oldestKey: K | undefined;\n let oldestAccess = Infinity;\n\n for (const [key, entry] of this.cache.entries()) {\n // Skip entries that are already expired\n if (Date.now() > entry.expiresAt) {\n this.cache.delete(key);\n return;\n }\n\n // Find the oldest accessed entry\n if (entry.lastAccessed && entry.lastAccessed < oldestAccess) {\n oldestAccess = entry.lastAccessed;\n oldestKey = key;\n }\n }\n\n if (oldestKey) {\n this.cache.delete(oldestKey);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"cache.utils.js","sourceRoot":"","sources":["../../../src/utils/cache.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Config } from '../config';\n\n/**\n * Represents a cached entry with a value and an expiration timestamp.\n */\ntype CacheEntry<T> = {\n value: T;\n expiresAt: number;\n lastAccessed?: number; // Track last access time for LRU functionality\n};\n\n/**\n * Options for configuring a TTLCache instance.\n */\nexport interface TTLCacheOptions {\n /** Default time-to-live in milliseconds for cache entries */\n ttlMs?: number;\n /** Maximum number of entries to keep in cache (uses LRU eviction policy) */\n maxSize?: number;\n /** Auto-cleanup interval in milliseconds (disabled if 0 or negative) */\n autoCleanupMs?: number;\n}\n\n/**\n * An in-memory cache with time-to-live (TTL) support for each entry.\n *\n * @typeParam K - Type of the key.\n * @typeParam V - Type of the value.\n *\n * @example\n * const cache = new TTLCache<string, number>({ ttlMs: 1000 });\n * cache.set(\"x\", 123);\n * const value = cache.get(\"x\"); // 123\n */\nexport class TTLCache<K, V> {\n private cache = new Map<K, CacheEntry<V>>();\n private ttlMs: number;\n private maxSize?: number;\n private cleanupInterval?: NodeJS.Timeout;\n\n /**\n * @param options - Configuration options for the cache\n */\n constructor(options: TTLCacheOptions = {}) {\n this.ttlMs = options.ttlMs ?? Config.Cache.defaultTtl;\n this.maxSize = options.maxSize;\n\n // Setup auto-cleanup if enabled\n const autoCleanupMs = options.autoCleanupMs;\n if (autoCleanupMs && autoCleanupMs > 0) {\n this.cleanupInterval = setInterval(() => {\n this.cleanup();\n }, autoCleanupMs);\n }\n }\n\n /**\n * Sets a key-value pair in the cache with the default TTL.\n *\n * @param key - The key to set.\n * @param value - The value to associate with the key.\n */\n set(key: K, value: V): void {\n this.setWithTTL(key, value, this.ttlMs);\n }\n\n /**\n * Sets a key-value pair in the cache with a custom TTL.\n *\n * @param key - The key to set.\n * @param value - The value to associate with the key.\n * @param ttlMs - Time-to-live in milliseconds.\n */\n setWithTTL(key: K, value: V, ttlMs: number): void {\n const now = Date.now();\n const expiresAt = now + ttlMs;\n this.cache.set(key, { value, expiresAt, lastAccessed: now });\n\n // Enforce max size limit if configured\n if (this.maxSize && this.cache.size > this.maxSize) {\n this.evictLRU();\n }\n }\n\n /**\n * Retrieves the value for a given key if it hasn't expired.\n *\n * @param key - The key to retrieve.\n * @returns The cached value, or undefined if not found or expired.\n */\n get(key: K): V | undefined {\n const entry = this.cache.get(key);\n if (!entry) return undefined;\n\n const now = Date.now();\n if (now > entry.expiresAt) {\n this.cache.delete(key);\n return undefined;\n }\n\n // Update last access time for LRU tracking\n entry.lastAccessed = now;\n return entry.value;\n }\n\n /**\n * Retrieves or computes a value if it's not in the cache or has expired.\n *\n * @param key - The key to retrieve\n * @param producer - Function to generate the value if not cached\n * @param ttlMs - Optional custom TTL for the computed value\n * @returns The cached or computed value\n */\n async getOrCompute(key: K, producer: () => Promise<V>, ttlMs?: number): Promise<V> {\n const value = this.get(key);\n if (value !== undefined) return value;\n\n const newValue = await producer();\n this.setWithTTL(key, newValue, ttlMs ?? this.ttlMs);\n return newValue;\n }\n\n /**\n * Checks if the key exists and hasn't expired.\n *\n * @param key - The key to check.\n * @returns `true` if key exists and is valid, otherwise `false`.\n */\n has(key: K): boolean {\n return this.get(key) !== undefined;\n }\n\n /**\n * Deletes a key from the cache.\n *\n * @param key - The key to delete.\n * @returns `true` if the key existed and was removed, `false` otherwise.\n */\n delete(key: K): boolean {\n return this.cache.delete(key);\n }\n\n /**\n * Clears all entries from the cache.\n */\n clear(): void {\n this.cache.clear();\n }\n\n /**\n * Returns the number of entries currently in the cache (includes expired entries until next access/cleanup).\n *\n * @returns Number of items in the cache (may include expired keys).\n */\n size(): number {\n return this.cache.size;\n }\n\n /**\n * Set multiple key-value pairs at once with the default TTL.\n *\n * @param entries - Array of [key, value] tuples to set\n */\n setMany(entries: [K, V][]): void {\n for (const [key, value] of entries) {\n this.set(key, value);\n }\n }\n\n /**\n * Get multiple values at once.\n *\n * @param keys - Array of keys to retrieve\n * @returns Array of values (undefined for keys that don't exist or expired)\n */\n getMany(keys: K[]): (V | undefined)[] {\n return keys.map(key => this.get(key));\n }\n\n /**\n * Removes all expired entries from the cache.\n *\n * @returns Number of entries removed.\n */\n cleanup(): number {\n let removed = 0;\n const now = Date.now();\n for (const [key, entry] of this.cache.entries()) {\n if (now > entry.expiresAt) {\n this.cache.delete(key);\n removed++;\n }\n }\n return removed;\n }\n\n /**\n * Returns an iterator of all current valid [key, value] pairs.\n *\n * @returns IterableIterator<[K, V]>\n */\n *entries(): IterableIterator<[K, V]> {\n for (const [key, entry] of this.cache.entries()) {\n if (Date.now() <= entry.expiresAt) {\n yield [key, entry.value];\n }\n }\n }\n\n /**\n * Returns an iterator of all current valid keys.\n *\n * @returns IterableIterator<K>\n */\n *keys(): IterableIterator<K> {\n for (const [key, entry] of this.cache.entries()) {\n if (Date.now() <= entry.expiresAt) {\n yield key;\n }\n }\n }\n\n /**\n * Returns an iterator of all current valid values.\n *\n * @returns IterableIterator<V>\n */\n *values(): IterableIterator<V> {\n for (const entry of this.cache.values()) {\n if (Date.now() <= entry.expiresAt) {\n yield entry.value;\n }\n }\n }\n\n /**\n * Extends the expiration of a key by the specified time or default TTL.\n *\n * @param key - The key to refresh\n * @param ttlMs - Optional new TTL in milliseconds (uses default if not specified)\n * @returns true if the key was found and refreshed, false otherwise\n */\n refresh(key: K, ttlMs?: number): boolean {\n const entry = this.cache.get(key);\n if (!entry) return false;\n\n const now = Date.now();\n if (now > entry.expiresAt) {\n this.cache.delete(key);\n return false;\n }\n\n entry.expiresAt = now + (ttlMs ?? this.ttlMs);\n entry.lastAccessed = now;\n return true;\n }\n\n /**\n * Returns a snapshot of cache stats.\n *\n * @returns Object containing cache statistics\n */\n stats() {\n const now = Date.now();\n let expired = 0;\n let valid = 0;\n\n for (const entry of this.cache.values()) {\n if (now > entry.expiresAt) {\n expired++;\n } else {\n valid++;\n }\n }\n\n return {\n size: this.cache.size,\n validEntries: valid,\n expiredEntries: expired,\n maxSize: this.maxSize\n };\n }\n\n /**\n * Stop the auto-cleanup interval if it's running.\n */\n destroy() {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = undefined;\n }\n }\n\n /**\n * Evict the least recently used entry from the cache.\n * @private\n */\n private evictLRU(): void {\n let oldestKey: K | undefined;\n let oldestAccess = Infinity;\n\n for (const [key, entry] of this.cache.entries()) {\n // Skip entries that are already expired\n if (Date.now() > entry.expiresAt) {\n this.cache.delete(key);\n return;\n }\n\n // Find the oldest accessed entry\n if (entry.lastAccessed && entry.lastAccessed < oldestAccess) {\n oldestAccess = entry.lastAccessed;\n oldestKey = key;\n }\n }\n\n if (oldestKey) {\n this.cache.delete(oldestKey);\n }\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { AsyncLocalStorage } from "async_hooks";
1
+ import { AsyncLocalStorage } from 'async_hooks';
2
2
  /**
3
3
  * Type representing the store object used in AsyncLocalStorage.
4
4
  * Keys must be unique symbols to ensure isolation and prevent collisions.
@@ -1,15 +1,15 @@
1
- import { AsyncLocalStorage } from "async_hooks";
1
+ import { AsyncLocalStorage } from 'async_hooks';
2
2
  /**
3
3
  * Predefined symbols used as keys in AsyncLocalStorage.
4
4
  * Add new symbols here to avoid duplication.
5
5
  */
6
6
  export const StoreKeys = {
7
- LOGGER: Symbol("logger"),
8
- REQUEST_ID: Symbol("requestId"),
9
- USER_ID: Symbol("userId"),
10
- TENANT_ID: Symbol("tenantId"),
11
- TRACE_ID: Symbol("traceId"),
12
- CORRELATION_ID: Symbol("correlationId"),
7
+ LOGGER: Symbol('logger'),
8
+ REQUEST_ID: Symbol('requestId'),
9
+ USER_ID: Symbol('userId'),
10
+ TENANT_ID: Symbol('tenantId'),
11
+ TRACE_ID: Symbol('traceId'),
12
+ CORRELATION_ID: Symbol('correlationId')
13
13
  };
14
14
  /**
15
15
  * Retrieves the current request ID from the async context, if available.
@@ -132,9 +132,9 @@ export class ContextStore {
132
132
  static patch(values) {
133
133
  const store = this.storage.getStore();
134
134
  if (!store) {
135
- throw new Error("Failed to patch: AsyncLocalStorage store is not initialized.");
135
+ throw new Error('Failed to patch: AsyncLocalStorage store is not initialized.');
136
136
  }
137
- Object.getOwnPropertySymbols(values).forEach((key) => {
137
+ Object.getOwnPropertySymbols(values).forEach(key => {
138
138
  store[key] = values[key];
139
139
  });
140
140
  }
@@ -186,7 +186,7 @@ export class ContextStore {
186
186
  // Create new store with current values plus new ones
187
187
  const newStore = Object.assign({}, currentStore);
188
188
  // Add new values
189
- Object.getOwnPropertySymbols(newValues).forEach((key) => {
189
+ Object.getOwnPropertySymbols(newValues).forEach(key => {
190
190
  newStore[key] = newValues[key];
191
191
  });
192
192
  // Run with extended store
@@ -1 +1 @@
1
- {"version":3,"file":"context-store.utils.js","sourceRoot":"","sources":["../../../src/utils/context-store.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from \"async_hooks\";\n\n/**\n * Type representing the store object used in AsyncLocalStorage.\n * Keys must be unique symbols to ensure isolation and prevent collisions.\n */\nexport interface Store {\n [key: symbol]: unknown;\n}\n\n/**\n * Predefined symbols used as keys in AsyncLocalStorage.\n * Add new symbols here to avoid duplication.\n */\nexport const StoreKeys = {\n LOGGER: Symbol(\"logger\"),\n REQUEST_ID: Symbol(\"requestId\"),\n USER_ID: Symbol(\"userId\"),\n TENANT_ID: Symbol(\"tenantId\"),\n TRACE_ID: Symbol(\"traceId\"),\n CORRELATION_ID: Symbol(\"correlationId\"),\n};\n\n/**\n * Retrieves the current request ID from the async context, if available.\n *\n * @returns {string | undefined} The request ID string or undefined if not present in the current context.\n */\nexport function getRequestId(): string | undefined {\n return ContextStore.get<string>(StoreKeys.REQUEST_ID);\n}\n\n/**\n * Type-safe getter for common context values.\n *\n * @param key The store key symbol\n * @returns The typed value from the store\n */\nexport function getFromContext<T>(key: symbol): T | undefined {\n return ContextStore.get<T>(key);\n}\n\n/**\n * ContextStore manages per-request scoped context using AsyncLocalStorage.\n * It allows storing and retrieving data across async calls (e.g., request ID, logger).\n *\n * Example (Express middleware):\n * ```\n * // Middleware to initialize context and logger\n * app.use((req, res, next) => {\n * const requestId = req.headers[\"x-request-id\"]?.toString() || crypto.randomUUID();\n * ContextStore.run({ [StoreKeys.REQUEST_ID]: requestId }, () => {\n * ContextStore.set(StoreKeys.LOGGER, getLogger().child({ reqId: requestId }));\n * next();\n * });\n * });\n * ```\n */\nexport class ContextStore {\n /**\n * The underlying AsyncLocalStorage instance for context.\n * @private\n */\n private static readonly storage = new AsyncLocalStorage<Store>();\n\n /**\n * Returns the raw AsyncLocalStorage instance for advanced access.\n *\n * @returns {AsyncLocalStorage<Store>} The AsyncLocalStorage instance.\n */\n static getInstance(): AsyncLocalStorage<Store> {\n return this.storage;\n }\n\n /**\n * Retrieves a value from the async context store by symbol key.\n *\n * @typeParam T - The expected return type of the value.\n * @param {symbol} key - Unique symbol used as the store key.\n * @returns {T | undefined} The value found (typed) or undefined if not present.\n */\n static get<T>(key: symbol): T | undefined {\n const store = this.storage.getStore();\n return store?.[key] as T | undefined;\n }\n\n /**\n * Sets a value in the current context store by symbol key.\n *\n * @typeParam T - The value type to set.\n * @param {symbol} key - Unique symbol key.\n * @param {T} value - Value to set in context.\n * @throws {Error} If called outside an active context (not within a .run call or in the wrong async boundaries).\n */\n static set<T>(key: symbol, value: T): void {\n const store = this.storage.getStore();\n if (!store) {\n throw new Error(\n `Failed to set ${String(key)}: AsyncLocalStorage store is not initialized.`,\n );\n }\n store[key] = value;\n }\n\n /**\n * Retrieves the entire context store object for the current async context.\n *\n * @returns {Store | undefined} The current store object or undefined if called outside a context.\n */\n static getAll(): Store | undefined {\n return this.storage.getStore();\n }\n\n /**\n * Initializes a new async context and executes a callback within it.\n * This must be called at the beginning of a request or logical async flow.\n *\n * @typeParam T - The callback's return type.\n * @param {Store} store - The initial key-value store object.\n * @param {() => T} callback - The function to run within the new context.\n * @returns {T} The result of the callback function.\n */\n static run<T>(store: Store, callback: () => T): T {\n return this.storage.run(store, callback);\n }\n\n /**\n * Checks if a key exists in the current context store.\n *\n * @param {symbol} key - The symbol key to check.\n * @returns {boolean} True if the key exists, false otherwise.\n */\n static has(key: symbol): boolean {\n const store = this.storage.getStore();\n return store !== undefined && key in store;\n }\n\n /**\n * Removes a value from the current context store by symbol key.\n *\n * @param {symbol} key - The symbol key to delete.\n * @returns {boolean} True if the key was deleted, false if the key wasn't found or no active context.\n * @throws {Error} If called outside an active context.\n */\n static delete(key: symbol): boolean {\n const store = this.storage.getStore();\n if (!store) {\n throw new Error(\n `Failed to delete ${String(key)}: AsyncLocalStorage store is not initialized.`,\n );\n }\n return delete store[key];\n }\n\n /**\n * Updates multiple values in the current context store at once.\n *\n * @param {Partial<Record<symbol, unknown>>} values - Object containing symbol keys and values to update.\n * @throws {Error} If called outside an active context.\n */\n static patch(values: Partial<Record<symbol, unknown>>): void {\n const store = this.storage.getStore();\n if (!store) {\n throw new Error(\n \"Failed to patch: AsyncLocalStorage store is not initialized.\",\n );\n }\n Object.getOwnPropertySymbols(values).forEach((key) => {\n store[key] = values[key];\n });\n }\n /**\n * Executes a callback with a temporary store value that only exists during execution.\n * Original store is restored after callback completes.\n *\n * @typeParam T - The callback's return type.\n * @param {symbol} key - The symbol key to temporarily set.\n * @param {unknown} value - The temporary value.\n * @param {() => T} callback - The function to execute with the temporary value.\n * @returns {T} The result of the callback function.\n * @throws {Error} If called outside an active context.\n */\n static withValue<T>(key: symbol, value: unknown, callback: () => T): T {\n const store = this.storage.getStore();\n if (!store) {\n throw new Error(\n `Failed to set temporary value: AsyncLocalStorage store is not initialized.`,\n );\n }\n\n // Save original value\n const hasOriginal = key in store;\n const originalValue = store[key];\n\n // Set temporary value\n store[key] = value;\n\n try {\n // Run callback\n return callback();\n } finally {\n // Restore original value\n if (hasOriginal) {\n store[key] = originalValue;\n } else {\n delete store[key];\n }\n }\n }\n\n /**\n * Creates a new context that inherits values from the current context.\n *\n * @typeParam T - The callback's return type.\n * @param {Partial<Record<symbol, unknown>>} newValues - New values to add to or override in the context.\n * @param {() => T} callback - The function to execute in the new context.\n * @returns {T} The result of the callback function.\n */\n static extend<T>(\n newValues: Partial<Record<symbol, unknown>>,\n callback: () => T,\n ): T {\n const currentStore = this.storage.getStore() || {};\n\n // Create new store with current values plus new ones\n const newStore: Store = { ...currentStore };\n\n // Add new values\n Object.getOwnPropertySymbols(newValues).forEach((key) => {\n newStore[key] = newValues[key];\n });\n\n // Run with extended store\n return this.storage.run(newStore, callback);\n }\n\n /**\n * Creates Express middleware that initializes a context for each request.\n *\n * @param {(req: any) => Partial<Record<symbol, unknown>>} initialValuesFactory - Function that returns initial context values.\n * @returns Express middleware function.\n */\n static createExpressMiddleware(\n initialValuesFactory: (\n req: any,\n ) => Partial<Record<symbol, unknown>> = () => ({}),\n ) {\n return (req: any, res: any, next: any) => {\n const initialValues = initialValuesFactory(req);\n ContextStore.run(initialValues as Store, next);\n };\n }\n}\n\n/**\n * Type-safe wrapper for accessing and modifying context values with specific types.\n *\n * @typeParam T - The value type.\n */\nexport class TypedContextKey<T> {\n /**\n * Creates a new typed context key.\n *\n * @param symbol - The unique symbol for this key\n * @param defaultValue - Optional default value if key is not found\n */\n constructor(\n private symbol: symbol,\n private defaultValue?: T,\n ) {}\n\n /**\n * Gets the current value for this key.\n *\n * @returns The value or defaultValue if not found\n */\n get(): T | undefined {\n const value = ContextStore.get<T>(this.symbol);\n return value !== undefined ? value : this.defaultValue;\n }\n\n /**\n * Sets the value for this key.\n *\n * @param value The value to set\n */\n set(value: T): void {\n ContextStore.set<T>(this.symbol, value);\n }\n\n /**\n * Checks if this key exists in the context.\n *\n * @returns True if the key exists\n */\n exists(): boolean {\n return ContextStore.has(this.symbol);\n }\n\n /**\n * Deletes this key from the context.\n *\n * @returns True if the key was deleted\n */\n delete(): boolean {\n return ContextStore.delete(this.symbol);\n }\n}\n"]}
1
+ {"version":3,"file":"context-store.utils.js","sourceRoot":"","sources":["../../../src/utils/context-store.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from 'async_hooks';\n\n/**\n * Type representing the store object used in AsyncLocalStorage.\n * Keys must be unique symbols to ensure isolation and prevent collisions.\n */\nexport interface Store {\n [key: symbol]: unknown;\n}\n\n/**\n * Predefined symbols used as keys in AsyncLocalStorage.\n * Add new symbols here to avoid duplication.\n */\nexport const StoreKeys = {\n LOGGER: Symbol('logger'),\n REQUEST_ID: Symbol('requestId'),\n USER_ID: Symbol('userId'),\n TENANT_ID: Symbol('tenantId'),\n TRACE_ID: Symbol('traceId'),\n CORRELATION_ID: Symbol('correlationId')\n};\n\n/**\n * Retrieves the current request ID from the async context, if available.\n *\n * @returns {string | undefined} The request ID string or undefined if not present in the current context.\n */\nexport function getRequestId(): string | undefined {\n return ContextStore.get<string>(StoreKeys.REQUEST_ID);\n}\n\n/**\n * Type-safe getter for common context values.\n *\n * @param key The store key symbol\n * @returns The typed value from the store\n */\nexport function getFromContext<T>(key: symbol): T | undefined {\n return ContextStore.get<T>(key);\n}\n\n/**\n * ContextStore manages per-request scoped context using AsyncLocalStorage.\n * It allows storing and retrieving data across async calls (e.g., request ID, logger).\n *\n * Example (Express middleware):\n * ```\n * // Middleware to initialize context and logger\n * app.use((req, res, next) => {\n * const requestId = req.headers[\"x-request-id\"]?.toString() || crypto.randomUUID();\n * ContextStore.run({ [StoreKeys.REQUEST_ID]: requestId }, () => {\n * ContextStore.set(StoreKeys.LOGGER, getLogger().child({ reqId: requestId }));\n * next();\n * });\n * });\n * ```\n */\nexport class ContextStore {\n /**\n * The underlying AsyncLocalStorage instance for context.\n * @private\n */\n private static readonly storage = new AsyncLocalStorage<Store>();\n\n /**\n * Returns the raw AsyncLocalStorage instance for advanced access.\n *\n * @returns {AsyncLocalStorage<Store>} The AsyncLocalStorage instance.\n */\n static getInstance(): AsyncLocalStorage<Store> {\n return this.storage;\n }\n\n /**\n * Retrieves a value from the async context store by symbol key.\n *\n * @typeParam T - The expected return type of the value.\n * @param {symbol} key - Unique symbol used as the store key.\n * @returns {T | undefined} The value found (typed) or undefined if not present.\n */\n static get<T>(key: symbol): T | undefined {\n const store = this.storage.getStore();\n return store?.[key] as T | undefined;\n }\n\n /**\n * Sets a value in the current context store by symbol key.\n *\n * @typeParam T - The value type to set.\n * @param {symbol} key - Unique symbol key.\n * @param {T} value - Value to set in context.\n * @throws {Error} If called outside an active context (not within a .run call or in the wrong async boundaries).\n */\n static set<T>(key: symbol, value: T): void {\n const store = this.storage.getStore();\n if (!store) {\n throw new Error(`Failed to set ${String(key)}: AsyncLocalStorage store is not initialized.`);\n }\n store[key] = value;\n }\n\n /**\n * Retrieves the entire context store object for the current async context.\n *\n * @returns {Store | undefined} The current store object or undefined if called outside a context.\n */\n static getAll(): Store | undefined {\n return this.storage.getStore();\n }\n\n /**\n * Initializes a new async context and executes a callback within it.\n * This must be called at the beginning of a request or logical async flow.\n *\n * @typeParam T - The callback's return type.\n * @param {Store} store - The initial key-value store object.\n * @param {() => T} callback - The function to run within the new context.\n * @returns {T} The result of the callback function.\n */\n static run<T>(store: Store, callback: () => T): T {\n return this.storage.run(store, callback);\n }\n\n /**\n * Checks if a key exists in the current context store.\n *\n * @param {symbol} key - The symbol key to check.\n * @returns {boolean} True if the key exists, false otherwise.\n */\n static has(key: symbol): boolean {\n const store = this.storage.getStore();\n return store !== undefined && key in store;\n }\n\n /**\n * Removes a value from the current context store by symbol key.\n *\n * @param {symbol} key - The symbol key to delete.\n * @returns {boolean} True if the key was deleted, false if the key wasn't found or no active context.\n * @throws {Error} If called outside an active context.\n */\n static delete(key: symbol): boolean {\n const store = this.storage.getStore();\n if (!store) {\n throw new Error(`Failed to delete ${String(key)}: AsyncLocalStorage store is not initialized.`);\n }\n return delete store[key];\n }\n\n /**\n * Updates multiple values in the current context store at once.\n *\n * @param {Partial<Record<symbol, unknown>>} values - Object containing symbol keys and values to update.\n * @throws {Error} If called outside an active context.\n */\n static patch(values: Partial<Record<symbol, unknown>>): void {\n const store = this.storage.getStore();\n if (!store) {\n throw new Error('Failed to patch: AsyncLocalStorage store is not initialized.');\n }\n Object.getOwnPropertySymbols(values).forEach(key => {\n store[key] = values[key];\n });\n }\n /**\n * Executes a callback with a temporary store value that only exists during execution.\n * Original store is restored after callback completes.\n *\n * @typeParam T - The callback's return type.\n * @param {symbol} key - The symbol key to temporarily set.\n * @param {unknown} value - The temporary value.\n * @param {() => T} callback - The function to execute with the temporary value.\n * @returns {T} The result of the callback function.\n * @throws {Error} If called outside an active context.\n */\n static withValue<T>(key: symbol, value: unknown, callback: () => T): T {\n const store = this.storage.getStore();\n if (!store) {\n throw new Error(`Failed to set temporary value: AsyncLocalStorage store is not initialized.`);\n }\n\n // Save original value\n const hasOriginal = key in store;\n const originalValue = store[key];\n\n // Set temporary value\n store[key] = value;\n\n try {\n // Run callback\n return callback();\n } finally {\n // Restore original value\n if (hasOriginal) {\n store[key] = originalValue;\n } else {\n delete store[key];\n }\n }\n }\n\n /**\n * Creates a new context that inherits values from the current context.\n *\n * @typeParam T - The callback's return type.\n * @param {Partial<Record<symbol, unknown>>} newValues - New values to add to or override in the context.\n * @param {() => T} callback - The function to execute in the new context.\n * @returns {T} The result of the callback function.\n */\n static extend<T>(newValues: Partial<Record<symbol, unknown>>, callback: () => T): T {\n const currentStore = this.storage.getStore() || {};\n\n // Create new store with current values plus new ones\n const newStore: Store = { ...currentStore };\n\n // Add new values\n Object.getOwnPropertySymbols(newValues).forEach(key => {\n newStore[key] = newValues[key];\n });\n\n // Run with extended store\n return this.storage.run(newStore, callback);\n }\n\n /**\n * Creates Express middleware that initializes a context for each request.\n *\n * @param {(req: any) => Partial<Record<symbol, unknown>>} initialValuesFactory - Function that returns initial context values.\n * @returns Express middleware function.\n */\n static createExpressMiddleware(initialValuesFactory: (req: any) => Partial<Record<symbol, unknown>> = () => ({})) {\n return (req: any, res: any, next: any) => {\n const initialValues = initialValuesFactory(req);\n ContextStore.run(initialValues as Store, next);\n };\n }\n}\n\n/**\n * Type-safe wrapper for accessing and modifying context values with specific types.\n *\n * @typeParam T - The value type.\n */\nexport class TypedContextKey<T> {\n /**\n * Creates a new typed context key.\n *\n * @param symbol - The unique symbol for this key\n * @param defaultValue - Optional default value if key is not found\n */\n constructor(\n private symbol: symbol,\n private defaultValue?: T\n ) {}\n\n /**\n * Gets the current value for this key.\n *\n * @returns The value or defaultValue if not found\n */\n get(): T | undefined {\n const value = ContextStore.get<T>(this.symbol);\n return value !== undefined ? value : this.defaultValue;\n }\n\n /**\n * Sets the value for this key.\n *\n * @param value The value to set\n */\n set(value: T): void {\n ContextStore.set<T>(this.symbol, value);\n }\n\n /**\n * Checks if this key exists in the context.\n *\n * @returns True if the key exists\n */\n exists(): boolean {\n return ContextStore.has(this.symbol);\n }\n\n /**\n * Deletes this key from the context.\n *\n * @returns True if the key was deleted\n */\n delete(): boolean {\n return ContextStore.delete(this.symbol);\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { BinaryToTextEncoding, CipherGCMTypes } from "crypto";
2
- export type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "utf-16le" | "ucs2" | "ucs-2" | "base64" | "base64url" | "latin1" | "binary" | "hex";
1
+ import { BinaryToTextEncoding, CipherGCMTypes } from 'crypto';
2
+ export type BufferEncoding = 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'utf-16le' | 'ucs2' | 'ucs-2' | 'base64' | 'base64url' | 'latin1' | 'binary' | 'hex';
3
3
  /**
4
4
  * Generates an HMAC digest using the specified algorithm and secret key.
5
5
  *
@@ -1,5 +1,5 @@
1
- import { createHmac, createHash, randomUUID, randomBytes, createCipheriv, createDecipheriv, scrypt, timingSafeEqual, } from "crypto";
2
- import { promisify } from "util";
1
+ import { createHmac, createHash, randomUUID, randomBytes, createCipheriv, createDecipheriv, scrypt, timingSafeEqual } from 'crypto';
2
+ import { promisify } from 'util';
3
3
  /**
4
4
  * Generates an HMAC digest using the specified algorithm and secret key.
5
5
  *
@@ -9,7 +9,7 @@ import { promisify } from "util";
9
9
  * @param {BinaryToTextEncoding} [encoding='hex'] - Output encoding ('hex', 'base64', etc).
10
10
  * @returns {string} HMAC digest as a string.
11
11
  */
12
- export function hmac(algorithm, input, secret, encoding = "hex") {
12
+ export function hmac(algorithm, input, secret, encoding = 'hex') {
13
13
  return createHmac(algorithm, secret).update(input).digest(encoding);
14
14
  }
15
15
  /**
@@ -20,7 +20,7 @@ export function hmac(algorithm, input, secret, encoding = "hex") {
20
20
  * @param {BinaryToTextEncoding} [encoding='hex'] - Output encoding ('hex', 'base64', etc).
21
21
  * @returns {string} Hash digest as a string.
22
22
  */
23
- export function hash(algorithm, input, encoding = "hex") {
23
+ export function hash(algorithm, input, encoding = 'hex') {
24
24
  return createHash(algorithm).update(input).digest(encoding);
25
25
  }
26
26
  /**
@@ -31,7 +31,7 @@ export function hash(algorithm, input, encoding = "hex") {
31
31
  * @returns {string} SHA-256 HMAC digest as a string.
32
32
  */
33
33
  export function sha256Hmac(input, secret) {
34
- return hmac("sha256", input, secret);
34
+ return hmac('sha256', input, secret);
35
35
  }
36
36
  /**
37
37
  * Generates a SHA1 hash digest.
@@ -40,8 +40,8 @@ export function sha256Hmac(input, secret) {
40
40
  * @param {BinaryToTextEncoding} [encoding='hex'] - Output encoding.
41
41
  * @returns {string} SHA-1 hash as a string.
42
42
  */
43
- export function sha1(input, encoding = "hex") {
44
- return hash("sha1", input, encoding);
43
+ export function sha1(input, encoding = 'hex') {
44
+ return hash('sha1', input, encoding);
45
45
  }
46
46
  /**
47
47
  * Generates a SHA256 hash digest.
@@ -50,8 +50,8 @@ export function sha1(input, encoding = "hex") {
50
50
  * @param {BinaryToTextEncoding} [encoding='hex'] - Output encoding.
51
51
  * @returns {string} SHA-256 hash as a string.
52
52
  */
53
- export function sha256(input, encoding = "hex") {
54
- return hash("sha256", input, encoding);
53
+ export function sha256(input, encoding = 'hex') {
54
+ return hash('sha256', input, encoding);
55
55
  }
56
56
  /**
57
57
  * Generates an MD5 hash digest.
@@ -60,7 +60,7 @@ export function sha256(input, encoding = "hex") {
60
60
  * @returns {string} MD5 hash as a string.
61
61
  */
62
62
  export function md5(input) {
63
- return hash("md5", input);
63
+ return hash('md5', input);
64
64
  }
65
65
  /**
66
66
  * Generates a cryptographically strong random string by hashing a random UUID with SHA-256.
@@ -86,7 +86,7 @@ export function generateRandomBytes(byteLength = 32) {
86
86
  * @param {BinaryToTextEncoding} [encoding='hex'] - Output encoding.
87
87
  * @returns {string} Random string in specified encoding.
88
88
  */
89
- export function generateRandomBytesAsString(byteLength = 32, encoding = "hex") {
89
+ export function generateRandomBytesAsString(byteLength = 32, encoding = 'hex') {
90
90
  return randomBytes(byteLength).toString(encoding);
91
91
  }
92
92
  /**
@@ -96,10 +96,10 @@ export function generateRandomBytesAsString(byteLength = 32, encoding = "hex") {
96
96
  * @param {number} [byteLength=24] - Number of random bytes to generate.
97
97
  * @returns {string} Formatted API key.
98
98
  */
99
- export function generateApiKey(prefix = "", byteLength = 24) {
100
- const randomString = generateRandomBytesAsString(byteLength, "base64");
99
+ export function generateApiKey(prefix = '', byteLength = 24) {
100
+ const randomString = generateRandomBytesAsString(byteLength, 'base64');
101
101
  const key = randomString
102
- .replace(/[+/=]/g, "") // Remove non-URL-safe characters
102
+ .replace(/[+/=]/g, '') // Remove non-URL-safe characters
103
103
  .substring(0, 32); // Limit length
104
104
  return prefix ? `${prefix}_${key}` : key;
105
105
  }
@@ -111,7 +111,7 @@ export function generateApiKey(prefix = "", byteLength = 24) {
111
111
  * @returns {boolean} True if values are equal
112
112
  */
113
113
  export function safeCompare(a, b) {
114
- if (typeof a === "string" && typeof b === "string") {
114
+ if (typeof a === 'string' && typeof b === 'string') {
115
115
  // Convert strings to buffers
116
116
  const bufA = Buffer.from(a);
117
117
  const bufB = Buffer.from(b);
@@ -120,14 +120,13 @@ export function safeCompare(a, b) {
120
120
  return false;
121
121
  return timingSafeEqual(bufA, bufB);
122
122
  }
123
- else if ((a instanceof Buffer || a instanceof Uint8Array) &&
124
- (b instanceof Buffer || b instanceof Uint8Array)) {
123
+ else if ((a instanceof Buffer || a instanceof Uint8Array) && (b instanceof Buffer || b instanceof Uint8Array)) {
125
124
  // Compare lengths first
126
125
  if (a.length !== b.length)
127
126
  return false;
128
127
  return timingSafeEqual(a instanceof Buffer ? a : Buffer.from(a), b instanceof Buffer ? b : Buffer.from(b));
129
128
  }
130
- throw new Error("Cannot compare: inputs must be strings, Buffers, or Uint8Arrays");
129
+ throw new Error('Cannot compare: inputs must be strings, Buffers, or Uint8Arrays');
131
130
  }
132
131
  // Promisified version of scrypt for key derivation
133
132
  const scryptAsync = promisify(scrypt);
@@ -140,36 +139,32 @@ const scryptAsync = promisify(scrypt);
140
139
  * @returns {Promise<EncryptionResult>} Encrypted data with metadata
141
140
  */
142
141
  export async function encrypt(data, key, options = {}) {
143
- const algorithm = options.algorithm || "aes-256-gcm";
144
- const inputEncoding = options.inputEncoding || "utf8";
145
- const outputEncoding = options.outputEncoding || "hex";
142
+ const algorithm = options.algorithm || 'aes-256-gcm';
143
+ const inputEncoding = options.inputEncoding || 'utf8';
144
+ const outputEncoding = options.outputEncoding || 'hex';
146
145
  // Generate a random IV
147
146
  const iv = randomBytes(16);
148
147
  // Derive key using scrypt if key is a string (passphrase)
149
- const derivedKey = typeof key === "string" ? await scryptAsync(key, iv.slice(0, 8), 32) : key;
148
+ const derivedKey = typeof key === 'string' ? await scryptAsync(key, iv.slice(0, 8), 32) : key;
150
149
  // Create cipher
151
150
  const cipher = createCipheriv(algorithm, derivedKey, iv);
152
151
  // Encrypt the data
153
152
  let ciphertext;
154
- if (typeof data === "string") {
153
+ if (typeof data === 'string') {
155
154
  ciphertext = cipher.update(data, inputEncoding, outputEncoding);
156
155
  ciphertext += cipher.final(outputEncoding);
157
156
  }
158
157
  else {
159
158
  const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
160
- ciphertext = outputEncoding
161
- ? encrypted.toString(outputEncoding)
162
- : encrypted;
159
+ ciphertext = outputEncoding ? encrypted.toString(outputEncoding) : encrypted;
163
160
  }
164
161
  // Get authentication tag if using GCM mode
165
- const authTag = algorithm.includes("gcm")
166
- ? cipher.getAuthTag()
167
- : undefined;
162
+ const authTag = algorithm.includes('gcm') ? cipher.getAuthTag() : undefined;
168
163
  return {
169
164
  ciphertext,
170
165
  iv,
171
166
  authTag,
172
- algorithm,
167
+ algorithm
173
168
  };
174
169
  }
175
170
  /**
@@ -181,30 +176,25 @@ export async function encrypt(data, key, options = {}) {
181
176
  * @returns {Promise<string | Buffer>} Decrypted data
182
177
  */
183
178
  export async function decrypt(encryptedData, key, options = {}) {
184
- const algorithm = options.algorithm || encryptedData.algorithm || "aes-256-gcm";
185
- const inputEncoding = options.inputEncoding || "hex";
186
- const outputEncoding = options.outputEncoding || "utf8";
179
+ const algorithm = options.algorithm || encryptedData.algorithm || 'aes-256-gcm';
180
+ const inputEncoding = options.inputEncoding || 'hex';
181
+ const outputEncoding = options.outputEncoding || 'utf8';
187
182
  // Derive key using scrypt if key is a string (passphrase)
188
- const derivedKey = typeof key === "string"
189
- ? await scryptAsync(key, encryptedData.iv.slice(0, 8), 32)
190
- : key;
183
+ const derivedKey = typeof key === 'string' ? await scryptAsync(key, encryptedData.iv.slice(0, 8), 32) : key;
191
184
  // Create decipher
192
185
  const decipher = createDecipheriv(algorithm, derivedKey, encryptedData.iv);
193
186
  // Set auth tag if using GCM mode
194
- if (encryptedData.authTag && algorithm.includes("gcm")) {
187
+ if (encryptedData.authTag && algorithm.includes('gcm')) {
195
188
  decipher.setAuthTag(encryptedData.authTag);
196
189
  }
197
190
  // Decrypt the data
198
191
  let decrypted;
199
- if (typeof encryptedData.ciphertext === "string") {
192
+ if (typeof encryptedData.ciphertext === 'string') {
200
193
  decrypted = decipher.update(encryptedData.ciphertext, inputEncoding, outputEncoding);
201
194
  decrypted += decipher.final(outputEncoding);
202
195
  }
203
196
  else {
204
- const result = Buffer.concat([
205
- decipher.update(encryptedData.ciphertext),
206
- decipher.final(),
207
- ]);
197
+ const result = Buffer.concat([decipher.update(encryptedData.ciphertext), decipher.final()]);
208
198
  decrypted = outputEncoding ? result.toString(outputEncoding) : result;
209
199
  }
210
200
  return decrypted;
@@ -223,9 +213,9 @@ export function createSignedToken(payload, secret, expiresInSeconds = 3600) {
223
213
  // Convert to string
224
214
  const payloadStr = JSON.stringify(tokenPayload);
225
215
  // Base64 encode the payload
226
- const base64Payload = Buffer.from(payloadStr).toString("base64url");
216
+ const base64Payload = Buffer.from(payloadStr).toString('base64url');
227
217
  // Create signature
228
- const signature = hmac("sha256", base64Payload, secret, "base64url");
218
+ const signature = hmac('sha256', base64Payload, secret, 'base64url');
229
219
  // Combine payload and signature
230
220
  return `${base64Payload}.${signature}`;
231
221
  }
@@ -239,15 +229,15 @@ export function createSignedToken(payload, secret, expiresInSeconds = 3600) {
239
229
  export function verifySignedToken(token, secret) {
240
230
  try {
241
231
  // Split token into parts
242
- const [payloadB64, signature] = token.split(".");
232
+ const [payloadB64, signature] = token.split('.');
243
233
  if (!payloadB64 || !signature)
244
234
  return null;
245
235
  // Verify signature
246
- const expectedSignature = hmac("sha256", payloadB64, secret, "base64url");
236
+ const expectedSignature = hmac('sha256', payloadB64, secret, 'base64url');
247
237
  if (!safeCompare(signature, expectedSignature))
248
238
  return null;
249
239
  // Decode payload
250
- const payloadStr = Buffer.from(payloadB64, "base64url").toString("utf8");
240
+ const payloadStr = Buffer.from(payloadB64, 'base64url').toString('utf8');
251
241
  const payload = JSON.parse(payloadStr);
252
242
  // Check expiration
253
243
  if (payload.exp && payload.exp < Math.floor(Date.now() / 1000)) {