@autofleet/node-common 4.2.22 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index-HHW_DgYK.d.cts +26 -0
- package/dist/index-Kw5jk3PY.d.ts +26 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -33
- package/dist/index.d.ts +2 -33
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/promise-utils/index.cjs +2 -0
- package/dist/promise-utils/index.cjs.map +1 -0
- package/dist/promise-utils/index.d.cts +12 -0
- package/dist/promise-utils/index.d.ts +12 -0
- package/dist/promise-utils/index.js +2 -0
- package/dist/promise-utils/index.js.map +1 -0
- package/dist/uuid-utils/index.cjs +1 -0
- package/dist/uuid-utils/index.d.cts +2 -0
- package/dist/uuid-utils/index.d.ts +2 -0
- package/dist/uuid-utils/index.js +1 -0
- package/dist/uuid-utils-DaVfcYml.cjs +2 -0
- package/dist/uuid-utils-DaVfcYml.cjs.map +1 -0
- package/dist/uuid-utils-XgVlI8eH.js +2 -0
- package/dist/uuid-utils-XgVlI8eH.js.map +1 -0
- package/package.json +29 -7
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/uuid-utils/string-to-uuid.d.ts
|
|
2
|
+
interface Args {
|
|
3
|
+
/** The input string to convert to UUID */
|
|
4
|
+
input: string;
|
|
5
|
+
/** The namespace for UUIDv5 generation. Can be arbitrary string. */
|
|
6
|
+
namespace: string;
|
|
7
|
+
/** Whether to normalize the input string. @default true */
|
|
8
|
+
shouldNormalize?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** Convert a string to a consistent UUIDv5 using a namespace */
|
|
11
|
+
declare function stringToConsistentUuid(params: Args): string;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/uuid-utils/uuidv5.d.ts
|
|
14
|
+
declare const NAMESPACE: {
|
|
15
|
+
readonly DNS: "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
|
|
16
|
+
readonly URL: "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
|
|
17
|
+
readonly OID: "6ba7b812-9dad-11d1-80b4-00c04fd430c8";
|
|
18
|
+
readonly X500: "6ba7b814-9dad-11d1-80b4-00c04fd430c8";
|
|
19
|
+
};
|
|
20
|
+
/** One-off generator: name + namespace (both strings) -> UUID v5 string */
|
|
21
|
+
declare function v5(name: string, namespace: string | keyof typeof NAMESPACE): string;
|
|
22
|
+
/** Hot path: bind namespace once; returns (name: string) => uuid string */
|
|
23
|
+
declare function createV5(namespace: string): (name: string) => string;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { stringToConsistentUuid as i, createV5 as n, v5 as r, NAMESPACE as t };
|
|
26
|
+
//# sourceMappingURL=index-HHW_DgYK.d.cts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/uuid-utils/string-to-uuid.d.ts
|
|
2
|
+
interface Args {
|
|
3
|
+
/** The input string to convert to UUID */
|
|
4
|
+
input: string;
|
|
5
|
+
/** The namespace for UUIDv5 generation. Can be arbitrary string. */
|
|
6
|
+
namespace: string;
|
|
7
|
+
/** Whether to normalize the input string. @default true */
|
|
8
|
+
shouldNormalize?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** Convert a string to a consistent UUIDv5 using a namespace */
|
|
11
|
+
declare function stringToConsistentUuid(params: Args): string;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/uuid-utils/uuidv5.d.ts
|
|
14
|
+
declare const NAMESPACE: {
|
|
15
|
+
readonly DNS: "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
|
|
16
|
+
readonly URL: "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
|
|
17
|
+
readonly OID: "6ba7b812-9dad-11d1-80b4-00c04fd430c8";
|
|
18
|
+
readonly X500: "6ba7b814-9dad-11d1-80b4-00c04fd430c8";
|
|
19
|
+
};
|
|
20
|
+
/** One-off generator: name + namespace (both strings) -> UUID v5 string */
|
|
21
|
+
declare function v5(name: string, namespace: string | keyof typeof NAMESPACE): string;
|
|
22
|
+
/** Hot path: bind namespace once; returns (name: string) => uuid string */
|
|
23
|
+
declare function createV5(namespace: string): (name: string) => string;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { stringToConsistentUuid as i, createV5 as n, v5 as r, NAMESPACE as t };
|
|
26
|
+
//# sourceMappingURL=index-Kw5jk3PY.d.ts.map
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
const e=require(`./promise-utils/index.cjs`),t=require(`./uuid-utils-DaVfcYml.cjs`);let n=require(`express`);const r=[`all`,`get`,`post`,`put`,`delete`,`patch`,`options`,`head`],i=(e,t)=>async(n,r,i)=>{try{await t(n,r,i)}catch(t){let a=t;if(e.error(`Caught rejection in route handler`,{err:t,url:n.originalUrl,method:n.method}),a.statusCode&&a.statusCode<500){r.status(400).json({error:a.message,status:`ERROR`});return}i(a)}},a=({logger:e,...t})=>{let a=(0,n.Router)({mergeParams:!0,...t});return r.forEach(e=>{let t=a[e].bind(a);a[e]=(...e)=>t(...e.map(o))}),a;function o(t){return Array.isArray(t)?t.map(o):typeof t==`function`?i(e,t):t}},o=Object.freeze({ok:`OK`,error:`ERROR`,fail:`FAIL`}),s=a;exports.AfRouter=a,exports.NAMESPACE=t.n,exports.Router=s,exports.consts=o,exports.createV5=t.r,exports.promiseMap=e.promiseMap,exports.stringToConsistentUuid=t.t,exports.v5=t.i;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["newMethodHandler: IRouterMatcher<Router>","Readable","consts: Readonly<{ ok: 'OK'; error: 'ERROR'; fail: 'FAIL'; }>","NAMESPACE: {\n readonly DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8';\n readonly URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8';\n readonly OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8';\n readonly X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8';\n}","maxSize: number","uuidv5","Router: typeof AfRouter"],"sources":["../src/router/index.ts","../src/promise-utils/index.ts","../src/consts/index.ts","../src/uuid-utils/uuidv5.ts","../../../libs/lru-cache/src/index.ts","../src/uuid-utils/string-to-uuid.ts","../src/index.ts"],"sourcesContent":["import {\n Router, type Request, type Response, type NextFunction, type Handler, type RouterOptions, type IRouterMatcher,\n} from 'express';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\n\nexport const METHODS = [\n 'all',\n 'get',\n 'post',\n 'put',\n 'delete',\n 'patch',\n 'options',\n 'head',\n] as const;\n\nconst AfEntryPoint = (logger: LoggerInstanceManager, func: (req: Request, res: Response, nextFn: NextFunction) => void | PromiseLike<void>): Handler => async (req, res, next) => {\n try {\n await func(req, res, next);\n } catch (err) {\n const e = err as Error & { statusCode?: number; };\n logger.error(e.message);\n if (e.statusCode && e.statusCode < 500) {\n res.status(400).json({ error: e.message, status: 'ERROR' });\n return;\n }\n next(e);\n }\n};\n\n/** @returns a monkey-patched express router that will handle async routes (and force a 400 status for codes <500) */\nexport const AfRouter = ({ logger, ...options }: RouterOptions & { logger: LoggerInstanceManager; }): Router => {\n const myRouter = Router({ mergeParams: true, ...options });\n METHODS.forEach((method) => {\n const internalMethod = myRouter[method].bind(myRouter);\n const newMethodHandler: IRouterMatcher<Router> = (...args: [...unknown[]]) => internalMethod(...args.map(argMapper) as [string]);\n myRouter[method] = newMethodHandler;\n });\n return myRouter;\n\n function argMapper(args: unknown): unknown {\n if (Array.isArray(args)) return args.map(argMapper);\n return typeof args === 'function' ? AfEntryPoint(logger, args as Handler) : args;\n }\n};\n","import { Readable } from 'node:stream';\n\nexport async function promiseMap<T, U>(\n iterable: T[] | Iterable<T>,\n handler: (item: T, options?: { signal?: AbortSignal; }) => PromiseLike<U>,\n { concurrency, signal }: Parameters<Readable['map']>[1] = {},\n): Promise<U[]> {\n if (!concurrency) {\n return Promise.all(Array.from(iterable, item => handler(item, signal ? { signal } : undefined)));\n }\n return Readable.from(iterable).map(handler, { concurrency, signal }).toArray();\n}\n","export const consts: Readonly<{ ok: 'OK'; error: 'ERROR'; fail: 'FAIL'; }> = Object.freeze({\n ok: 'OK',\n error: 'ERROR',\n fail: 'FAIL',\n});\n","import { createHash } from 'node:crypto';\n\n// RFC 4122 well-known namespaces (as strings)\nexport const NAMESPACE: {\n readonly DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8';\n readonly URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8';\n readonly OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8';\n readonly X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8';\n} = Object.freeze({\n DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',\n URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8',\n OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8',\n X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8',\n});\n\nfunction parseNs(nsStr: unknown): Buffer {\n if (typeof nsStr !== 'string') throw new TypeError('namespace must be a UUID string');\n\n // Check proper UUID format first (8-4-4-4-12 with hyphens)\n if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(nsStr)) {\n throw new TypeError('invalid namespace UUID');\n }\n\n const s = nsStr.replace(/-/g, '').toLowerCase();\n const out = Buffer.allocUnsafe(16);\n for (let i = 0; i < 16; i++) out[i] = parseInt(s.slice(i * 2, i * 2 + 2), 16);\n return out; // 16 bytes\n}\n\nfunction formatHexToUuid(hex32: string): string {\n // hex32 is 32 hex chars\n return `${hex32.slice(0, 8)}-${hex32.slice(8, 12)}-${hex32.slice(12, 16)}-${hex32.slice(16, 20)}-${hex32.slice(20)}`;\n}\n\nfunction v5WithParsed(name: string, nsBytes: Buffer): string {\n if (typeof name !== 'string') throw new TypeError('name must be a string');\n // sha1(namespace || name)\n const d = createHash('sha1').update(nsBytes).update(name, 'utf8').digest(); // 20 bytes\n // set version & variant on first 16 bytes (no extra allocs)\n d[6] = (d[6] & 0x0f) | 0x50; // version 5\n d[8] = (d[8] & 0x3f) | 0x80; // RFC 4122 variant\n const hex = d.subarray(0, 16).toString('hex');\n return formatHexToUuid(hex);\n}\n\n/** One-off generator: name + namespace (both strings) -> UUID v5 string */\nexport function v5(name: string, namespace: string | keyof typeof NAMESPACE): string {\n const nsStr = (namespace in NAMESPACE) ? NAMESPACE[namespace as keyof typeof NAMESPACE] : namespace;\n return v5WithParsed(name, parseNs(nsStr));\n}\n\n/** Hot path: bind namespace once; returns (name: string) => uuid string */\nexport function createV5(namespace: string): (name: string) => string {\n const nsStr = (namespace in NAMESPACE) ? NAMESPACE[namespace as keyof typeof NAMESPACE] : namespace;\n const nsBytes = parseNs(nsStr);\n return (name: string): string => v5WithParsed(name, nsBytes);\n}\n","export class LruCache<K, V> {\n private readonly cache: Map<K, V> = new Map<K, V>();\n\n constructor(private readonly maxSize: number) {\n if (maxSize <= 0) {\n throw new Error('maxSize must be greater than 0');\n }\n }\n\n public get(key: K): V | undefined {\n if (!this.cache.has(key)) {\n return undefined;\n }\n\n const value = this.cache.get(key)!;\n // Refresh key\n this.cache.delete(key);\n this.cache.set(key, value);\n return value;\n }\n\n public set(key: K, value: V): void {\n if (this.cache.has(key)) {\n this.cache.delete(key);\n } else if (this.cache.size >= this.maxSize) {\n // Delete least recently used item\n const [oldestKey] = this.cache.keys();\n this.cache.delete(oldestKey);\n }\n this.cache.set(key, value);\n }\n\n public has(key: K): boolean {\n return this.cache.has(key);\n }\n\n public delete(key: K): boolean {\n return this.cache.delete(key);\n }\n\n public clear(): void {\n this.cache.clear();\n }\n\n public size(): number {\n return this.cache.size;\n }\n\n public keys(): MapIterator<K> {\n return this.cache.keys();\n }\n\n public values(): MapIterator<V> {\n return this.cache.values();\n }\n}\n","import { v5 as uuidv5, NAMESPACE, createV5 } from './uuidv5';\nimport { LruCache } from '@autofleet/lru-cache';\n\nconst namespaceGenerators = new LruCache<string, (name: string) => string>(5);\n\nfunction normalize(input: string): string {\n return input.trim().toLowerCase().normalize('NFC');\n}\n\ninterface Args {\n /** The input string to convert to UUID */\n input: string;\n /** The namespace for UUIDv5 generation. Can be arbitrary string. */\n namespace: string;\n /** Whether to normalize the input string. @default true */\n shouldNormalize?: boolean;\n}\n\n/** Convert a string to a consistent UUIDv5 using a namespace */\nexport function stringToConsistentUuid(params: Args): string {\n const { input, namespace, shouldNormalize = true } = params;\n let generator = namespaceGenerators.get(namespace);\n\n if (!generator) {\n const namespaceUUID = uuidv5(namespace, NAMESPACE.DNS); // Convert arbitrary string namespace to UUIDv5 using DNS namespace\n generator = createV5(namespaceUUID);\n namespaceGenerators.set(namespace, generator);\n }\n\n return generator(shouldNormalize ? normalize(input) : input);\n}\n","import { AfRouter } from './router';\n\nexport { AfRouter } from './router';\nexport { promiseMap } from './promise-utils';\n\nexport { consts } from './consts';\n\nexport { stringToConsistentUuid } from './uuid-utils/string-to-uuid';\nexport { v5, createV5, NAMESPACE } from './uuid-utils/uuidv5';\n\nexport const Router: typeof AfRouter = AfRouter;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["newMethodHandler: IRouterMatcher<Router>","consts: Readonly<{ ok: 'OK'; error: 'ERROR'; fail: 'FAIL'; }>","Router: typeof AfRouter"],"sources":["../src/router/index.ts","../src/consts/index.ts","../src/index.ts"],"sourcesContent":["import {\n Router, type Request, type Response, type NextFunction, type Handler, type RouterOptions, type IRouterMatcher,\n} from 'express';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\n\nexport const METHODS = [\n 'all',\n 'get',\n 'post',\n 'put',\n 'delete',\n 'patch',\n 'options',\n 'head',\n] as const;\n\nconst AfEntryPoint = (logger: LoggerInstanceManager, func: (req: Request, res: Response, nextFn: NextFunction) => void | PromiseLike<void>): Handler => async (req, res, next) => {\n try {\n await func(req, res, next);\n } catch (err) {\n const e = err as Error & { statusCode?: number; };\n logger.error('Caught rejection in route handler', { err, url: req.originalUrl, method: req.method });\n if (e.statusCode && e.statusCode < 500) {\n res.status(400).json({ error: e.message, status: 'ERROR' });\n return;\n }\n next(e);\n }\n};\n\n/** @returns a monkey-patched express router that will handle async routes (and force a 400 status for codes <500) */\nexport const AfRouter = ({ logger, ...options }: RouterOptions & { logger: LoggerInstanceManager; }): Router => {\n const myRouter = Router({ mergeParams: true, ...options });\n METHODS.forEach((method) => {\n const internalMethod = myRouter[method].bind(myRouter);\n const newMethodHandler: IRouterMatcher<Router> = (...args: [...unknown[]]) => internalMethod(...args.map(argMapper) as [string]);\n myRouter[method] = newMethodHandler;\n });\n return myRouter;\n\n function argMapper(args: unknown): unknown {\n if (Array.isArray(args)) return args.map(argMapper);\n return typeof args === 'function' ? AfEntryPoint(logger, args as Handler) : args;\n }\n};\n","export const consts: Readonly<{ ok: 'OK'; error: 'ERROR'; fail: 'FAIL'; }> = Object.freeze({\n ok: 'OK',\n error: 'ERROR',\n fail: 'FAIL',\n});\n","import { AfRouter } from './router';\n\nexport { AfRouter } from './router';\nexport { promiseMap } from './promise-utils';\n\nexport { consts } from './consts';\n\nexport { stringToConsistentUuid, v5, createV5, NAMESPACE } from './uuid-utils';\n\nexport const Router: typeof AfRouter = AfRouter;\n"],"mappings":"6GAKA,MAAa,EAAU,CACrB,MACA,MACA,OACA,MACA,SACA,QACA,UACA,OACD,CAEK,GAAgB,EAA+B,IAAmG,MAAO,EAAK,EAAK,IAAS,CAChL,GAAI,CACF,MAAM,EAAK,EAAK,EAAK,EAAK,OACnB,EAAK,CACZ,IAAM,EAAI,EAEV,GADA,EAAO,MAAM,oCAAqC,CAAE,MAAK,IAAK,EAAI,YAAa,OAAQ,EAAI,OAAQ,CAAC,CAChG,EAAE,YAAc,EAAE,WAAa,IAAK,CACtC,EAAI,OAAO,IAAI,CAAC,KAAK,CAAE,MAAO,EAAE,QAAS,OAAQ,QAAS,CAAC,CAC3D,OAEF,EAAK,EAAE,GAKE,GAAY,CAAE,SAAQ,GAAG,KAA0E,CAC9G,IAAM,GAAA,EAAA,EAAA,QAAkB,CAAE,YAAa,GAAM,GAAG,EAAS,CAAC,CAM1D,OALA,EAAQ,QAAS,GAAW,CAC1B,IAAM,EAAiB,EAAS,GAAQ,KAAK,EAAS,CAEtD,EAAS,IADyC,GAAG,IAAyB,EAAe,GAAG,EAAK,IAAI,EAAU,CAAa,EAEhI,CACK,EAEP,SAAS,EAAU,EAAwB,CAEzC,OADI,MAAM,QAAQ,EAAK,CAAS,EAAK,IAAI,EAAU,CAC5C,OAAO,GAAS,WAAa,EAAa,EAAQ,EAAgB,CAAG,IC1CnEC,EAAgE,OAAO,OAAO,CACzF,GAAI,KACJ,MAAO,QACP,KAAM,OACP,CAAC,CCKWC,EAA0B"}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { promiseMap } from "./promise-utils/index.cjs";
|
|
2
|
+
import { i as stringToConsistentUuid, n as createV5, r as v5, t as NAMESPACE } from "./index-HHW_DgYK.cjs";
|
|
1
3
|
import { Router as Router$1, RouterOptions } from "express";
|
|
2
4
|
import { LoggerInstanceManager } from "@autofleet/logger";
|
|
3
|
-
import { Readable } from "node:stream";
|
|
4
5
|
|
|
5
6
|
//#region src/router/index.d.ts
|
|
6
7
|
/** @returns a monkey-patched express router that will handle async routes (and force a 400 status for codes <500) */
|
|
@@ -11,14 +12,6 @@ declare const AfRouter: ({
|
|
|
11
12
|
logger: LoggerInstanceManager;
|
|
12
13
|
}) => Router$1;
|
|
13
14
|
//#endregion
|
|
14
|
-
//#region src/promise-utils/index.d.ts
|
|
15
|
-
declare function promiseMap<T, U>(iterable: T[] | Iterable<T>, handler: (item: T, options?: {
|
|
16
|
-
signal?: AbortSignal;
|
|
17
|
-
}) => PromiseLike<U>, {
|
|
18
|
-
concurrency,
|
|
19
|
-
signal
|
|
20
|
-
}?: Parameters<Readable["map"]>[1]): Promise<U[]>;
|
|
21
|
-
//#endregion
|
|
22
15
|
//#region src/consts/index.d.ts
|
|
23
16
|
declare const consts: Readonly<{
|
|
24
17
|
ok: "OK";
|
|
@@ -26,30 +19,6 @@ declare const consts: Readonly<{
|
|
|
26
19
|
fail: "FAIL";
|
|
27
20
|
}>;
|
|
28
21
|
//#endregion
|
|
29
|
-
//#region src/uuid-utils/string-to-uuid.d.ts
|
|
30
|
-
interface Args {
|
|
31
|
-
/** The input string to convert to UUID */
|
|
32
|
-
input: string;
|
|
33
|
-
/** The namespace for UUIDv5 generation. Can be arbitrary string. */
|
|
34
|
-
namespace: string;
|
|
35
|
-
/** Whether to normalize the input string. @default true */
|
|
36
|
-
shouldNormalize?: boolean;
|
|
37
|
-
}
|
|
38
|
-
/** Convert a string to a consistent UUIDv5 using a namespace */
|
|
39
|
-
declare function stringToConsistentUuid(params: Args): string;
|
|
40
|
-
//#endregion
|
|
41
|
-
//#region src/uuid-utils/uuidv5.d.ts
|
|
42
|
-
declare const NAMESPACE: {
|
|
43
|
-
readonly DNS: "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
|
|
44
|
-
readonly URL: "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
|
|
45
|
-
readonly OID: "6ba7b812-9dad-11d1-80b4-00c04fd430c8";
|
|
46
|
-
readonly X500: "6ba7b814-9dad-11d1-80b4-00c04fd430c8";
|
|
47
|
-
};
|
|
48
|
-
/** One-off generator: name + namespace (both strings) -> UUID v5 string */
|
|
49
|
-
declare function v5(name: string, namespace: string | keyof typeof NAMESPACE): string;
|
|
50
|
-
/** Hot path: bind namespace once; returns (name: string) => uuid string */
|
|
51
|
-
declare function createV5(namespace: string): (name: string) => string;
|
|
52
|
-
//#endregion
|
|
53
22
|
//#region src/index.d.ts
|
|
54
23
|
declare const Router: typeof AfRouter;
|
|
55
24
|
//#endregion
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { promiseMap } from "./promise-utils/index.js";
|
|
2
|
+
import { i as stringToConsistentUuid, n as createV5, r as v5, t as NAMESPACE } from "./index-Kw5jk3PY.js";
|
|
1
3
|
import { Router as Router$1, RouterOptions } from "express";
|
|
2
|
-
import { Readable } from "node:stream";
|
|
3
4
|
import { LoggerInstanceManager } from "@autofleet/logger";
|
|
4
5
|
|
|
5
6
|
//#region src/router/index.d.ts
|
|
@@ -11,14 +12,6 @@ declare const AfRouter: ({
|
|
|
11
12
|
logger: LoggerInstanceManager;
|
|
12
13
|
}) => Router$1;
|
|
13
14
|
//#endregion
|
|
14
|
-
//#region src/promise-utils/index.d.ts
|
|
15
|
-
declare function promiseMap<T, U>(iterable: T[] | Iterable<T>, handler: (item: T, options?: {
|
|
16
|
-
signal?: AbortSignal;
|
|
17
|
-
}) => PromiseLike<U>, {
|
|
18
|
-
concurrency,
|
|
19
|
-
signal
|
|
20
|
-
}?: Parameters<Readable["map"]>[1]): Promise<U[]>;
|
|
21
|
-
//#endregion
|
|
22
15
|
//#region src/consts/index.d.ts
|
|
23
16
|
declare const consts: Readonly<{
|
|
24
17
|
ok: "OK";
|
|
@@ -26,30 +19,6 @@ declare const consts: Readonly<{
|
|
|
26
19
|
fail: "FAIL";
|
|
27
20
|
}>;
|
|
28
21
|
//#endregion
|
|
29
|
-
//#region src/uuid-utils/string-to-uuid.d.ts
|
|
30
|
-
interface Args {
|
|
31
|
-
/** The input string to convert to UUID */
|
|
32
|
-
input: string;
|
|
33
|
-
/** The namespace for UUIDv5 generation. Can be arbitrary string. */
|
|
34
|
-
namespace: string;
|
|
35
|
-
/** Whether to normalize the input string. @default true */
|
|
36
|
-
shouldNormalize?: boolean;
|
|
37
|
-
}
|
|
38
|
-
/** Convert a string to a consistent UUIDv5 using a namespace */
|
|
39
|
-
declare function stringToConsistentUuid(params: Args): string;
|
|
40
|
-
//#endregion
|
|
41
|
-
//#region src/uuid-utils/uuidv5.d.ts
|
|
42
|
-
declare const NAMESPACE: {
|
|
43
|
-
readonly DNS: "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
|
|
44
|
-
readonly URL: "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
|
|
45
|
-
readonly OID: "6ba7b812-9dad-11d1-80b4-00c04fd430c8";
|
|
46
|
-
readonly X500: "6ba7b814-9dad-11d1-80b4-00c04fd430c8";
|
|
47
|
-
};
|
|
48
|
-
/** One-off generator: name + namespace (both strings) -> UUID v5 string */
|
|
49
|
-
declare function v5(name: string, namespace: string | keyof typeof NAMESPACE): string;
|
|
50
|
-
/** Hot path: bind namespace once; returns (name: string) => uuid string */
|
|
51
|
-
declare function createV5(namespace: string): (name: string) => string;
|
|
52
|
-
//#endregion
|
|
53
22
|
//#region src/index.d.ts
|
|
54
23
|
declare const Router: typeof AfRouter;
|
|
55
24
|
//#endregion
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{promiseMap as e}from"./promise-utils/index.js";import{i as t,n,r,t as i}from"./uuid-utils-XgVlI8eH.js";import{Router as a}from"express";const o=[`all`,`get`,`post`,`put`,`delete`,`patch`,`options`,`head`],s=(e,t)=>async(n,r,i)=>{try{await t(n,r,i)}catch(t){let a=t;if(e.error(`Caught rejection in route handler`,{err:t,url:n.originalUrl,method:n.method}),a.statusCode&&a.statusCode<500){r.status(400).json({error:a.message,status:`ERROR`});return}i(a)}},c=({logger:e,...t})=>{let n=a({mergeParams:!0,...t});return o.forEach(e=>{let t=n[e].bind(n);n[e]=(...e)=>t(...e.map(r))}),n;function r(t){return Array.isArray(t)?t.map(r):typeof t==`function`?s(e,t):t}},l=Object.freeze({ok:`OK`,error:`ERROR`,fail:`FAIL`}),u=c;export{c as AfRouter,n as NAMESPACE,u as Router,l as consts,r as createV5,e as promiseMap,i as stringToConsistentUuid,t as v5};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["Router","newMethodHandler: IRouterMatcher<Router>","consts: Readonly<{ ok: 'OK'; error: 'ERROR'; fail: 'FAIL'; }>","NAMESPACE: {\n readonly DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8';\n readonly URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8';\n readonly OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8';\n readonly X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8';\n}","maxSize: number","uuidv5","Router: typeof AfRouter"],"sources":["../src/router/index.ts","../src/promise-utils/index.ts","../src/consts/index.ts","../src/uuid-utils/uuidv5.ts","../../../libs/lru-cache/src/index.ts","../src/uuid-utils/string-to-uuid.ts","../src/index.ts"],"sourcesContent":["import {\n Router, type Request, type Response, type NextFunction, type Handler, type RouterOptions, type IRouterMatcher,\n} from 'express';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\n\nexport const METHODS = [\n 'all',\n 'get',\n 'post',\n 'put',\n 'delete',\n 'patch',\n 'options',\n 'head',\n] as const;\n\nconst AfEntryPoint = (logger: LoggerInstanceManager, func: (req: Request, res: Response, nextFn: NextFunction) => void | PromiseLike<void>): Handler => async (req, res, next) => {\n try {\n await func(req, res, next);\n } catch (err) {\n const e = err as Error & { statusCode?: number; };\n logger.error(e.message);\n if (e.statusCode && e.statusCode < 500) {\n res.status(400).json({ error: e.message, status: 'ERROR' });\n return;\n }\n next(e);\n }\n};\n\n/** @returns a monkey-patched express router that will handle async routes (and force a 400 status for codes <500) */\nexport const AfRouter = ({ logger, ...options }: RouterOptions & { logger: LoggerInstanceManager; }): Router => {\n const myRouter = Router({ mergeParams: true, ...options });\n METHODS.forEach((method) => {\n const internalMethod = myRouter[method].bind(myRouter);\n const newMethodHandler: IRouterMatcher<Router> = (...args: [...unknown[]]) => internalMethod(...args.map(argMapper) as [string]);\n myRouter[method] = newMethodHandler;\n });\n return myRouter;\n\n function argMapper(args: unknown): unknown {\n if (Array.isArray(args)) return args.map(argMapper);\n return typeof args === 'function' ? AfEntryPoint(logger, args as Handler) : args;\n }\n};\n","import { Readable } from 'node:stream';\n\nexport async function promiseMap<T, U>(\n iterable: T[] | Iterable<T>,\n handler: (item: T, options?: { signal?: AbortSignal; }) => PromiseLike<U>,\n { concurrency, signal }: Parameters<Readable['map']>[1] = {},\n): Promise<U[]> {\n if (!concurrency) {\n return Promise.all(Array.from(iterable, item => handler(item, signal ? { signal } : undefined)));\n }\n return Readable.from(iterable).map(handler, { concurrency, signal }).toArray();\n}\n","export const consts: Readonly<{ ok: 'OK'; error: 'ERROR'; fail: 'FAIL'; }> = Object.freeze({\n ok: 'OK',\n error: 'ERROR',\n fail: 'FAIL',\n});\n","import { createHash } from 'node:crypto';\n\n// RFC 4122 well-known namespaces (as strings)\nexport const NAMESPACE: {\n readonly DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8';\n readonly URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8';\n readonly OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8';\n readonly X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8';\n} = Object.freeze({\n DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',\n URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8',\n OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8',\n X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8',\n});\n\nfunction parseNs(nsStr: unknown): Buffer {\n if (typeof nsStr !== 'string') throw new TypeError('namespace must be a UUID string');\n\n // Check proper UUID format first (8-4-4-4-12 with hyphens)\n if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(nsStr)) {\n throw new TypeError('invalid namespace UUID');\n }\n\n const s = nsStr.replace(/-/g, '').toLowerCase();\n const out = Buffer.allocUnsafe(16);\n for (let i = 0; i < 16; i++) out[i] = parseInt(s.slice(i * 2, i * 2 + 2), 16);\n return out; // 16 bytes\n}\n\nfunction formatHexToUuid(hex32: string): string {\n // hex32 is 32 hex chars\n return `${hex32.slice(0, 8)}-${hex32.slice(8, 12)}-${hex32.slice(12, 16)}-${hex32.slice(16, 20)}-${hex32.slice(20)}`;\n}\n\nfunction v5WithParsed(name: string, nsBytes: Buffer): string {\n if (typeof name !== 'string') throw new TypeError('name must be a string');\n // sha1(namespace || name)\n const d = createHash('sha1').update(nsBytes).update(name, 'utf8').digest(); // 20 bytes\n // set version & variant on first 16 bytes (no extra allocs)\n d[6] = (d[6] & 0x0f) | 0x50; // version 5\n d[8] = (d[8] & 0x3f) | 0x80; // RFC 4122 variant\n const hex = d.subarray(0, 16).toString('hex');\n return formatHexToUuid(hex);\n}\n\n/** One-off generator: name + namespace (both strings) -> UUID v5 string */\nexport function v5(name: string, namespace: string | keyof typeof NAMESPACE): string {\n const nsStr = (namespace in NAMESPACE) ? NAMESPACE[namespace as keyof typeof NAMESPACE] : namespace;\n return v5WithParsed(name, parseNs(nsStr));\n}\n\n/** Hot path: bind namespace once; returns (name: string) => uuid string */\nexport function createV5(namespace: string): (name: string) => string {\n const nsStr = (namespace in NAMESPACE) ? NAMESPACE[namespace as keyof typeof NAMESPACE] : namespace;\n const nsBytes = parseNs(nsStr);\n return (name: string): string => v5WithParsed(name, nsBytes);\n}\n","export class LruCache<K, V> {\n private readonly cache: Map<K, V> = new Map<K, V>();\n\n constructor(private readonly maxSize: number) {\n if (maxSize <= 0) {\n throw new Error('maxSize must be greater than 0');\n }\n }\n\n public get(key: K): V | undefined {\n if (!this.cache.has(key)) {\n return undefined;\n }\n\n const value = this.cache.get(key)!;\n // Refresh key\n this.cache.delete(key);\n this.cache.set(key, value);\n return value;\n }\n\n public set(key: K, value: V): void {\n if (this.cache.has(key)) {\n this.cache.delete(key);\n } else if (this.cache.size >= this.maxSize) {\n // Delete least recently used item\n const [oldestKey] = this.cache.keys();\n this.cache.delete(oldestKey);\n }\n this.cache.set(key, value);\n }\n\n public has(key: K): boolean {\n return this.cache.has(key);\n }\n\n public delete(key: K): boolean {\n return this.cache.delete(key);\n }\n\n public clear(): void {\n this.cache.clear();\n }\n\n public size(): number {\n return this.cache.size;\n }\n\n public keys(): MapIterator<K> {\n return this.cache.keys();\n }\n\n public values(): MapIterator<V> {\n return this.cache.values();\n }\n}\n","import { v5 as uuidv5, NAMESPACE, createV5 } from './uuidv5';\nimport { LruCache } from '@autofleet/lru-cache';\n\nconst namespaceGenerators = new LruCache<string, (name: string) => string>(5);\n\nfunction normalize(input: string): string {\n return input.trim().toLowerCase().normalize('NFC');\n}\n\ninterface Args {\n /** The input string to convert to UUID */\n input: string;\n /** The namespace for UUIDv5 generation. Can be arbitrary string. */\n namespace: string;\n /** Whether to normalize the input string. @default true */\n shouldNormalize?: boolean;\n}\n\n/** Convert a string to a consistent UUIDv5 using a namespace */\nexport function stringToConsistentUuid(params: Args): string {\n const { input, namespace, shouldNormalize = true } = params;\n let generator = namespaceGenerators.get(namespace);\n\n if (!generator) {\n const namespaceUUID = uuidv5(namespace, NAMESPACE.DNS); // Convert arbitrary string namespace to UUIDv5 using DNS namespace\n generator = createV5(namespaceUUID);\n namespaceGenerators.set(namespace, generator);\n }\n\n return generator(shouldNormalize ? normalize(input) : input);\n}\n","import { AfRouter } from './router';\n\nexport { AfRouter } from './router';\nexport { promiseMap } from './promise-utils';\n\nexport { consts } from './consts';\n\nexport { stringToConsistentUuid } from './uuid-utils/string-to-uuid';\nexport { v5, createV5, NAMESPACE } from './uuid-utils/uuidv5';\n\nexport const Router: typeof AfRouter = AfRouter;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["Router","newMethodHandler: IRouterMatcher<Router>","consts: Readonly<{ ok: 'OK'; error: 'ERROR'; fail: 'FAIL'; }>","Router: typeof AfRouter"],"sources":["../src/router/index.ts","../src/consts/index.ts","../src/index.ts"],"sourcesContent":["import {\n Router, type Request, type Response, type NextFunction, type Handler, type RouterOptions, type IRouterMatcher,\n} from 'express';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\n\nexport const METHODS = [\n 'all',\n 'get',\n 'post',\n 'put',\n 'delete',\n 'patch',\n 'options',\n 'head',\n] as const;\n\nconst AfEntryPoint = (logger: LoggerInstanceManager, func: (req: Request, res: Response, nextFn: NextFunction) => void | PromiseLike<void>): Handler => async (req, res, next) => {\n try {\n await func(req, res, next);\n } catch (err) {\n const e = err as Error & { statusCode?: number; };\n logger.error('Caught rejection in route handler', { err, url: req.originalUrl, method: req.method });\n if (e.statusCode && e.statusCode < 500) {\n res.status(400).json({ error: e.message, status: 'ERROR' });\n return;\n }\n next(e);\n }\n};\n\n/** @returns a monkey-patched express router that will handle async routes (and force a 400 status for codes <500) */\nexport const AfRouter = ({ logger, ...options }: RouterOptions & { logger: LoggerInstanceManager; }): Router => {\n const myRouter = Router({ mergeParams: true, ...options });\n METHODS.forEach((method) => {\n const internalMethod = myRouter[method].bind(myRouter);\n const newMethodHandler: IRouterMatcher<Router> = (...args: [...unknown[]]) => internalMethod(...args.map(argMapper) as [string]);\n myRouter[method] = newMethodHandler;\n });\n return myRouter;\n\n function argMapper(args: unknown): unknown {\n if (Array.isArray(args)) return args.map(argMapper);\n return typeof args === 'function' ? AfEntryPoint(logger, args as Handler) : args;\n }\n};\n","export const consts: Readonly<{ ok: 'OK'; error: 'ERROR'; fail: 'FAIL'; }> = Object.freeze({\n ok: 'OK',\n error: 'ERROR',\n fail: 'FAIL',\n});\n","import { AfRouter } from './router';\n\nexport { AfRouter } from './router';\nexport { promiseMap } from './promise-utils';\n\nexport { consts } from './consts';\n\nexport { stringToConsistentUuid, v5, createV5, NAMESPACE } from './uuid-utils';\n\nexport const Router: typeof AfRouter = AfRouter;\n"],"mappings":"+IAKA,MAAa,EAAU,CACrB,MACA,MACA,OACA,MACA,SACA,QACA,UACA,OACD,CAEK,GAAgB,EAA+B,IAAmG,MAAO,EAAK,EAAK,IAAS,CAChL,GAAI,CACF,MAAM,EAAK,EAAK,EAAK,EAAK,OACnB,EAAK,CACZ,IAAM,EAAI,EAEV,GADA,EAAO,MAAM,oCAAqC,CAAE,MAAK,IAAK,EAAI,YAAa,OAAQ,EAAI,OAAQ,CAAC,CAChG,EAAE,YAAc,EAAE,WAAa,IAAK,CACtC,EAAI,OAAO,IAAI,CAAC,KAAK,CAAE,MAAO,EAAE,QAAS,OAAQ,QAAS,CAAC,CAC3D,OAEF,EAAK,EAAE,GAKE,GAAY,CAAE,SAAQ,GAAG,KAA0E,CAC9G,IAAM,EAAWA,EAAO,CAAE,YAAa,GAAM,GAAG,EAAS,CAAC,CAM1D,OALA,EAAQ,QAAS,GAAW,CAC1B,IAAM,EAAiB,EAAS,GAAQ,KAAK,EAAS,CAEtD,EAAS,IADyC,GAAG,IAAyB,EAAe,GAAG,EAAK,IAAI,EAAU,CAAa,EAEhI,CACK,EAEP,SAAS,EAAU,EAAwB,CAEzC,OADI,MAAM,QAAQ,EAAK,CAAS,EAAK,IAAI,EAAU,CAC5C,OAAO,GAAS,WAAa,EAAa,EAAQ,EAAgB,CAAG,IC1CnEE,EAAgE,OAAO,OAAO,CACzF,GAAI,KACJ,MAAO,QACP,KAAM,OACP,CAAC,CCKWC,EAA0B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["Readable"],"sources":["../../src/promise-utils/index.ts"],"sourcesContent":["import { Readable } from 'node:stream';\n\nexport async function promiseMap<T, U>(\n iterable: T[] | Iterable<T>,\n handler: (item: T, options?: { signal?: AbortSignal; }) => PromiseLike<U>,\n { concurrency, signal }: Parameters<Readable['map']>[1] = {},\n): Promise<U[]> {\n if (!concurrency) {\n return Promise.all(Array.from(iterable, item => handler(item, signal ? { signal } : undefined)));\n }\n return Readable.from(iterable).map(handler, { concurrency, signal }).toArray();\n}\n"],"mappings":"6BAEA,eAAsB,EACpB,EACA,EACA,CAAE,cAAa,UAA2C,EAAE,CAC9C,CAId,OAHK,EAGEA,EAAAA,SAAS,KAAK,EAAS,CAAC,IAAI,EAAS,CAAE,cAAa,SAAQ,CAAC,CAAC,SAAS,CAFrE,QAAQ,IAAI,MAAM,KAAK,EAAU,GAAQ,EAAQ,EAAM,EAAS,CAAE,SAAQ,CAAG,IAAA,GAAU,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Readable } from "node:stream";
|
|
2
|
+
|
|
3
|
+
//#region src/promise-utils/index.d.ts
|
|
4
|
+
declare function promiseMap<T, U>(iterable: T[] | Iterable<T>, handler: (item: T, options?: {
|
|
5
|
+
signal?: AbortSignal;
|
|
6
|
+
}) => PromiseLike<U>, {
|
|
7
|
+
concurrency,
|
|
8
|
+
signal
|
|
9
|
+
}?: Parameters<Readable["map"]>[1]): Promise<U[]>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { promiseMap };
|
|
12
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Readable } from "node:stream";
|
|
2
|
+
|
|
3
|
+
//#region src/promise-utils/index.d.ts
|
|
4
|
+
declare function promiseMap<T, U>(iterable: T[] | Iterable<T>, handler: (item: T, options?: {
|
|
5
|
+
signal?: AbortSignal;
|
|
6
|
+
}) => PromiseLike<U>, {
|
|
7
|
+
concurrency,
|
|
8
|
+
signal
|
|
9
|
+
}?: Parameters<Readable["map"]>[1]): Promise<U[]>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { promiseMap };
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/promise-utils/index.ts"],"sourcesContent":["import { Readable } from 'node:stream';\n\nexport async function promiseMap<T, U>(\n iterable: T[] | Iterable<T>,\n handler: (item: T, options?: { signal?: AbortSignal; }) => PromiseLike<U>,\n { concurrency, signal }: Parameters<Readable['map']>[1] = {},\n): Promise<U[]> {\n if (!concurrency) {\n return Promise.all(Array.from(iterable, item => handler(item, signal ? { signal } : undefined)));\n }\n return Readable.from(iterable).map(handler, { concurrency, signal }).toArray();\n}\n"],"mappings":"uCAEA,eAAsB,EACpB,EACA,EACA,CAAE,cAAa,UAA2C,EAAE,CAC9C,CAId,OAHK,EAGE,EAAS,KAAK,EAAS,CAAC,IAAI,EAAS,CAAE,cAAa,SAAQ,CAAC,CAAC,SAAS,CAFrE,QAAQ,IAAI,MAAM,KAAK,EAAU,GAAQ,EAAQ,EAAM,EAAS,CAAE,SAAQ,CAAG,IAAA,GAAU,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require(`../uuid-utils-DaVfcYml.cjs`);exports.NAMESPACE=e.n,exports.createV5=e.r,exports.stringToConsistentUuid=e.t,exports.v5=e.i;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,n as t,r as n,t as r}from"../uuid-utils-XgVlI8eH.js";export{t as NAMESPACE,n as createV5,r as stringToConsistentUuid,e as v5};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
let e=require(`node:crypto`);const t=Object.freeze({DNS:`6ba7b810-9dad-11d1-80b4-00c04fd430c8`,URL:`6ba7b811-9dad-11d1-80b4-00c04fd430c8`,OID:`6ba7b812-9dad-11d1-80b4-00c04fd430c8`,X500:`6ba7b814-9dad-11d1-80b4-00c04fd430c8`});function n(e){if(typeof e!=`string`)throw TypeError(`namespace must be a UUID string`);if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e))throw TypeError(`invalid namespace UUID`);let t=e.replace(/-/g,``).toLowerCase(),n=Buffer.allocUnsafe(16);for(let e=0;e<16;e++)n[e]=parseInt(t.slice(e*2,e*2+2),16);return n}function r(e){return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}function i(t,n){if(typeof t!=`string`)throw TypeError(`name must be a string`);let i=(0,e.createHash)(`sha1`).update(n).update(t,`utf8`).digest();return i[6]=i[6]&15|80,i[8]=i[8]&63|128,r(i.subarray(0,16).toString(`hex`))}function a(e,r){return i(e,n(r in t?t[r]:r))}function o(e){let r=n(e in t?t[e]:e);return e=>i(e,r)}var s=class{constructor(e){if(this.maxSize=e,this.cache=new Map,e<=0)throw Error(`maxSize must be greater than 0`)}get(e){if(!this.cache.has(e))return;let t=this.cache.get(e);return this.cache.delete(e),this.cache.set(e,t),t}set(e,t){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.maxSize){let[e]=this.cache.keys();this.cache.delete(e)}this.cache.set(e,t)}has(e){return this.cache.has(e)}delete(e){return this.cache.delete(e)}clear(){this.cache.clear()}size(){return this.cache.size}keys(){return this.cache.keys()}values(){return this.cache.values()}};const c=new s(5);function l(e){return e.trim().toLowerCase().normalize(`NFC`)}function u(e){let{input:n,namespace:r,shouldNormalize:i=!0}=e,s=c.get(r);return s||(s=o(a(r,t.DNS)),c.set(r,s)),s(i?l(n):n)}Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return u}});
|
|
2
|
+
//# sourceMappingURL=uuid-utils-DaVfcYml.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uuid-utils-DaVfcYml.cjs","names":["NAMESPACE: {\n readonly DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8';\n readonly URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8';\n readonly OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8';\n readonly X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8';\n}","maxSize: number","uuidv5"],"sources":["../src/uuid-utils/uuidv5.ts","../../../libs/lru-cache/src/index.ts","../src/uuid-utils/string-to-uuid.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\n\n// RFC 4122 well-known namespaces (as strings)\nexport const NAMESPACE: {\n readonly DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8';\n readonly URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8';\n readonly OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8';\n readonly X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8';\n} = Object.freeze({\n DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',\n URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8',\n OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8',\n X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8',\n});\n\nfunction parseNs(nsStr: unknown): Buffer {\n if (typeof nsStr !== 'string') throw new TypeError('namespace must be a UUID string');\n\n // Check proper UUID format first (8-4-4-4-12 with hyphens)\n if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(nsStr)) {\n throw new TypeError('invalid namespace UUID');\n }\n\n const s = nsStr.replace(/-/g, '').toLowerCase();\n const out = Buffer.allocUnsafe(16);\n for (let i = 0; i < 16; i++) out[i] = parseInt(s.slice(i * 2, i * 2 + 2), 16);\n return out; // 16 bytes\n}\n\nfunction formatHexToUuid(hex32: string): string {\n // hex32 is 32 hex chars\n return `${hex32.slice(0, 8)}-${hex32.slice(8, 12)}-${hex32.slice(12, 16)}-${hex32.slice(16, 20)}-${hex32.slice(20)}`;\n}\n\nfunction v5WithParsed(name: string, nsBytes: Buffer): string {\n if (typeof name !== 'string') throw new TypeError('name must be a string');\n // sha1(namespace || name)\n const d = createHash('sha1').update(nsBytes).update(name, 'utf8').digest(); // 20 bytes\n // set version & variant on first 16 bytes (no extra allocs)\n d[6] = (d[6] & 0x0f) | 0x50; // version 5\n d[8] = (d[8] & 0x3f) | 0x80; // RFC 4122 variant\n const hex = d.subarray(0, 16).toString('hex');\n return formatHexToUuid(hex);\n}\n\n/** One-off generator: name + namespace (both strings) -> UUID v5 string */\nexport function v5(name: string, namespace: string | keyof typeof NAMESPACE): string {\n const nsStr = (namespace in NAMESPACE) ? NAMESPACE[namespace as keyof typeof NAMESPACE] : namespace;\n return v5WithParsed(name, parseNs(nsStr));\n}\n\n/** Hot path: bind namespace once; returns (name: string) => uuid string */\nexport function createV5(namespace: string): (name: string) => string {\n const nsStr = (namespace in NAMESPACE) ? NAMESPACE[namespace as keyof typeof NAMESPACE] : namespace;\n const nsBytes = parseNs(nsStr);\n return (name: string): string => v5WithParsed(name, nsBytes);\n}\n","export class LruCache<K, V> {\n private readonly cache: Map<K, V> = new Map<K, V>();\n\n constructor(private readonly maxSize: number) {\n if (maxSize <= 0) {\n throw new Error('maxSize must be greater than 0');\n }\n }\n\n public get(key: K): V | undefined {\n if (!this.cache.has(key)) {\n return undefined;\n }\n\n const value = this.cache.get(key)!;\n // Refresh key\n this.cache.delete(key);\n this.cache.set(key, value);\n return value;\n }\n\n public set(key: K, value: V): void {\n if (this.cache.has(key)) {\n this.cache.delete(key);\n } else if (this.cache.size >= this.maxSize) {\n // Delete least recently used item\n const [oldestKey] = this.cache.keys();\n this.cache.delete(oldestKey);\n }\n this.cache.set(key, value);\n }\n\n public has(key: K): boolean {\n return this.cache.has(key);\n }\n\n public delete(key: K): boolean {\n return this.cache.delete(key);\n }\n\n public clear(): void {\n this.cache.clear();\n }\n\n public size(): number {\n return this.cache.size;\n }\n\n public keys(): MapIterator<K> {\n return this.cache.keys();\n }\n\n public values(): MapIterator<V> {\n return this.cache.values();\n }\n}\n","import { v5 as uuidv5, NAMESPACE, createV5 } from './uuidv5';\nimport { LruCache } from '@autofleet/lru-cache';\n\nconst namespaceGenerators = new LruCache<string, (name: string) => string>(5);\n\nfunction normalize(input: string): string {\n return input.trim().toLowerCase().normalize('NFC');\n}\n\ninterface Args {\n /** The input string to convert to UUID */\n input: string;\n /** The namespace for UUIDv5 generation. Can be arbitrary string. */\n namespace: string;\n /** Whether to normalize the input string. @default true */\n shouldNormalize?: boolean;\n}\n\n/** Convert a string to a consistent UUIDv5 using a namespace */\nexport function stringToConsistentUuid(params: Args): string {\n const { input, namespace, shouldNormalize = true } = params;\n let generator = namespaceGenerators.get(namespace);\n\n if (!generator) {\n const namespaceUUID = uuidv5(namespace, NAMESPACE.DNS); // Convert arbitrary string namespace to UUIDv5 using DNS namespace\n generator = createV5(namespaceUUID);\n namespaceGenerators.set(namespace, generator);\n }\n\n return generator(shouldNormalize ? normalize(input) : input);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createHash as e}from"node:crypto";const t=Object.freeze({DNS:`6ba7b810-9dad-11d1-80b4-00c04fd430c8`,URL:`6ba7b811-9dad-11d1-80b4-00c04fd430c8`,OID:`6ba7b812-9dad-11d1-80b4-00c04fd430c8`,X500:`6ba7b814-9dad-11d1-80b4-00c04fd430c8`});function n(e){if(typeof e!=`string`)throw TypeError(`namespace must be a UUID string`);if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e))throw TypeError(`invalid namespace UUID`);let t=e.replace(/-/g,``).toLowerCase(),n=Buffer.allocUnsafe(16);for(let e=0;e<16;e++)n[e]=parseInt(t.slice(e*2,e*2+2),16);return n}function r(e){return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}function i(t,n){if(typeof t!=`string`)throw TypeError(`name must be a string`);let i=e(`sha1`).update(n).update(t,`utf8`).digest();return i[6]=i[6]&15|80,i[8]=i[8]&63|128,r(i.subarray(0,16).toString(`hex`))}function a(e,r){return i(e,n(r in t?t[r]:r))}function o(e){let r=n(e in t?t[e]:e);return e=>i(e,r)}const s=new class{constructor(e){if(this.maxSize=e,this.cache=new Map,e<=0)throw Error(`maxSize must be greater than 0`)}get(e){if(!this.cache.has(e))return;let t=this.cache.get(e);return this.cache.delete(e),this.cache.set(e,t),t}set(e,t){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.maxSize){let[e]=this.cache.keys();this.cache.delete(e)}this.cache.set(e,t)}has(e){return this.cache.has(e)}delete(e){return this.cache.delete(e)}clear(){this.cache.clear()}size(){return this.cache.size}keys(){return this.cache.keys()}values(){return this.cache.values()}}(5);function c(e){return e.trim().toLowerCase().normalize(`NFC`)}function l(e){let{input:n,namespace:r,shouldNormalize:i=!0}=e,l=s.get(r);return l||(l=o(a(r,t.DNS)),s.set(r,l)),l(i?c(n):n)}export{a as i,t as n,o as r,l as t};
|
|
2
|
+
//# sourceMappingURL=uuid-utils-XgVlI8eH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uuid-utils-XgVlI8eH.js","names":["NAMESPACE: {\n readonly DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8';\n readonly URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8';\n readonly OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8';\n readonly X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8';\n}","maxSize: number","uuidv5"],"sources":["../src/uuid-utils/uuidv5.ts","../../../libs/lru-cache/src/index.ts","../src/uuid-utils/string-to-uuid.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\n\n// RFC 4122 well-known namespaces (as strings)\nexport const NAMESPACE: {\n readonly DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8';\n readonly URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8';\n readonly OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8';\n readonly X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8';\n} = Object.freeze({\n DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',\n URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8',\n OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8',\n X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8',\n});\n\nfunction parseNs(nsStr: unknown): Buffer {\n if (typeof nsStr !== 'string') throw new TypeError('namespace must be a UUID string');\n\n // Check proper UUID format first (8-4-4-4-12 with hyphens)\n if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(nsStr)) {\n throw new TypeError('invalid namespace UUID');\n }\n\n const s = nsStr.replace(/-/g, '').toLowerCase();\n const out = Buffer.allocUnsafe(16);\n for (let i = 0; i < 16; i++) out[i] = parseInt(s.slice(i * 2, i * 2 + 2), 16);\n return out; // 16 bytes\n}\n\nfunction formatHexToUuid(hex32: string): string {\n // hex32 is 32 hex chars\n return `${hex32.slice(0, 8)}-${hex32.slice(8, 12)}-${hex32.slice(12, 16)}-${hex32.slice(16, 20)}-${hex32.slice(20)}`;\n}\n\nfunction v5WithParsed(name: string, nsBytes: Buffer): string {\n if (typeof name !== 'string') throw new TypeError('name must be a string');\n // sha1(namespace || name)\n const d = createHash('sha1').update(nsBytes).update(name, 'utf8').digest(); // 20 bytes\n // set version & variant on first 16 bytes (no extra allocs)\n d[6] = (d[6] & 0x0f) | 0x50; // version 5\n d[8] = (d[8] & 0x3f) | 0x80; // RFC 4122 variant\n const hex = d.subarray(0, 16).toString('hex');\n return formatHexToUuid(hex);\n}\n\n/** One-off generator: name + namespace (both strings) -> UUID v5 string */\nexport function v5(name: string, namespace: string | keyof typeof NAMESPACE): string {\n const nsStr = (namespace in NAMESPACE) ? NAMESPACE[namespace as keyof typeof NAMESPACE] : namespace;\n return v5WithParsed(name, parseNs(nsStr));\n}\n\n/** Hot path: bind namespace once; returns (name: string) => uuid string */\nexport function createV5(namespace: string): (name: string) => string {\n const nsStr = (namespace in NAMESPACE) ? NAMESPACE[namespace as keyof typeof NAMESPACE] : namespace;\n const nsBytes = parseNs(nsStr);\n return (name: string): string => v5WithParsed(name, nsBytes);\n}\n","export class LruCache<K, V> {\n private readonly cache: Map<K, V> = new Map<K, V>();\n\n constructor(private readonly maxSize: number) {\n if (maxSize <= 0) {\n throw new Error('maxSize must be greater than 0');\n }\n }\n\n public get(key: K): V | undefined {\n if (!this.cache.has(key)) {\n return undefined;\n }\n\n const value = this.cache.get(key)!;\n // Refresh key\n this.cache.delete(key);\n this.cache.set(key, value);\n return value;\n }\n\n public set(key: K, value: V): void {\n if (this.cache.has(key)) {\n this.cache.delete(key);\n } else if (this.cache.size >= this.maxSize) {\n // Delete least recently used item\n const [oldestKey] = this.cache.keys();\n this.cache.delete(oldestKey);\n }\n this.cache.set(key, value);\n }\n\n public has(key: K): boolean {\n return this.cache.has(key);\n }\n\n public delete(key: K): boolean {\n return this.cache.delete(key);\n }\n\n public clear(): void {\n this.cache.clear();\n }\n\n public size(): number {\n return this.cache.size;\n }\n\n public keys(): MapIterator<K> {\n return this.cache.keys();\n }\n\n public values(): MapIterator<V> {\n return this.cache.values();\n }\n}\n","import { v5 as uuidv5, NAMESPACE, createV5 } from './uuidv5';\nimport { LruCache } from '@autofleet/lru-cache';\n\nconst namespaceGenerators = new LruCache<string, (name: string) => string>(5);\n\nfunction normalize(input: string): string {\n return input.trim().toLowerCase().normalize('NFC');\n}\n\ninterface Args {\n /** The input string to convert to UUID */\n input: string;\n /** The namespace for UUIDv5 generation. Can be arbitrary string. */\n namespace: string;\n /** Whether to normalize the input string. @default true */\n shouldNormalize?: boolean;\n}\n\n/** Convert a string to a consistent UUIDv5 using a namespace */\nexport function stringToConsistentUuid(params: Args): string {\n const { input, namespace, shouldNormalize = true } = params;\n let generator = namespaceGenerators.get(namespace);\n\n if (!generator) {\n const namespaceUUID = uuidv5(namespace, NAMESPACE.DNS); // Convert arbitrary string namespace to UUIDv5 using DNS namespace\n generator = createV5(namespaceUUID);\n namespaceGenerators.set(namespace, generator);\n }\n\n return generator(shouldNormalize ? normalize(input) : input);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,19 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/node-common",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
13
19
|
},
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
20
|
+
"./promise-utils": {
|
|
21
|
+
"import": {
|
|
22
|
+
"types": "./dist/promise-utils/index.d.ts",
|
|
23
|
+
"default": "./dist/promise-utils/index.js"
|
|
24
|
+
},
|
|
25
|
+
"require": {
|
|
26
|
+
"types": "./dist/promise-utils/index.d.cts",
|
|
27
|
+
"default": "./dist/promise-utils/index.cjs"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"./uuid-utils": {
|
|
31
|
+
"import": {
|
|
32
|
+
"types": "./dist/uuid-utils/index.d.ts",
|
|
33
|
+
"default": "./dist/uuid-utils/index.js"
|
|
34
|
+
},
|
|
35
|
+
"require": {
|
|
36
|
+
"types": "./dist/uuid-utils/index.d.cts",
|
|
37
|
+
"default": "./dist/uuid-utils/index.cjs"
|
|
38
|
+
}
|
|
17
39
|
}
|
|
18
40
|
},
|
|
19
41
|
"files": [
|