logixia 1.12.4 → 1.12.6
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/README.md +80 -27
- package/dist/.tsbuildinfo +1 -1
- package/dist/async-context-CSHWoHMB.js +88 -0
- package/dist/async-context-CSHWoHMB.js.map +1 -0
- package/dist/async-context-CwBNMm2E.mjs +68 -0
- package/dist/async-context-CwBNMm2E.mjs.map +1 -0
- package/dist/azure-monitor.transport-CG7ClkYj.d.ts +62 -0
- package/dist/azure-monitor.transport-CG7ClkYj.d.ts.map +1 -0
- package/dist/azure-monitor.transport-CHnjVRF-.mjs +152 -0
- package/dist/azure-monitor.transport-CHnjVRF-.mjs.map +1 -0
- package/dist/azure-monitor.transport-Cm74kXZS.d.mts +62 -0
- package/dist/azure-monitor.transport-Cm74kXZS.d.mts.map +1 -0
- package/dist/azure-monitor.transport-CrvfHd9C.js +157 -0
- package/dist/azure-monitor.transport-CrvfHd9C.js.map +1 -0
- package/dist/azure.d.mts +3 -0
- package/dist/azure.d.ts +3 -0
- package/dist/azure.js +6 -0
- package/dist/azure.mjs +6 -0
- package/dist/batch-buffer-BY-mRWIK.js +170 -0
- package/dist/batch-buffer-BY-mRWIK.js.map +1 -0
- package/dist/batch-buffer-PGvSgbmd.mjs +132 -0
- package/dist/batch-buffer-PGvSgbmd.mjs.map +1 -0
- package/dist/browser.d.mts +427 -0
- package/dist/browser.d.mts.map +1 -0
- package/dist/browser.d.ts +427 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +590 -0
- package/dist/browser.js.map +1 -0
- package/dist/browser.mjs +586 -0
- package/dist/browser.mjs.map +1 -0
- package/dist/chunk-DLSkYcPk.mjs +7 -0
- package/dist/chunk-nOFOJqeH.js +30 -0
- package/dist/cloudwatch.d.mts +3 -0
- package/dist/cloudwatch.d.ts +3 -0
- package/dist/cloudwatch.js +6 -0
- package/dist/cloudwatch.mjs +6 -0
- package/dist/cloudwatch.transport-CGHY4buE.d.mts +81 -0
- package/dist/cloudwatch.transport-CGHY4buE.d.mts.map +1 -0
- package/dist/cloudwatch.transport-DK_8cKd3.d.ts +81 -0
- package/dist/cloudwatch.transport-DK_8cKd3.d.ts.map +1 -0
- package/dist/cloudwatch.transport-pNBNWJLt.js +370 -0
- package/dist/cloudwatch.transport-pNBNWJLt.js.map +1 -0
- package/dist/cloudwatch.transport-yBwm4OeO.mjs +360 -0
- package/dist/cloudwatch.transport-yBwm4OeO.mjs.map +1 -0
- package/dist/coerce.utils-BN980Y9V.js +44 -0
- package/dist/coerce.utils-BN980Y9V.js.map +1 -0
- package/dist/coerce.utils-Dxv4_ikC.mjs +38 -0
- package/dist/coerce.utils-Dxv4_ikC.mjs.map +1 -0
- package/dist/correlation.d.mts +238 -0
- package/dist/correlation.d.mts.map +1 -0
- package/dist/correlation.d.ts +238 -0
- package/dist/correlation.d.ts.map +1 -0
- package/dist/correlation.js +272 -0
- package/dist/correlation.js.map +1 -0
- package/dist/correlation.mjs +261 -0
- package/dist/correlation.mjs.map +1 -0
- package/dist/gcp.d.mts +3 -0
- package/dist/gcp.d.ts +3 -0
- package/dist/gcp.js +6 -0
- package/dist/gcp.mjs +6 -0
- package/dist/gcp.transport-BJuNRFe_.mjs +192 -0
- package/dist/gcp.transport-BJuNRFe_.mjs.map +1 -0
- package/dist/gcp.transport-BOhkVKlI.d.ts +71 -0
- package/dist/gcp.transport-BOhkVKlI.d.ts.map +1 -0
- package/dist/gcp.transport-Bi6CUqZR.d.mts +71 -0
- package/dist/gcp.transport-Bi6CUqZR.d.mts.map +1 -0
- package/dist/gcp.transport-SHdtc1n0.js +198 -0
- package/dist/gcp.transport-SHdtc1n0.js.map +1 -0
- package/dist/{index-CwFww7VC.d.ts → index-BPKwwERo.d.mts} +18 -174
- package/dist/index-BPKwwERo.d.mts.map +1 -0
- package/dist/{index-DnyeaoZU.d.mts → index-C1X-TE5I.d.ts} +18 -174
- package/dist/index-C1X-TE5I.d.ts.map +1 -0
- package/dist/index.d.mts +41 -11
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +40 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +87 -147
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +62 -132
- package/dist/index.mjs.map +1 -1
- package/dist/internal-log-BUJYMZbE.js +70 -0
- package/dist/internal-log-BUJYMZbE.js.map +1 -0
- package/dist/internal-log-Cm8SOWSV.mjs +52 -0
- package/dist/internal-log-Cm8SOWSV.mjs.map +1 -0
- package/dist/{logitron-logger.module-BIGTm2V6.mjs → logitron-logger.module-Bs3XYZgF.mjs} +266 -166
- package/dist/logitron-logger.module-Bs3XYZgF.mjs.map +1 -0
- package/dist/{logitron-logger.module-BTxDpK6u.js → logitron-logger.module-BsDZR5BH.js} +297 -203
- package/dist/logitron-logger.module-BsDZR5BH.js.map +1 -0
- package/dist/{logitron-logger.module-BmT-ewin.d.ts → logitron-logger.module-CxT1F6Cm.d.ts} +23 -10
- package/dist/logitron-logger.module-CxT1F6Cm.d.ts.map +1 -0
- package/dist/{logitron-logger.module-BCq3sF27.d.mts → logitron-logger.module-zDKVd_o0.d.mts} +23 -10
- package/dist/logitron-logger.module-zDKVd_o0.d.mts.map +1 -0
- package/dist/middleware.d.mts +5 -2
- package/dist/middleware.d.mts.map +1 -1
- package/dist/middleware.d.ts +5 -2
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +13 -4
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +14 -4
- package/dist/middleware.mjs.map +1 -1
- package/dist/nest.d.mts +3 -2
- package/dist/nest.d.mts.map +1 -1
- package/dist/nest.d.ts +3 -2
- package/dist/nest.d.ts.map +1 -1
- package/dist/nest.js +6 -2
- package/dist/nest.mjs +6 -2
- package/dist/safe-stringify-DJ66tW5I.mjs +118 -0
- package/dist/safe-stringify-DJ66tW5I.mjs.map +1 -0
- package/dist/safe-stringify-DWo3aZp_.js +142 -0
- package/dist/safe-stringify-DWo3aZp_.js.map +1 -0
- package/dist/search-CFQRISUv.mjs +1596 -0
- package/dist/search-CFQRISUv.mjs.map +1 -0
- package/dist/search-CQOo-Iq6.d.mts +816 -0
- package/dist/search-CQOo-Iq6.d.mts.map +1 -0
- package/dist/search-DujhR94O.d.ts +816 -0
- package/dist/search-DujhR94O.d.ts.map +1 -0
- package/dist/search-njTI2hdo.js +1631 -0
- package/dist/search-njTI2hdo.js.map +1 -0
- package/dist/search.d.mts +4 -1
- package/dist/search.d.ts +4 -1
- package/dist/search.js +9 -1
- package/dist/search.mjs +3 -2
- package/dist/testing.d.mts +2 -1
- package/dist/testing.d.mts.map +1 -1
- package/dist/testing.d.ts +2 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/{transport.manager-ciG4r5uz.js → transport.manager-BivyUTtU.js} +497 -437
- package/dist/transport.manager-BivyUTtU.js.map +1 -0
- package/dist/{transport.manager-DETpXuaY.mjs → transport.manager-D6KL3t9V.mjs} +473 -364
- package/dist/transport.manager-D6KL3t9V.mjs.map +1 -0
- package/dist/transport.types-B5vcyv2k.d.mts +187 -0
- package/dist/transport.types-B5vcyv2k.d.mts.map +1 -0
- package/dist/transport.types-BuY84TwO.d.ts +187 -0
- package/dist/transport.types-BuY84TwO.d.ts.map +1 -0
- package/dist/transports.d.mts +90 -29
- package/dist/transports.d.mts.map +1 -1
- package/dist/transports.d.ts +90 -29
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +14 -2
- package/dist/transports.mjs +10 -2
- package/dist/worker-entry.js +1241 -0
- package/dist/worker.d.mts +3 -0
- package/dist/worker.d.ts +3 -0
- package/dist/worker.js +4 -0
- package/dist/worker.mjs +4 -0
- package/dist/worker.transport-BP8Q28Z2.d.mts +76 -0
- package/dist/worker.transport-BP8Q28Z2.d.mts.map +1 -0
- package/dist/worker.transport-BhMyvqQ2.mjs +167 -0
- package/dist/worker.transport-BhMyvqQ2.mjs.map +1 -0
- package/dist/worker.transport-CfH6z37Z.js +168 -0
- package/dist/worker.transport-CfH6z37Z.js.map +1 -0
- package/dist/worker.transport-mKXgNK0L.d.ts +76 -0
- package/dist/worker.transport-mKXgNK0L.d.ts.map +1 -0
- package/package.json +23 -18
- package/dist/index-CwFww7VC.d.ts.map +0 -1
- package/dist/index-DnyeaoZU.d.mts.map +0 -1
- package/dist/logitron-logger.module-BCq3sF27.d.mts.map +0 -1
- package/dist/logitron-logger.module-BIGTm2V6.mjs.map +0 -1
- package/dist/logitron-logger.module-BTxDpK6u.js.map +0 -1
- package/dist/logitron-logger.module-BmT-ewin.d.ts.map +0 -1
- package/dist/search-Cg_OasF-.d.ts +0 -1
- package/dist/search-DN676Dnz.d.mts +0 -1
- package/dist/search-DOvSI-mb.mjs +0 -1
- package/dist/search-DoZF3RZj.js +0 -0
- package/dist/transport.manager-DETpXuaY.mjs.map +0 -1
- package/dist/transport.manager-ciG4r5uz.js.map +0 -1
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
//#region src/utils/safe-stringify.ts
|
|
2
|
+
/** Build a JSONPath like `$["a"][0]["b"]` for a decycle pointer. */
|
|
3
|
+
function jsonPath(parts) {
|
|
4
|
+
let path = "$";
|
|
5
|
+
for (const p of parts) path += typeof p === "number" ? `[${p}]` : `[${JSON.stringify(p)}]`;
|
|
6
|
+
return path;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Serialize any value to JSON without throwing on circular references or BigInt.
|
|
10
|
+
* Circular refs become `"[Circular]"` (or `{ $ref }` pointers when `decycle`).
|
|
11
|
+
*/
|
|
12
|
+
function safeStringify(value, options = {}) {
|
|
13
|
+
const { indent, deterministic = false, decycle = false, bigint = "string" } = options;
|
|
14
|
+
if (decycle) return JSON.stringify(decycleValue(value, bigint), void 0, indent);
|
|
15
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
16
|
+
const transform = (val) => {
|
|
17
|
+
if (typeof val === "bigint") return bigint === "number" ? Number(val) : val.toString();
|
|
18
|
+
if (typeof val === "function") return `[Function: ${val.name || "anonymous"}]`;
|
|
19
|
+
if (typeof val === "symbol") return val.toString();
|
|
20
|
+
if (val === null || typeof val !== "object") return val;
|
|
21
|
+
if (seen.has(val)) return "[Circular]";
|
|
22
|
+
seen.add(val);
|
|
23
|
+
let out;
|
|
24
|
+
const toJSON = val.toJSON;
|
|
25
|
+
if (Array.isArray(val)) out = val.map((item) => transform(item));
|
|
26
|
+
else if (typeof toJSON === "function") out = transform(toJSON.call(val));
|
|
27
|
+
else {
|
|
28
|
+
const rec = val;
|
|
29
|
+
const keys = deterministic ? Object.keys(rec).sort() : Object.keys(rec);
|
|
30
|
+
const obj = {};
|
|
31
|
+
for (const k of keys) {
|
|
32
|
+
if (k === "__proto__" || k === "constructor" || k === "prototype") continue;
|
|
33
|
+
obj[k] = transform(rec[k]);
|
|
34
|
+
}
|
|
35
|
+
out = obj;
|
|
36
|
+
}
|
|
37
|
+
seen.delete(val);
|
|
38
|
+
return out;
|
|
39
|
+
};
|
|
40
|
+
return JSON.stringify(transform(value), void 0, indent);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Replace repeated object references with round-trippable `{ "$ref": "$..." }`
|
|
44
|
+
* JSONPath pointers (the classic Crockford decycle). Pair with {@link retrocycle}
|
|
45
|
+
* to reconstruct the original shared/circular graph.
|
|
46
|
+
*/
|
|
47
|
+
function decycleValue(value, bigint = "string") {
|
|
48
|
+
const paths = /* @__PURE__ */ new WeakMap();
|
|
49
|
+
const walk = (val, path) => {
|
|
50
|
+
if (typeof val === "bigint") return bigint === "number" ? Number(val) : val.toString();
|
|
51
|
+
if (val === null || typeof val !== "object") return val;
|
|
52
|
+
if (val instanceof Date) return val.toISOString();
|
|
53
|
+
const existing = paths.get(val);
|
|
54
|
+
if (existing !== void 0) return { $ref: existing };
|
|
55
|
+
paths.set(val, jsonPath(path));
|
|
56
|
+
if (Array.isArray(val)) return val.map((item, i) => walk(item, [...path, i]));
|
|
57
|
+
const rec = val;
|
|
58
|
+
const obj = {};
|
|
59
|
+
for (const k of Object.keys(rec)) {
|
|
60
|
+
if (k === "__proto__" || k === "constructor" || k === "prototype") continue;
|
|
61
|
+
obj[k] = walk(rec[k], [...path, k]);
|
|
62
|
+
}
|
|
63
|
+
return obj;
|
|
64
|
+
};
|
|
65
|
+
return walk(value, []);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Inverse of {@link decycleValue}: resolve `{ "$ref": "$..." }` pointers back
|
|
69
|
+
* into the live object graph (mutates and returns the parsed input).
|
|
70
|
+
*/
|
|
71
|
+
function retrocycle(root) {
|
|
72
|
+
const refRe = /^\$(?:\[(?:\d+|"(?:[^"\\]|\\.)*")\])*$/;
|
|
73
|
+
const resolve = (path) => {
|
|
74
|
+
const segs = [];
|
|
75
|
+
const partRe = /\[(\d+|"(?:[^"\\]|\\.)*")\]/g;
|
|
76
|
+
let m;
|
|
77
|
+
while ((m = partRe.exec(path)) !== null) {
|
|
78
|
+
const raw = m[1];
|
|
79
|
+
segs.push(raw.startsWith("\"") ? JSON.parse(raw) : Number(raw));
|
|
80
|
+
}
|
|
81
|
+
let node = root;
|
|
82
|
+
for (const s of segs) node = node[s];
|
|
83
|
+
return node;
|
|
84
|
+
};
|
|
85
|
+
const walk = (val) => {
|
|
86
|
+
if (val === null || typeof val !== "object") return;
|
|
87
|
+
const rec = val;
|
|
88
|
+
for (const k of Object.keys(rec)) {
|
|
89
|
+
const child = rec[k];
|
|
90
|
+
if (child !== null && typeof child === "object" && typeof child.$ref === "string" && refRe.test(child.$ref)) rec[k] = resolve(child.$ref);
|
|
91
|
+
else walk(child);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
walk(root);
|
|
95
|
+
return root;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* `JSON.stringify` for log output. Takes the plain fast path first and only
|
|
99
|
+
* falls back to {@link safeStringify} when that throws (a cycle, a BigInt, a
|
|
100
|
+
* throwing `toJSON`), so a bad payload costs nothing until it shows up.
|
|
101
|
+
* Never throws: if even the safe walk fails, the value is replaced by a marker.
|
|
102
|
+
*/
|
|
103
|
+
function stringifyForLog(value) {
|
|
104
|
+
try {
|
|
105
|
+
return JSON.stringify(value);
|
|
106
|
+
} catch {
|
|
107
|
+
try {
|
|
108
|
+
return safeStringify(value);
|
|
109
|
+
} catch (error) {
|
|
110
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
111
|
+
return JSON.stringify(`[Unserializable: ${reason}]`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
//#endregion
|
|
117
|
+
export { stringifyForLog as i, retrocycle as n, safeStringify as r, decycleValue as t };
|
|
118
|
+
//# sourceMappingURL=safe-stringify-DJ66tW5I.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-stringify-DJ66tW5I.mjs","names":["out: unknown","obj: Record<string, unknown>","segs: Array<string | number>","m: RegExpExecArray | null","node: unknown"],"sources":["../src/utils/safe-stringify.ts"],"sourcesContent":["/**\n * logixia — robust JSON serialization for log payloads.\n *\n * Modern Winston/Pino already neutralize circular refs to `[Circular]` (via\n * safe-stable-stringify / fast-safe-stringify), so merely \"surviving cycles\" is\n * not a differentiator. This goes one notch further:\n *\n * - **BigInt** → serialized (as a string by default; JSON.stringify throws on\n * BigInt, which silently breaks logging of e.g. DB bigint ids).\n * - **Deterministic key order** (optional) so identical objects hash/diff equal.\n * - **True decycle** (optional) — replace repeated references with JSONPath\n * `$ref` pointers that round-trip back to the original object graph, instead\n * of the lossy `[Circular]` tag. Useful when you need to reconstruct shared\n * structure downstream.\n *\n * @example\n * ```ts\n * safeStringify({ id: 10n, self: obj }); // → BigInt + cycle safe\n * safeStringify(graph, { decycle: true }); // → round-trippable $ref pointers\n * const back = retrocycle(JSON.parse(json)); // → reconstruct shared refs\n * ```\n */\n\nexport interface SafeStringifyOptions {\n /** Indentation passed to JSON.stringify (number of spaces or a string). */\n indent?: number | string;\n /** Sort object keys for deterministic output. Default: false. */\n deterministic?: boolean;\n /**\n * Use round-trippable `$ref` JSONPath pointers for repeated references instead\n * of the lossy \"[Circular]\" tag. Default: false.\n */\n decycle?: boolean;\n /** How to render BigInt: 'string' (default) or 'number' (may lose precision). */\n bigint?: 'string' | 'number';\n}\n\n/** Build a JSONPath like `$[\"a\"][0][\"b\"]` for a decycle pointer. */\nfunction jsonPath(parts: Array<string | number>): string {\n let path = '$';\n for (const p of parts) {\n path += typeof p === 'number' ? `[${p}]` : `[${JSON.stringify(p)}]`;\n }\n return path;\n}\n\n/**\n * Serialize any value to JSON without throwing on circular references or BigInt.\n * Circular refs become `\"[Circular]\"` (or `{ $ref }` pointers when `decycle`).\n */\nexport function safeStringify(value: unknown, options: SafeStringifyOptions = {}): string {\n const { indent, deterministic = false, decycle = false, bigint = 'string' } = options;\n\n if (decycle) {\n return JSON.stringify(decycleValue(value, bigint), undefined, indent);\n }\n\n const seen = new WeakSet<object>();\n\n const transform = (val: unknown): unknown => {\n if (typeof val === 'bigint') return bigint === 'number' ? Number(val) : val.toString();\n if (typeof val === 'function') return `[Function: ${val.name || 'anonymous'}]`;\n if (typeof val === 'symbol') return val.toString();\n if (val === null || typeof val !== 'object') return val;\n\n if (seen.has(val)) return '[Circular]';\n seen.add(val);\n\n let out: unknown;\n const toJSON = (val as { toJSON?: unknown }).toJSON;\n if (Array.isArray(val)) {\n out = val.map((item) => transform(item));\n } else if (typeof toJSON === 'function') {\n // Dates, URLs, Buffers and classes with their own toJSON print the way\n // JSON.stringify would; a toJSON that returns `this` hits the cycle check.\n out = transform(toJSON.call(val));\n } else {\n const rec = val as Record<string, unknown>;\n const keys = deterministic ? Object.keys(rec).sort() : Object.keys(rec);\n const obj: Record<string, unknown> = {};\n for (const k of keys) {\n if (k === '__proto__' || k === 'constructor' || k === 'prototype') continue;\n obj[k] = transform(rec[k]);\n }\n out = obj;\n }\n // Allow the same object to appear in sibling branches (not a true cycle):\n // remove from `seen` after we finish its subtree.\n seen.delete(val);\n return out;\n };\n\n return JSON.stringify(transform(value), undefined, indent);\n}\n\n/**\n * Replace repeated object references with round-trippable `{ \"$ref\": \"$...\" }`\n * JSONPath pointers (the classic Crockford decycle). Pair with {@link retrocycle}\n * to reconstruct the original shared/circular graph.\n */\nexport function decycleValue(value: unknown, bigint: 'string' | 'number' = 'string'): unknown {\n const paths = new WeakMap<object, string>();\n\n const walk = (val: unknown, path: Array<string | number>): unknown => {\n if (typeof val === 'bigint') return bigint === 'number' ? Number(val) : val.toString();\n if (val === null || typeof val !== 'object') return val;\n if (val instanceof Date) return val.toISOString();\n\n const existing = paths.get(val);\n if (existing !== undefined) return { $ref: existing };\n paths.set(val, jsonPath(path));\n\n if (Array.isArray(val)) {\n return val.map((item, i) => walk(item, [...path, i]));\n }\n const rec = val as Record<string, unknown>;\n const obj: Record<string, unknown> = {};\n for (const k of Object.keys(rec)) {\n if (k === '__proto__' || k === 'constructor' || k === 'prototype') continue;\n obj[k] = walk(rec[k], [...path, k]);\n }\n return obj;\n };\n\n return walk(value, []);\n}\n\n/**\n * Inverse of {@link decycleValue}: resolve `{ \"$ref\": \"$...\" }` pointers back\n * into the live object graph (mutates and returns the parsed input).\n */\nexport function retrocycle<T>(root: T): T {\n const refRe = /^\\$(?:\\[(?:\\d+|\"(?:[^\"\\\\]|\\\\.)*\")\\])*$/;\n\n const resolve = (path: string): unknown => {\n // Parse the JSONPath segments back out.\n const segs: Array<string | number> = [];\n const partRe = /\\[(\\d+|\"(?:[^\"\\\\]|\\\\.)*\")\\]/g;\n let m: RegExpExecArray | null;\n while ((m = partRe.exec(path)) !== null) {\n const raw = m[1]!;\n segs.push(raw.startsWith('\"') ? (JSON.parse(raw) as string) : Number(raw));\n }\n let node: unknown = root;\n for (const s of segs) {\n node = (node as Record<string | number, unknown>)[s];\n }\n return node;\n };\n\n const walk = (val: unknown): void => {\n if (val === null || typeof val !== 'object') return;\n const rec = val as Record<string, unknown>;\n for (const k of Object.keys(rec)) {\n const child = rec[k];\n if (\n child !== null &&\n typeof child === 'object' &&\n typeof (child as { $ref?: unknown }).$ref === 'string' &&\n refRe.test((child as { $ref: string }).$ref)\n ) {\n rec[k] = resolve((child as { $ref: string }).$ref);\n } else {\n walk(child);\n }\n }\n };\n\n walk(root);\n return root;\n}\n\n/**\n * `JSON.stringify` for log output. Takes the plain fast path first and only\n * falls back to {@link safeStringify} when that throws (a cycle, a BigInt, a\n * throwing `toJSON`), so a bad payload costs nothing until it shows up.\n * Never throws: if even the safe walk fails, the value is replaced by a marker.\n */\nexport function stringifyForLog(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n try {\n return safeStringify(value);\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return JSON.stringify(`[Unserializable: ${reason}]`);\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/utils/safe-stringify.ts
|
|
3
|
+
/** Build a JSONPath like `$["a"][0]["b"]` for a decycle pointer. */
|
|
4
|
+
function jsonPath(parts) {
|
|
5
|
+
let path = "$";
|
|
6
|
+
for (const p of parts) path += typeof p === "number" ? `[${p}]` : `[${JSON.stringify(p)}]`;
|
|
7
|
+
return path;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Serialize any value to JSON without throwing on circular references or BigInt.
|
|
11
|
+
* Circular refs become `"[Circular]"` (or `{ $ref }` pointers when `decycle`).
|
|
12
|
+
*/
|
|
13
|
+
function safeStringify(value, options = {}) {
|
|
14
|
+
const { indent, deterministic = false, decycle = false, bigint = "string" } = options;
|
|
15
|
+
if (decycle) return JSON.stringify(decycleValue(value, bigint), void 0, indent);
|
|
16
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
17
|
+
const transform = (val) => {
|
|
18
|
+
if (typeof val === "bigint") return bigint === "number" ? Number(val) : val.toString();
|
|
19
|
+
if (typeof val === "function") return `[Function: ${val.name || "anonymous"}]`;
|
|
20
|
+
if (typeof val === "symbol") return val.toString();
|
|
21
|
+
if (val === null || typeof val !== "object") return val;
|
|
22
|
+
if (seen.has(val)) return "[Circular]";
|
|
23
|
+
seen.add(val);
|
|
24
|
+
let out;
|
|
25
|
+
const toJSON = val.toJSON;
|
|
26
|
+
if (Array.isArray(val)) out = val.map((item) => transform(item));
|
|
27
|
+
else if (typeof toJSON === "function") out = transform(toJSON.call(val));
|
|
28
|
+
else {
|
|
29
|
+
const rec = val;
|
|
30
|
+
const keys = deterministic ? Object.keys(rec).sort() : Object.keys(rec);
|
|
31
|
+
const obj = {};
|
|
32
|
+
for (const k of keys) {
|
|
33
|
+
if (k === "__proto__" || k === "constructor" || k === "prototype") continue;
|
|
34
|
+
obj[k] = transform(rec[k]);
|
|
35
|
+
}
|
|
36
|
+
out = obj;
|
|
37
|
+
}
|
|
38
|
+
seen.delete(val);
|
|
39
|
+
return out;
|
|
40
|
+
};
|
|
41
|
+
return JSON.stringify(transform(value), void 0, indent);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Replace repeated object references with round-trippable `{ "$ref": "$..." }`
|
|
45
|
+
* JSONPath pointers (the classic Crockford decycle). Pair with {@link retrocycle}
|
|
46
|
+
* to reconstruct the original shared/circular graph.
|
|
47
|
+
*/
|
|
48
|
+
function decycleValue(value, bigint = "string") {
|
|
49
|
+
const paths = /* @__PURE__ */ new WeakMap();
|
|
50
|
+
const walk = (val, path) => {
|
|
51
|
+
if (typeof val === "bigint") return bigint === "number" ? Number(val) : val.toString();
|
|
52
|
+
if (val === null || typeof val !== "object") return val;
|
|
53
|
+
if (val instanceof Date) return val.toISOString();
|
|
54
|
+
const existing = paths.get(val);
|
|
55
|
+
if (existing !== void 0) return { $ref: existing };
|
|
56
|
+
paths.set(val, jsonPath(path));
|
|
57
|
+
if (Array.isArray(val)) return val.map((item, i) => walk(item, [...path, i]));
|
|
58
|
+
const rec = val;
|
|
59
|
+
const obj = {};
|
|
60
|
+
for (const k of Object.keys(rec)) {
|
|
61
|
+
if (k === "__proto__" || k === "constructor" || k === "prototype") continue;
|
|
62
|
+
obj[k] = walk(rec[k], [...path, k]);
|
|
63
|
+
}
|
|
64
|
+
return obj;
|
|
65
|
+
};
|
|
66
|
+
return walk(value, []);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Inverse of {@link decycleValue}: resolve `{ "$ref": "$..." }` pointers back
|
|
70
|
+
* into the live object graph (mutates and returns the parsed input).
|
|
71
|
+
*/
|
|
72
|
+
function retrocycle(root) {
|
|
73
|
+
const refRe = /^\$(?:\[(?:\d+|"(?:[^"\\]|\\.)*")\])*$/;
|
|
74
|
+
const resolve = (path) => {
|
|
75
|
+
const segs = [];
|
|
76
|
+
const partRe = /\[(\d+|"(?:[^"\\]|\\.)*")\]/g;
|
|
77
|
+
let m;
|
|
78
|
+
while ((m = partRe.exec(path)) !== null) {
|
|
79
|
+
const raw = m[1];
|
|
80
|
+
segs.push(raw.startsWith("\"") ? JSON.parse(raw) : Number(raw));
|
|
81
|
+
}
|
|
82
|
+
let node = root;
|
|
83
|
+
for (const s of segs) node = node[s];
|
|
84
|
+
return node;
|
|
85
|
+
};
|
|
86
|
+
const walk = (val) => {
|
|
87
|
+
if (val === null || typeof val !== "object") return;
|
|
88
|
+
const rec = val;
|
|
89
|
+
for (const k of Object.keys(rec)) {
|
|
90
|
+
const child = rec[k];
|
|
91
|
+
if (child !== null && typeof child === "object" && typeof child.$ref === "string" && refRe.test(child.$ref)) rec[k] = resolve(child.$ref);
|
|
92
|
+
else walk(child);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
walk(root);
|
|
96
|
+
return root;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* `JSON.stringify` for log output. Takes the plain fast path first and only
|
|
100
|
+
* falls back to {@link safeStringify} when that throws (a cycle, a BigInt, a
|
|
101
|
+
* throwing `toJSON`), so a bad payload costs nothing until it shows up.
|
|
102
|
+
* Never throws: if even the safe walk fails, the value is replaced by a marker.
|
|
103
|
+
*/
|
|
104
|
+
function stringifyForLog(value) {
|
|
105
|
+
try {
|
|
106
|
+
return JSON.stringify(value);
|
|
107
|
+
} catch {
|
|
108
|
+
try {
|
|
109
|
+
return safeStringify(value);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
112
|
+
return JSON.stringify(`[Unserializable: ${reason}]`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
//#endregion
|
|
118
|
+
Object.defineProperty(exports, 'decycleValue', {
|
|
119
|
+
enumerable: true,
|
|
120
|
+
get: function () {
|
|
121
|
+
return decycleValue;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
Object.defineProperty(exports, 'retrocycle', {
|
|
125
|
+
enumerable: true,
|
|
126
|
+
get: function () {
|
|
127
|
+
return retrocycle;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
Object.defineProperty(exports, 'safeStringify', {
|
|
131
|
+
enumerable: true,
|
|
132
|
+
get: function () {
|
|
133
|
+
return safeStringify;
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
Object.defineProperty(exports, 'stringifyForLog', {
|
|
137
|
+
enumerable: true,
|
|
138
|
+
get: function () {
|
|
139
|
+
return stringifyForLog;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
//# sourceMappingURL=safe-stringify-DWo3aZp_.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-stringify-DWo3aZp_.js","names":["out: unknown","obj: Record<string, unknown>","segs: Array<string | number>","m: RegExpExecArray | null","node: unknown"],"sources":["../src/utils/safe-stringify.ts"],"sourcesContent":["/**\n * logixia — robust JSON serialization for log payloads.\n *\n * Modern Winston/Pino already neutralize circular refs to `[Circular]` (via\n * safe-stable-stringify / fast-safe-stringify), so merely \"surviving cycles\" is\n * not a differentiator. This goes one notch further:\n *\n * - **BigInt** → serialized (as a string by default; JSON.stringify throws on\n * BigInt, which silently breaks logging of e.g. DB bigint ids).\n * - **Deterministic key order** (optional) so identical objects hash/diff equal.\n * - **True decycle** (optional) — replace repeated references with JSONPath\n * `$ref` pointers that round-trip back to the original object graph, instead\n * of the lossy `[Circular]` tag. Useful when you need to reconstruct shared\n * structure downstream.\n *\n * @example\n * ```ts\n * safeStringify({ id: 10n, self: obj }); // → BigInt + cycle safe\n * safeStringify(graph, { decycle: true }); // → round-trippable $ref pointers\n * const back = retrocycle(JSON.parse(json)); // → reconstruct shared refs\n * ```\n */\n\nexport interface SafeStringifyOptions {\n /** Indentation passed to JSON.stringify (number of spaces or a string). */\n indent?: number | string;\n /** Sort object keys for deterministic output. Default: false. */\n deterministic?: boolean;\n /**\n * Use round-trippable `$ref` JSONPath pointers for repeated references instead\n * of the lossy \"[Circular]\" tag. Default: false.\n */\n decycle?: boolean;\n /** How to render BigInt: 'string' (default) or 'number' (may lose precision). */\n bigint?: 'string' | 'number';\n}\n\n/** Build a JSONPath like `$[\"a\"][0][\"b\"]` for a decycle pointer. */\nfunction jsonPath(parts: Array<string | number>): string {\n let path = '$';\n for (const p of parts) {\n path += typeof p === 'number' ? `[${p}]` : `[${JSON.stringify(p)}]`;\n }\n return path;\n}\n\n/**\n * Serialize any value to JSON without throwing on circular references or BigInt.\n * Circular refs become `\"[Circular]\"` (or `{ $ref }` pointers when `decycle`).\n */\nexport function safeStringify(value: unknown, options: SafeStringifyOptions = {}): string {\n const { indent, deterministic = false, decycle = false, bigint = 'string' } = options;\n\n if (decycle) {\n return JSON.stringify(decycleValue(value, bigint), undefined, indent);\n }\n\n const seen = new WeakSet<object>();\n\n const transform = (val: unknown): unknown => {\n if (typeof val === 'bigint') return bigint === 'number' ? Number(val) : val.toString();\n if (typeof val === 'function') return `[Function: ${val.name || 'anonymous'}]`;\n if (typeof val === 'symbol') return val.toString();\n if (val === null || typeof val !== 'object') return val;\n\n if (seen.has(val)) return '[Circular]';\n seen.add(val);\n\n let out: unknown;\n const toJSON = (val as { toJSON?: unknown }).toJSON;\n if (Array.isArray(val)) {\n out = val.map((item) => transform(item));\n } else if (typeof toJSON === 'function') {\n // Dates, URLs, Buffers and classes with their own toJSON print the way\n // JSON.stringify would; a toJSON that returns `this` hits the cycle check.\n out = transform(toJSON.call(val));\n } else {\n const rec = val as Record<string, unknown>;\n const keys = deterministic ? Object.keys(rec).sort() : Object.keys(rec);\n const obj: Record<string, unknown> = {};\n for (const k of keys) {\n if (k === '__proto__' || k === 'constructor' || k === 'prototype') continue;\n obj[k] = transform(rec[k]);\n }\n out = obj;\n }\n // Allow the same object to appear in sibling branches (not a true cycle):\n // remove from `seen` after we finish its subtree.\n seen.delete(val);\n return out;\n };\n\n return JSON.stringify(transform(value), undefined, indent);\n}\n\n/**\n * Replace repeated object references with round-trippable `{ \"$ref\": \"$...\" }`\n * JSONPath pointers (the classic Crockford decycle). Pair with {@link retrocycle}\n * to reconstruct the original shared/circular graph.\n */\nexport function decycleValue(value: unknown, bigint: 'string' | 'number' = 'string'): unknown {\n const paths = new WeakMap<object, string>();\n\n const walk = (val: unknown, path: Array<string | number>): unknown => {\n if (typeof val === 'bigint') return bigint === 'number' ? Number(val) : val.toString();\n if (val === null || typeof val !== 'object') return val;\n if (val instanceof Date) return val.toISOString();\n\n const existing = paths.get(val);\n if (existing !== undefined) return { $ref: existing };\n paths.set(val, jsonPath(path));\n\n if (Array.isArray(val)) {\n return val.map((item, i) => walk(item, [...path, i]));\n }\n const rec = val as Record<string, unknown>;\n const obj: Record<string, unknown> = {};\n for (const k of Object.keys(rec)) {\n if (k === '__proto__' || k === 'constructor' || k === 'prototype') continue;\n obj[k] = walk(rec[k], [...path, k]);\n }\n return obj;\n };\n\n return walk(value, []);\n}\n\n/**\n * Inverse of {@link decycleValue}: resolve `{ \"$ref\": \"$...\" }` pointers back\n * into the live object graph (mutates and returns the parsed input).\n */\nexport function retrocycle<T>(root: T): T {\n const refRe = /^\\$(?:\\[(?:\\d+|\"(?:[^\"\\\\]|\\\\.)*\")\\])*$/;\n\n const resolve = (path: string): unknown => {\n // Parse the JSONPath segments back out.\n const segs: Array<string | number> = [];\n const partRe = /\\[(\\d+|\"(?:[^\"\\\\]|\\\\.)*\")\\]/g;\n let m: RegExpExecArray | null;\n while ((m = partRe.exec(path)) !== null) {\n const raw = m[1]!;\n segs.push(raw.startsWith('\"') ? (JSON.parse(raw) as string) : Number(raw));\n }\n let node: unknown = root;\n for (const s of segs) {\n node = (node as Record<string | number, unknown>)[s];\n }\n return node;\n };\n\n const walk = (val: unknown): void => {\n if (val === null || typeof val !== 'object') return;\n const rec = val as Record<string, unknown>;\n for (const k of Object.keys(rec)) {\n const child = rec[k];\n if (\n child !== null &&\n typeof child === 'object' &&\n typeof (child as { $ref?: unknown }).$ref === 'string' &&\n refRe.test((child as { $ref: string }).$ref)\n ) {\n rec[k] = resolve((child as { $ref: string }).$ref);\n } else {\n walk(child);\n }\n }\n };\n\n walk(root);\n return root;\n}\n\n/**\n * `JSON.stringify` for log output. Takes the plain fast path first and only\n * falls back to {@link safeStringify} when that throws (a cycle, a BigInt, a\n * throwing `toJSON`), so a bad payload costs nothing until it shows up.\n * Never throws: if even the safe walk fails, the value is replaced by a marker.\n */\nexport function stringifyForLog(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n try {\n return safeStringify(value);\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return JSON.stringify(`[Unserializable: ${reason}]`);\n }\n }\n}\n"],"mappings":"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"}
|