ohbee-safe-json 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -76,7 +76,13 @@ function isRedactedKey(key, opts) {
76
76
  }
77
77
  return false;
78
78
  }
79
- function serializeError(err, opts, seen, depth) {
79
+ function circularRef(opts, seen, obj) {
80
+ if (opts.onCircular === "path") {
81
+ return `[Circular: ${seen.get(obj) ?? "?"}]`;
82
+ }
83
+ return "[Circular]";
84
+ }
85
+ function serializeError(err, opts, seen, depth, path) {
80
86
  const result = {
81
87
  name: err.name,
82
88
  message: err.message
@@ -85,7 +91,7 @@ function serializeError(err, opts, seen, depth) {
85
91
  result["stack"] = err.stack.length > opts.maxStringLength ? err.stack.slice(0, opts.maxStringLength) + "...[Truncated]" : err.stack;
86
92
  }
87
93
  if (err.cause !== void 0) {
88
- result["cause"] = walk(err.cause, opts, seen, depth + 1);
94
+ result["cause"] = walk(err.cause, opts, seen, depth + 1, `${path}.cause`);
89
95
  }
90
96
  for (const key of Object.keys(err)) {
91
97
  if (key in result) continue;
@@ -96,13 +102,14 @@ function serializeError(err, opts, seen, depth) {
96
102
  err[key],
97
103
  opts,
98
104
  seen,
99
- depth + 1
105
+ depth + 1,
106
+ `${path}.${key}`
100
107
  );
101
108
  }
102
109
  }
103
110
  return result;
104
111
  }
105
- function walk(value, opts, seen, depth) {
112
+ function walk(value, opts, seen, depth, path) {
106
113
  if (value === null) return null;
107
114
  if (value === void 0) return void 0;
108
115
  if (typeof value === "boolean" || typeof value === "number") return value;
@@ -132,33 +139,31 @@ function walk(value, opts, seen, depth) {
132
139
  if (depth > opts.maxDepth) return "[MaxDepth]";
133
140
  if (value instanceof Date) return value.toISOString();
134
141
  if (value instanceof Error) {
135
- if (seen.has(value)) {
136
- return opts.onCircular === "placeholder" ? "[Circular]" : "[Circular]";
137
- }
138
- seen.add(value);
139
- const result = serializeError(value, opts, seen, depth);
142
+ if (seen.has(value)) return circularRef(opts, seen, value);
143
+ seen.set(value, path);
144
+ const result = serializeError(value, opts, seen, depth, path);
140
145
  seen.delete(value);
141
146
  return result;
142
147
  }
143
148
  if (value instanceof Map) {
144
- if (seen.has(value)) return "[Circular]";
145
- seen.add(value);
149
+ if (seen.has(value)) return circularRef(opts, seen, value);
150
+ seen.set(value, path);
146
151
  const obj = {};
147
152
  let keyCount = 0;
148
153
  for (const [k, v] of value) {
149
154
  if (keyCount >= opts.maxObjectKeys) break;
150
155
  const keyStr = String(k);
151
- obj[keyStr] = isRedactedKey(keyStr, opts) ? opts.replacement : walk(v, opts, seen, depth + 1);
156
+ obj[keyStr] = isRedactedKey(keyStr, opts) ? opts.replacement : walk(v, opts, seen, depth + 1, `${path}.${keyStr}`);
152
157
  keyCount++;
153
158
  }
154
159
  seen.delete(value);
155
160
  return obj;
156
161
  }
157
162
  if (value instanceof Set) {
158
- if (seen.has(value)) return "[Circular]";
159
- seen.add(value);
163
+ if (seen.has(value)) return circularRef(opts, seen, value);
164
+ seen.set(value, path);
160
165
  const arr = [...value].slice(0, opts.maxArrayLength);
161
- const result = arr.map((v) => walk(v, opts, seen, depth + 1));
166
+ const result = arr.map((v, i) => walk(v, opts, seen, depth + 1, `${path}[${i}]`));
162
167
  if (value.size > opts.maxArrayLength) {
163
168
  result.push(`[Truncated ${value.size - opts.maxArrayLength} more items]`);
164
169
  }
@@ -166,10 +171,10 @@ function walk(value, opts, seen, depth) {
166
171
  return result;
167
172
  }
168
173
  if (Array.isArray(value)) {
169
- if (seen.has(value)) return "[Circular]";
170
- seen.add(value);
174
+ if (seen.has(value)) return circularRef(opts, seen, value);
175
+ seen.set(value, path);
171
176
  const slice = value.slice(0, opts.maxArrayLength);
172
- const result = slice.map((v) => walk(v, opts, seen, depth + 1));
177
+ const result = slice.map((v, i) => walk(v, opts, seen, depth + 1, `${path}[${i}]`));
173
178
  if (value.length > opts.maxArrayLength) {
174
179
  result.push(`[Truncated ${value.length - opts.maxArrayLength} more items]`);
175
180
  }
@@ -177,8 +182,8 @@ function walk(value, opts, seen, depth) {
177
182
  return result;
178
183
  }
179
184
  if (isPlainObject(value)) {
180
- if (seen.has(value)) return "[Circular]";
181
- seen.add(value);
185
+ if (seen.has(value)) return circularRef(opts, seen, value);
186
+ seen.set(value, path);
182
187
  const keys = opts.stable ? sortedKeys(value) : Object.keys(value);
183
188
  const result = {};
184
189
  let keyCount = 0;
@@ -187,7 +192,7 @@ function walk(value, opts, seen, depth) {
187
192
  if (isRedactedKey(key, opts)) {
188
193
  result[key] = opts.replacement;
189
194
  } else {
190
- const walked = walk(value[key], opts, seen, depth + 1);
195
+ const walked = walk(value[key], opts, seen, depth + 1, `${path}.${key}`);
191
196
  if (walked !== void 0) {
192
197
  result[key] = walked;
193
198
  }
@@ -198,8 +203,8 @@ function walk(value, opts, seen, depth) {
198
203
  return result;
199
204
  }
200
205
  if (typeof value === "object") {
201
- if (seen.has(value)) return "[Circular]";
202
- seen.add(value);
206
+ if (seen.has(value)) return circularRef(opts, seen, value);
207
+ seen.set(value, path);
203
208
  const keys = opts.stable ? Object.keys(value).sort() : Object.keys(value);
204
209
  const result = {};
205
210
  let keyCount = 0;
@@ -212,7 +217,8 @@ function walk(value, opts, seen, depth) {
212
217
  value[key],
213
218
  opts,
214
219
  seen,
215
- depth + 1
220
+ depth + 1,
221
+ `${path}.${key}`
216
222
  );
217
223
  if (walked !== void 0) {
218
224
  result[key] = walked;
@@ -225,16 +231,18 @@ function walk(value, opts, seen, depth) {
225
231
  }
226
232
  return value;
227
233
  }
234
+ function safeCloneResolved(value, opts) {
235
+ const seen = /* @__PURE__ */ new WeakMap();
236
+ return walk(value, opts, seen, 0, "$");
237
+ }
228
238
  function safeClone(value, options) {
229
- const opts = resolveOptions(options);
230
- const seen = /* @__PURE__ */ new WeakSet();
231
- return walk(value, opts, seen, 0);
239
+ return safeCloneResolved(value, resolveOptions(options));
232
240
  }
233
241
 
234
242
  // src/safe-stringify.ts
235
243
  function safeStringify(value, options) {
236
244
  const opts = resolveOptions(options);
237
- const cloned = safeClone(value, options);
245
+ const cloned = safeCloneResolved(value, opts);
238
246
  const indent = opts.pretty === true ? 2 : opts.pretty === false ? void 0 : opts.pretty;
239
247
  return JSON.stringify(cloned, null, indent) ?? "undefined";
240
248
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/is-plain-object.ts","../src/utils/stable-sort.ts","../src/safe-clone.ts","../src/safe-stringify.ts","../src/redact.ts","../src/presets.ts","../src/create-safe-json.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto = Object.getPrototypeOf(value) as unknown;\n return proto === Object.prototype || proto === null;\n}\n","export function sortedKeys(obj: Record<string, unknown>): string[] {\n return Object.keys(obj).sort();\n}\n","import type { ResolvedOptions, SafeJsonOptions } from \"./types.js\";\nimport { isPlainObject } from \"./utils/is-plain-object.js\";\nimport { sortedKeys } from \"./utils/stable-sort.js\";\n\nconst DEFAULT_REDACT_KEYS = [\n \"password\",\n \"pass\",\n \"pwd\",\n \"secret\",\n \"token\",\n \"accesstoken\",\n \"refreshtoken\",\n \"authorization\",\n \"cookie\",\n \"set-cookie\",\n \"apikey\",\n \"privatekey\",\n \"otp\",\n \"pin\",\n \"cardnumber\",\n \"cvv\",\n];\n\nconst DEFAULTS: ResolvedOptions = {\n redactKeys: DEFAULT_REDACT_KEYS,\n redactByPattern: [],\n replacement: \"[REDACTED]\",\n maxDepth: 6,\n maxArrayLength: 100,\n maxObjectKeys: 100,\n maxStringLength: 4000,\n includeErrorStack: false,\n stable: false,\n pretty: false,\n handleBigInt: \"string\",\n handleFunction: \"omit\",\n handleSymbol: \"omit\",\n onCircular: \"placeholder\",\n};\n\nexport function resolveOptions(options?: SafeJsonOptions): ResolvedOptions {\n if (!options) return DEFAULTS;\n\n const userKeys = options.redactKeys?.map((k) => k.toLowerCase()) ?? [];\n const mergedKeys = [...DEFAULT_REDACT_KEYS, ...userKeys];\n\n return {\n redactKeys: mergedKeys,\n redactByPattern: options.redactByPattern ?? DEFAULTS.redactByPattern,\n replacement: options.replacement ?? DEFAULTS.replacement,\n maxDepth: options.maxDepth ?? DEFAULTS.maxDepth,\n maxArrayLength: options.maxArrayLength ?? DEFAULTS.maxArrayLength,\n maxObjectKeys: options.maxObjectKeys ?? DEFAULTS.maxObjectKeys,\n maxStringLength: options.maxStringLength ?? DEFAULTS.maxStringLength,\n includeErrorStack: options.includeErrorStack ?? DEFAULTS.includeErrorStack,\n stable: options.stable ?? DEFAULTS.stable,\n pretty: options.pretty ?? DEFAULTS.pretty,\n handleBigInt: options.handleBigInt ?? DEFAULTS.handleBigInt,\n handleFunction: options.handleFunction ?? DEFAULTS.handleFunction,\n handleSymbol: options.handleSymbol ?? DEFAULTS.handleSymbol,\n onCircular: options.onCircular ?? DEFAULTS.onCircular,\n };\n}\n\nfunction isRedactedKey(key: string, opts: ResolvedOptions): boolean {\n const lower = key.toLowerCase();\n if (opts.redactKeys.includes(lower)) return true;\n for (const pattern of opts.redactByPattern) {\n if (pattern.test(key)) return true;\n }\n return false;\n}\n\nfunction serializeError(\n err: Error,\n opts: ResolvedOptions,\n seen: WeakSet<object>,\n depth: number\n): Record<string, unknown> {\n const result: Record<string, unknown> = {\n name: err.name,\n message: err.message,\n };\n\n if (opts.includeErrorStack && err.stack) {\n result[\"stack\"] =\n err.stack.length > opts.maxStringLength\n ? err.stack.slice(0, opts.maxStringLength) + \"...[Truncated]\"\n : err.stack;\n }\n\n if (err.cause !== undefined) {\n result[\"cause\"] = walk(err.cause, opts, seen, depth + 1);\n }\n\n for (const key of Object.keys(err)) {\n if (key in result) continue;\n if (isRedactedKey(key, opts)) {\n result[key] = opts.replacement;\n } else {\n result[key] = walk(\n (err as unknown as Record<string, unknown>)[key],\n opts,\n seen,\n depth + 1\n );\n }\n }\n\n return result;\n}\n\nfunction walk(\n value: unknown,\n opts: ResolvedOptions,\n seen: WeakSet<object>,\n depth: number\n): unknown {\n // primitives\n if (value === null) return null;\n if (value === undefined) return undefined;\n\n if (typeof value === \"boolean\" || typeof value === \"number\") return value;\n\n if (typeof value === \"string\") {\n if (value.length > opts.maxStringLength) {\n return value.slice(0, opts.maxStringLength) + \"...[Truncated]\";\n }\n return value;\n }\n\n if (typeof value === \"bigint\") {\n if (opts.handleBigInt === \"redact\") return opts.replacement;\n if (opts.handleBigInt === \"number\") return Number(value);\n return value.toString();\n }\n\n if (typeof value === \"function\") {\n if (opts.handleFunction === \"omit\") return undefined;\n if (opts.handleFunction === \"name\")\n return value.name ? `[Function: ${value.name}]` : \"[Function]\";\n return \"[Function]\";\n }\n\n if (typeof value === \"symbol\") {\n if (opts.handleSymbol === \"omit\") return undefined;\n if (opts.handleSymbol === \"description\")\n return value.description ?? \"[Symbol]\";\n return \"[Symbol]\";\n }\n\n // objects\n if (depth > opts.maxDepth) return \"[MaxDepth]\";\n\n if (value instanceof Date) return value.toISOString();\n\n if (value instanceof Error) {\n if (seen.has(value)) {\n return opts.onCircular === \"placeholder\" ? \"[Circular]\" : \"[Circular]\";\n }\n seen.add(value);\n const result = serializeError(value, opts, seen, depth);\n seen.delete(value);\n return result;\n }\n\n if (value instanceof Map) {\n if (seen.has(value)) return \"[Circular]\";\n seen.add(value);\n const obj: Record<string, unknown> = {};\n let keyCount = 0;\n for (const [k, v] of value) {\n if (keyCount >= opts.maxObjectKeys) break;\n const keyStr = String(k);\n obj[keyStr] = isRedactedKey(keyStr, opts)\n ? opts.replacement\n : walk(v, opts, seen, depth + 1);\n keyCount++;\n }\n seen.delete(value);\n return obj;\n }\n\n if (value instanceof Set) {\n if (seen.has(value)) return \"[Circular]\";\n seen.add(value);\n const arr = [...value].slice(0, opts.maxArrayLength);\n const result = arr.map((v) => walk(v, opts, seen, depth + 1));\n if (value.size > opts.maxArrayLength) {\n result.push(`[Truncated ${value.size - opts.maxArrayLength} more items]`);\n }\n seen.delete(value);\n return result;\n }\n\n if (Array.isArray(value)) {\n if (seen.has(value)) return \"[Circular]\";\n seen.add(value);\n const slice = value.slice(0, opts.maxArrayLength);\n const result = slice.map((v) => walk(v, opts, seen, depth + 1));\n if (value.length > opts.maxArrayLength) {\n result.push(`[Truncated ${value.length - opts.maxArrayLength} more items]`);\n }\n seen.delete(value);\n return result;\n }\n\n if (isPlainObject(value)) {\n if (seen.has(value)) return \"[Circular]\";\n seen.add(value);\n\n const keys = opts.stable ? sortedKeys(value) : Object.keys(value);\n const result: Record<string, unknown> = {};\n let keyCount = 0;\n\n for (const key of keys) {\n if (keyCount >= opts.maxObjectKeys) break;\n if (isRedactedKey(key, opts)) {\n result[key] = opts.replacement;\n } else {\n const walked = walk(value[key], opts, seen, depth + 1);\n if (walked !== undefined) {\n result[key] = walked;\n }\n }\n keyCount++;\n }\n\n seen.delete(value);\n return result;\n }\n\n // non-plain objects (class instances) — treat as plain, extract own enumerable keys\n if (typeof value === \"object\") {\n if (seen.has(value as object)) return \"[Circular]\";\n seen.add(value as object);\n\n const keys = opts.stable\n ? Object.keys(value as object).sort()\n : Object.keys(value as object);\n const result: Record<string, unknown> = {};\n let keyCount = 0;\n\n for (const key of keys) {\n if (keyCount >= opts.maxObjectKeys) break;\n if (isRedactedKey(key, opts)) {\n result[key] = opts.replacement;\n } else {\n const walked = walk(\n (value as Record<string, unknown>)[key],\n opts,\n seen,\n depth + 1\n );\n if (walked !== undefined) {\n result[key] = walked;\n }\n }\n keyCount++;\n }\n\n seen.delete(value as object);\n return result;\n }\n\n return value;\n}\n\nexport function safeClone(value: unknown, options?: SafeJsonOptions): unknown {\n const opts = resolveOptions(options);\n const seen = new WeakSet<object>();\n return walk(value, opts, seen, 0);\n}\n","import type { SafeJsonOptions } from \"./types.js\";\nimport { safeClone, resolveOptions } from \"./safe-clone.js\";\n\nexport function safeStringify(value: unknown, options?: SafeJsonOptions): string {\n const opts = resolveOptions(options);\n const cloned = safeClone(value, options);\n const indent = opts.pretty === true ? 2 : opts.pretty === false ? undefined : opts.pretty;\n return JSON.stringify(cloned, null, indent) ?? \"undefined\";\n}\n","import type { SafeJsonOptions } from \"./types.js\";\nimport { safeClone } from \"./safe-clone.js\";\n\nexport type RedactOptions = {\n keys?: string[];\n pattern?: RegExp[];\n replacement?: string;\n};\n\nexport function redact(value: unknown, options?: RedactOptions): unknown {\n const opts: SafeJsonOptions = {};\n if (options?.keys !== undefined) opts.redactKeys = options.keys;\n if (options?.pattern !== undefined) opts.redactByPattern = options.pattern;\n if (options?.replacement !== undefined) opts.replacement = options.replacement;\n return safeClone(value, opts);\n}\n","import type { SafeJsonOptions } from \"./types.js\";\n\nexport const presets = {\n log: {\n maxDepth: 5,\n maxArrayLength: 50,\n maxStringLength: 2000,\n includeErrorStack: false,\n stable: false,\n } satisfies SafeJsonOptions,\n\n debug: {\n maxDepth: 8,\n maxArrayLength: 200,\n maxStringLength: 8000,\n includeErrorStack: true,\n stable: false,\n } satisfies SafeJsonOptions,\n\n http: {\n maxDepth: 5,\n maxArrayLength: 50,\n maxStringLength: 2000,\n includeErrorStack: false,\n stable: false,\n redactKeys: [\"headers\", \"cookie\", \"set-cookie\", \"authorization\"],\n } satisfies SafeJsonOptions,\n\n audit: {\n maxDepth: 5,\n maxArrayLength: 100,\n maxStringLength: 4000,\n includeErrorStack: false,\n stable: true,\n } satisfies SafeJsonOptions,\n} as const;\n","import type { SafeJsonOptions, SafeJsonInstance } from \"./types.js\";\nimport { safeClone } from \"./safe-clone.js\";\nimport { safeStringify } from \"./safe-stringify.js\";\nimport { presets } from \"./presets.js\";\n\nexport function createSafeJson(base: SafeJsonOptions = {}): SafeJsonInstance {\n function merge(overrides?: SafeJsonOptions): SafeJsonOptions {\n if (!overrides) return base;\n const mergedKeys = [\n ...(base.redactKeys ?? []),\n ...(overrides.redactKeys ?? []),\n ];\n const mergedPatterns = [\n ...(base.redactByPattern ?? []),\n ...(overrides.redactByPattern ?? []),\n ];\n const merged: SafeJsonOptions = { ...base, ...overrides };\n if (mergedKeys.length > 0) merged.redactKeys = mergedKeys;\n if (mergedPatterns.length > 0) merged.redactByPattern = mergedPatterns;\n return merged;\n }\n\n return {\n stringify(value, overrides) {\n return safeStringify(value, merge(overrides));\n },\n clone(value, overrides) {\n return safeClone(value, merge(overrides));\n },\n forLog(value) {\n return safeClone(value, merge(presets.log));\n },\n forDebug(value) {\n return safeClone(value, merge(presets.debug));\n },\n forHttp(value) {\n return safeClone(value, merge(presets.http));\n },\n forAudit(value) {\n return safeClone(value, merge(presets.audit));\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/is-plain-object.ts","../src/utils/stable-sort.ts","../src/safe-clone.ts","../src/safe-stringify.ts","../src/redact.ts","../src/presets.ts","../src/create-safe-json.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto = Object.getPrototypeOf(value) as unknown;\n return proto === Object.prototype || proto === null;\n}\n","export function sortedKeys(obj: Record<string, unknown>): string[] {\n return Object.keys(obj).sort();\n}\n","import type { ResolvedOptions, SafeJsonOptions } from \"./types.js\";\nimport { isPlainObject } from \"./utils/is-plain-object.js\";\nimport { sortedKeys } from \"./utils/stable-sort.js\";\n\nconst DEFAULT_REDACT_KEYS = [\n \"password\",\n \"pass\",\n \"pwd\",\n \"secret\",\n \"token\",\n \"accesstoken\",\n \"refreshtoken\",\n \"authorization\",\n \"cookie\",\n \"set-cookie\",\n \"apikey\",\n \"privatekey\",\n \"otp\",\n \"pin\",\n \"cardnumber\",\n \"cvv\",\n];\n\nconst DEFAULTS: ResolvedOptions = {\n redactKeys: DEFAULT_REDACT_KEYS,\n redactByPattern: [],\n replacement: \"[REDACTED]\",\n maxDepth: 6,\n maxArrayLength: 100,\n maxObjectKeys: 100,\n maxStringLength: 4000,\n includeErrorStack: false,\n stable: false,\n pretty: false,\n handleBigInt: \"string\",\n handleFunction: \"omit\",\n handleSymbol: \"omit\",\n onCircular: \"placeholder\",\n};\n\nexport function resolveOptions(options?: SafeJsonOptions): ResolvedOptions {\n if (!options) return DEFAULTS;\n\n const userKeys = options.redactKeys?.map((k) => k.toLowerCase()) ?? [];\n const mergedKeys = [...DEFAULT_REDACT_KEYS, ...userKeys];\n\n return {\n redactKeys: mergedKeys,\n redactByPattern: options.redactByPattern ?? DEFAULTS.redactByPattern,\n replacement: options.replacement ?? DEFAULTS.replacement,\n maxDepth: options.maxDepth ?? DEFAULTS.maxDepth,\n maxArrayLength: options.maxArrayLength ?? DEFAULTS.maxArrayLength,\n maxObjectKeys: options.maxObjectKeys ?? DEFAULTS.maxObjectKeys,\n maxStringLength: options.maxStringLength ?? DEFAULTS.maxStringLength,\n includeErrorStack: options.includeErrorStack ?? DEFAULTS.includeErrorStack,\n stable: options.stable ?? DEFAULTS.stable,\n pretty: options.pretty ?? DEFAULTS.pretty,\n handleBigInt: options.handleBigInt ?? DEFAULTS.handleBigInt,\n handleFunction: options.handleFunction ?? DEFAULTS.handleFunction,\n handleSymbol: options.handleSymbol ?? DEFAULTS.handleSymbol,\n onCircular: options.onCircular ?? DEFAULTS.onCircular,\n };\n}\n\nfunction isRedactedKey(key: string, opts: ResolvedOptions): boolean {\n const lower = key.toLowerCase();\n if (opts.redactKeys.includes(lower)) return true;\n for (const pattern of opts.redactByPattern) {\n if (pattern.test(key)) return true;\n }\n return false;\n}\n\nfunction circularRef(\n opts: ResolvedOptions,\n seen: WeakMap<object, string>,\n obj: object\n): string {\n if (opts.onCircular === \"path\") {\n return `[Circular: ${seen.get(obj) ?? \"?\"}]`;\n }\n return \"[Circular]\";\n}\n\nfunction serializeError(\n err: Error,\n opts: ResolvedOptions,\n seen: WeakMap<object, string>,\n depth: number,\n path: string\n): Record<string, unknown> {\n const result: Record<string, unknown> = {\n name: err.name,\n message: err.message,\n };\n\n if (opts.includeErrorStack && err.stack) {\n result[\"stack\"] =\n err.stack.length > opts.maxStringLength\n ? err.stack.slice(0, opts.maxStringLength) + \"...[Truncated]\"\n : err.stack;\n }\n\n if (err.cause !== undefined) {\n result[\"cause\"] = walk(err.cause, opts, seen, depth + 1, `${path}.cause`);\n }\n\n for (const key of Object.keys(err)) {\n if (key in result) continue;\n if (isRedactedKey(key, opts)) {\n result[key] = opts.replacement;\n } else {\n result[key] = walk(\n (err as unknown as Record<string, unknown>)[key],\n opts,\n seen,\n depth + 1,\n `${path}.${key}`\n );\n }\n }\n\n return result;\n}\n\nfunction walk(\n value: unknown,\n opts: ResolvedOptions,\n seen: WeakMap<object, string>,\n depth: number,\n path: string\n): unknown {\n // primitives\n if (value === null) return null;\n if (value === undefined) return undefined;\n\n if (typeof value === \"boolean\" || typeof value === \"number\") return value;\n\n if (typeof value === \"string\") {\n if (value.length > opts.maxStringLength) {\n return value.slice(0, opts.maxStringLength) + \"...[Truncated]\";\n }\n return value;\n }\n\n if (typeof value === \"bigint\") {\n if (opts.handleBigInt === \"redact\") return opts.replacement;\n if (opts.handleBigInt === \"number\") return Number(value);\n return value.toString();\n }\n\n if (typeof value === \"function\") {\n if (opts.handleFunction === \"omit\") return undefined;\n if (opts.handleFunction === \"name\")\n return value.name ? `[Function: ${value.name}]` : \"[Function]\";\n return \"[Function]\";\n }\n\n if (typeof value === \"symbol\") {\n if (opts.handleSymbol === \"omit\") return undefined;\n if (opts.handleSymbol === \"description\")\n return value.description ?? \"[Symbol]\";\n return \"[Symbol]\";\n }\n\n // objects\n if (depth > opts.maxDepth) return \"[MaxDepth]\";\n\n if (value instanceof Date) return value.toISOString();\n\n if (value instanceof Error) {\n if (seen.has(value)) return circularRef(opts, seen, value);\n seen.set(value, path);\n const result = serializeError(value, opts, seen, depth, path);\n seen.delete(value);\n return result;\n }\n\n if (value instanceof Map) {\n if (seen.has(value)) return circularRef(opts, seen, value);\n seen.set(value, path);\n const obj: Record<string, unknown> = {};\n let keyCount = 0;\n for (const [k, v] of value) {\n if (keyCount >= opts.maxObjectKeys) break;\n const keyStr = String(k);\n obj[keyStr] = isRedactedKey(keyStr, opts)\n ? opts.replacement\n : walk(v, opts, seen, depth + 1, `${path}.${keyStr}`);\n keyCount++;\n }\n seen.delete(value);\n return obj;\n }\n\n if (value instanceof Set) {\n if (seen.has(value)) return circularRef(opts, seen, value);\n seen.set(value, path);\n const arr = [...value].slice(0, opts.maxArrayLength);\n const result = arr.map((v, i) => walk(v, opts, seen, depth + 1, `${path}[${i}]`));\n if (value.size > opts.maxArrayLength) {\n result.push(`[Truncated ${value.size - opts.maxArrayLength} more items]`);\n }\n seen.delete(value);\n return result;\n }\n\n if (Array.isArray(value)) {\n if (seen.has(value)) return circularRef(opts, seen, value);\n seen.set(value, path);\n const slice = value.slice(0, opts.maxArrayLength);\n const result = slice.map((v, i) => walk(v, opts, seen, depth + 1, `${path}[${i}]`));\n if (value.length > opts.maxArrayLength) {\n result.push(`[Truncated ${value.length - opts.maxArrayLength} more items]`);\n }\n seen.delete(value);\n return result;\n }\n\n if (isPlainObject(value)) {\n if (seen.has(value)) return circularRef(opts, seen, value);\n seen.set(value, path);\n\n const keys = opts.stable ? sortedKeys(value) : Object.keys(value);\n const result: Record<string, unknown> = {};\n let keyCount = 0;\n\n for (const key of keys) {\n if (keyCount >= opts.maxObjectKeys) break;\n if (isRedactedKey(key, opts)) {\n result[key] = opts.replacement;\n } else {\n const walked = walk(value[key], opts, seen, depth + 1, `${path}.${key}`);\n if (walked !== undefined) {\n result[key] = walked;\n }\n }\n keyCount++;\n }\n\n seen.delete(value);\n return result;\n }\n\n // non-plain objects (class instances) — treat as plain, extract own enumerable keys\n if (typeof value === \"object\") {\n if (seen.has(value as object)) return circularRef(opts, seen, value as object);\n seen.set(value as object, path);\n\n const keys = opts.stable\n ? Object.keys(value as object).sort()\n : Object.keys(value as object);\n const result: Record<string, unknown> = {};\n let keyCount = 0;\n\n for (const key of keys) {\n if (keyCount >= opts.maxObjectKeys) break;\n if (isRedactedKey(key, opts)) {\n result[key] = opts.replacement;\n } else {\n const walked = walk(\n (value as Record<string, unknown>)[key],\n opts,\n seen,\n depth + 1,\n `${path}.${key}`\n );\n if (walked !== undefined) {\n result[key] = walked;\n }\n }\n keyCount++;\n }\n\n seen.delete(value as object);\n return result;\n }\n\n return value;\n}\n\nexport function safeCloneResolved(value: unknown, opts: ResolvedOptions): unknown {\n const seen = new WeakMap<object, string>();\n return walk(value, opts, seen, 0, \"$\");\n}\n\nexport function safeClone(value: unknown, options?: SafeJsonOptions): unknown {\n return safeCloneResolved(value, resolveOptions(options));\n}\n","import type { SafeJsonOptions } from \"./types.js\";\nimport { resolveOptions, safeCloneResolved } from \"./safe-clone.js\";\n\nexport function safeStringify(value: unknown, options?: SafeJsonOptions): string {\n const opts = resolveOptions(options);\n const cloned = safeCloneResolved(value, opts);\n const indent = opts.pretty === true ? 2 : opts.pretty === false ? undefined : opts.pretty;\n return JSON.stringify(cloned, null, indent) ?? \"undefined\";\n}\n","import type { SafeJsonOptions } from \"./types.js\";\nimport { safeClone } from \"./safe-clone.js\";\n\nexport type RedactOptions = {\n keys?: string[];\n pattern?: RegExp[];\n replacement?: string;\n};\n\nexport function redact(value: unknown, options?: RedactOptions): unknown {\n const opts: SafeJsonOptions = {};\n if (options?.keys !== undefined) opts.redactKeys = options.keys;\n if (options?.pattern !== undefined) opts.redactByPattern = options.pattern;\n if (options?.replacement !== undefined) opts.replacement = options.replacement;\n return safeClone(value, opts);\n}\n","import type { SafeJsonOptions } from \"./types.js\";\n\nexport const presets = {\n log: {\n maxDepth: 5,\n maxArrayLength: 50,\n maxStringLength: 2000,\n includeErrorStack: false,\n stable: false,\n } satisfies SafeJsonOptions,\n\n debug: {\n maxDepth: 8,\n maxArrayLength: 200,\n maxStringLength: 8000,\n includeErrorStack: true,\n stable: false,\n } satisfies SafeJsonOptions,\n\n http: {\n maxDepth: 5,\n maxArrayLength: 50,\n maxStringLength: 2000,\n includeErrorStack: false,\n stable: false,\n redactKeys: [\"headers\", \"cookie\", \"set-cookie\", \"authorization\"],\n } satisfies SafeJsonOptions,\n\n audit: {\n maxDepth: 5,\n maxArrayLength: 100,\n maxStringLength: 4000,\n includeErrorStack: false,\n stable: true,\n } satisfies SafeJsonOptions,\n} as const;\n","import type { SafeJsonOptions, SafeJsonInstance } from \"./types.js\";\nimport { safeClone } from \"./safe-clone.js\";\nimport { safeStringify } from \"./safe-stringify.js\";\nimport { presets } from \"./presets.js\";\n\nexport function createSafeJson(base: SafeJsonOptions = {}): SafeJsonInstance {\n function merge(overrides?: SafeJsonOptions): SafeJsonOptions {\n if (!overrides) return base;\n const mergedKeys = [\n ...(base.redactKeys ?? []),\n ...(overrides.redactKeys ?? []),\n ];\n const mergedPatterns = [\n ...(base.redactByPattern ?? []),\n ...(overrides.redactByPattern ?? []),\n ];\n const merged: SafeJsonOptions = { ...base, ...overrides };\n if (mergedKeys.length > 0) merged.redactKeys = mergedKeys;\n if (mergedPatterns.length > 0) merged.redactByPattern = mergedPatterns;\n return merged;\n }\n\n return {\n stringify(value, overrides) {\n return safeStringify(value, merge(overrides));\n },\n clone(value, overrides) {\n return safeClone(value, merge(overrides));\n },\n forLog(value) {\n return safeClone(value, merge(presets.log));\n },\n forDebug(value) {\n return safeClone(value, merge(presets.debug));\n },\n forHttp(value) {\n return safeClone(value, merge(presets.http));\n },\n forAudit(value) {\n return safeClone(value, merge(presets.audit));\n },\n };\n}\n"]}
package/dist/index.js CHANGED
@@ -74,7 +74,13 @@ function isRedactedKey(key, opts) {
74
74
  }
75
75
  return false;
76
76
  }
77
- function serializeError(err, opts, seen, depth) {
77
+ function circularRef(opts, seen, obj) {
78
+ if (opts.onCircular === "path") {
79
+ return `[Circular: ${seen.get(obj) ?? "?"}]`;
80
+ }
81
+ return "[Circular]";
82
+ }
83
+ function serializeError(err, opts, seen, depth, path) {
78
84
  const result = {
79
85
  name: err.name,
80
86
  message: err.message
@@ -83,7 +89,7 @@ function serializeError(err, opts, seen, depth) {
83
89
  result["stack"] = err.stack.length > opts.maxStringLength ? err.stack.slice(0, opts.maxStringLength) + "...[Truncated]" : err.stack;
84
90
  }
85
91
  if (err.cause !== void 0) {
86
- result["cause"] = walk(err.cause, opts, seen, depth + 1);
92
+ result["cause"] = walk(err.cause, opts, seen, depth + 1, `${path}.cause`);
87
93
  }
88
94
  for (const key of Object.keys(err)) {
89
95
  if (key in result) continue;
@@ -94,13 +100,14 @@ function serializeError(err, opts, seen, depth) {
94
100
  err[key],
95
101
  opts,
96
102
  seen,
97
- depth + 1
103
+ depth + 1,
104
+ `${path}.${key}`
98
105
  );
99
106
  }
100
107
  }
101
108
  return result;
102
109
  }
103
- function walk(value, opts, seen, depth) {
110
+ function walk(value, opts, seen, depth, path) {
104
111
  if (value === null) return null;
105
112
  if (value === void 0) return void 0;
106
113
  if (typeof value === "boolean" || typeof value === "number") return value;
@@ -130,33 +137,31 @@ function walk(value, opts, seen, depth) {
130
137
  if (depth > opts.maxDepth) return "[MaxDepth]";
131
138
  if (value instanceof Date) return value.toISOString();
132
139
  if (value instanceof Error) {
133
- if (seen.has(value)) {
134
- return opts.onCircular === "placeholder" ? "[Circular]" : "[Circular]";
135
- }
136
- seen.add(value);
137
- const result = serializeError(value, opts, seen, depth);
140
+ if (seen.has(value)) return circularRef(opts, seen, value);
141
+ seen.set(value, path);
142
+ const result = serializeError(value, opts, seen, depth, path);
138
143
  seen.delete(value);
139
144
  return result;
140
145
  }
141
146
  if (value instanceof Map) {
142
- if (seen.has(value)) return "[Circular]";
143
- seen.add(value);
147
+ if (seen.has(value)) return circularRef(opts, seen, value);
148
+ seen.set(value, path);
144
149
  const obj = {};
145
150
  let keyCount = 0;
146
151
  for (const [k, v] of value) {
147
152
  if (keyCount >= opts.maxObjectKeys) break;
148
153
  const keyStr = String(k);
149
- obj[keyStr] = isRedactedKey(keyStr, opts) ? opts.replacement : walk(v, opts, seen, depth + 1);
154
+ obj[keyStr] = isRedactedKey(keyStr, opts) ? opts.replacement : walk(v, opts, seen, depth + 1, `${path}.${keyStr}`);
150
155
  keyCount++;
151
156
  }
152
157
  seen.delete(value);
153
158
  return obj;
154
159
  }
155
160
  if (value instanceof Set) {
156
- if (seen.has(value)) return "[Circular]";
157
- seen.add(value);
161
+ if (seen.has(value)) return circularRef(opts, seen, value);
162
+ seen.set(value, path);
158
163
  const arr = [...value].slice(0, opts.maxArrayLength);
159
- const result = arr.map((v) => walk(v, opts, seen, depth + 1));
164
+ const result = arr.map((v, i) => walk(v, opts, seen, depth + 1, `${path}[${i}]`));
160
165
  if (value.size > opts.maxArrayLength) {
161
166
  result.push(`[Truncated ${value.size - opts.maxArrayLength} more items]`);
162
167
  }
@@ -164,10 +169,10 @@ function walk(value, opts, seen, depth) {
164
169
  return result;
165
170
  }
166
171
  if (Array.isArray(value)) {
167
- if (seen.has(value)) return "[Circular]";
168
- seen.add(value);
172
+ if (seen.has(value)) return circularRef(opts, seen, value);
173
+ seen.set(value, path);
169
174
  const slice = value.slice(0, opts.maxArrayLength);
170
- const result = slice.map((v) => walk(v, opts, seen, depth + 1));
175
+ const result = slice.map((v, i) => walk(v, opts, seen, depth + 1, `${path}[${i}]`));
171
176
  if (value.length > opts.maxArrayLength) {
172
177
  result.push(`[Truncated ${value.length - opts.maxArrayLength} more items]`);
173
178
  }
@@ -175,8 +180,8 @@ function walk(value, opts, seen, depth) {
175
180
  return result;
176
181
  }
177
182
  if (isPlainObject(value)) {
178
- if (seen.has(value)) return "[Circular]";
179
- seen.add(value);
183
+ if (seen.has(value)) return circularRef(opts, seen, value);
184
+ seen.set(value, path);
180
185
  const keys = opts.stable ? sortedKeys(value) : Object.keys(value);
181
186
  const result = {};
182
187
  let keyCount = 0;
@@ -185,7 +190,7 @@ function walk(value, opts, seen, depth) {
185
190
  if (isRedactedKey(key, opts)) {
186
191
  result[key] = opts.replacement;
187
192
  } else {
188
- const walked = walk(value[key], opts, seen, depth + 1);
193
+ const walked = walk(value[key], opts, seen, depth + 1, `${path}.${key}`);
189
194
  if (walked !== void 0) {
190
195
  result[key] = walked;
191
196
  }
@@ -196,8 +201,8 @@ function walk(value, opts, seen, depth) {
196
201
  return result;
197
202
  }
198
203
  if (typeof value === "object") {
199
- if (seen.has(value)) return "[Circular]";
200
- seen.add(value);
204
+ if (seen.has(value)) return circularRef(opts, seen, value);
205
+ seen.set(value, path);
201
206
  const keys = opts.stable ? Object.keys(value).sort() : Object.keys(value);
202
207
  const result = {};
203
208
  let keyCount = 0;
@@ -210,7 +215,8 @@ function walk(value, opts, seen, depth) {
210
215
  value[key],
211
216
  opts,
212
217
  seen,
213
- depth + 1
218
+ depth + 1,
219
+ `${path}.${key}`
214
220
  );
215
221
  if (walked !== void 0) {
216
222
  result[key] = walked;
@@ -223,16 +229,18 @@ function walk(value, opts, seen, depth) {
223
229
  }
224
230
  return value;
225
231
  }
232
+ function safeCloneResolved(value, opts) {
233
+ const seen = /* @__PURE__ */ new WeakMap();
234
+ return walk(value, opts, seen, 0, "$");
235
+ }
226
236
  function safeClone(value, options) {
227
- const opts = resolveOptions(options);
228
- const seen = /* @__PURE__ */ new WeakSet();
229
- return walk(value, opts, seen, 0);
237
+ return safeCloneResolved(value, resolveOptions(options));
230
238
  }
231
239
 
232
240
  // src/safe-stringify.ts
233
241
  function safeStringify(value, options) {
234
242
  const opts = resolveOptions(options);
235
- const cloned = safeClone(value, options);
243
+ const cloned = safeCloneResolved(value, opts);
236
244
  const indent = opts.pretty === true ? 2 : opts.pretty === false ? void 0 : opts.pretty;
237
245
  return JSON.stringify(cloned, null, indent) ?? "undefined";
238
246
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/is-plain-object.ts","../src/utils/stable-sort.ts","../src/safe-clone.ts","../src/safe-stringify.ts","../src/redact.ts","../src/presets.ts","../src/create-safe-json.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto = Object.getPrototypeOf(value) as unknown;\n return proto === Object.prototype || proto === null;\n}\n","export function sortedKeys(obj: Record<string, unknown>): string[] {\n return Object.keys(obj).sort();\n}\n","import type { ResolvedOptions, SafeJsonOptions } from \"./types.js\";\nimport { isPlainObject } from \"./utils/is-plain-object.js\";\nimport { sortedKeys } from \"./utils/stable-sort.js\";\n\nconst DEFAULT_REDACT_KEYS = [\n \"password\",\n \"pass\",\n \"pwd\",\n \"secret\",\n \"token\",\n \"accesstoken\",\n \"refreshtoken\",\n \"authorization\",\n \"cookie\",\n \"set-cookie\",\n \"apikey\",\n \"privatekey\",\n \"otp\",\n \"pin\",\n \"cardnumber\",\n \"cvv\",\n];\n\nconst DEFAULTS: ResolvedOptions = {\n redactKeys: DEFAULT_REDACT_KEYS,\n redactByPattern: [],\n replacement: \"[REDACTED]\",\n maxDepth: 6,\n maxArrayLength: 100,\n maxObjectKeys: 100,\n maxStringLength: 4000,\n includeErrorStack: false,\n stable: false,\n pretty: false,\n handleBigInt: \"string\",\n handleFunction: \"omit\",\n handleSymbol: \"omit\",\n onCircular: \"placeholder\",\n};\n\nexport function resolveOptions(options?: SafeJsonOptions): ResolvedOptions {\n if (!options) return DEFAULTS;\n\n const userKeys = options.redactKeys?.map((k) => k.toLowerCase()) ?? [];\n const mergedKeys = [...DEFAULT_REDACT_KEYS, ...userKeys];\n\n return {\n redactKeys: mergedKeys,\n redactByPattern: options.redactByPattern ?? DEFAULTS.redactByPattern,\n replacement: options.replacement ?? DEFAULTS.replacement,\n maxDepth: options.maxDepth ?? DEFAULTS.maxDepth,\n maxArrayLength: options.maxArrayLength ?? DEFAULTS.maxArrayLength,\n maxObjectKeys: options.maxObjectKeys ?? DEFAULTS.maxObjectKeys,\n maxStringLength: options.maxStringLength ?? DEFAULTS.maxStringLength,\n includeErrorStack: options.includeErrorStack ?? DEFAULTS.includeErrorStack,\n stable: options.stable ?? DEFAULTS.stable,\n pretty: options.pretty ?? DEFAULTS.pretty,\n handleBigInt: options.handleBigInt ?? DEFAULTS.handleBigInt,\n handleFunction: options.handleFunction ?? DEFAULTS.handleFunction,\n handleSymbol: options.handleSymbol ?? DEFAULTS.handleSymbol,\n onCircular: options.onCircular ?? DEFAULTS.onCircular,\n };\n}\n\nfunction isRedactedKey(key: string, opts: ResolvedOptions): boolean {\n const lower = key.toLowerCase();\n if (opts.redactKeys.includes(lower)) return true;\n for (const pattern of opts.redactByPattern) {\n if (pattern.test(key)) return true;\n }\n return false;\n}\n\nfunction serializeError(\n err: Error,\n opts: ResolvedOptions,\n seen: WeakSet<object>,\n depth: number\n): Record<string, unknown> {\n const result: Record<string, unknown> = {\n name: err.name,\n message: err.message,\n };\n\n if (opts.includeErrorStack && err.stack) {\n result[\"stack\"] =\n err.stack.length > opts.maxStringLength\n ? err.stack.slice(0, opts.maxStringLength) + \"...[Truncated]\"\n : err.stack;\n }\n\n if (err.cause !== undefined) {\n result[\"cause\"] = walk(err.cause, opts, seen, depth + 1);\n }\n\n for (const key of Object.keys(err)) {\n if (key in result) continue;\n if (isRedactedKey(key, opts)) {\n result[key] = opts.replacement;\n } else {\n result[key] = walk(\n (err as unknown as Record<string, unknown>)[key],\n opts,\n seen,\n depth + 1\n );\n }\n }\n\n return result;\n}\n\nfunction walk(\n value: unknown,\n opts: ResolvedOptions,\n seen: WeakSet<object>,\n depth: number\n): unknown {\n // primitives\n if (value === null) return null;\n if (value === undefined) return undefined;\n\n if (typeof value === \"boolean\" || typeof value === \"number\") return value;\n\n if (typeof value === \"string\") {\n if (value.length > opts.maxStringLength) {\n return value.slice(0, opts.maxStringLength) + \"...[Truncated]\";\n }\n return value;\n }\n\n if (typeof value === \"bigint\") {\n if (opts.handleBigInt === \"redact\") return opts.replacement;\n if (opts.handleBigInt === \"number\") return Number(value);\n return value.toString();\n }\n\n if (typeof value === \"function\") {\n if (opts.handleFunction === \"omit\") return undefined;\n if (opts.handleFunction === \"name\")\n return value.name ? `[Function: ${value.name}]` : \"[Function]\";\n return \"[Function]\";\n }\n\n if (typeof value === \"symbol\") {\n if (opts.handleSymbol === \"omit\") return undefined;\n if (opts.handleSymbol === \"description\")\n return value.description ?? \"[Symbol]\";\n return \"[Symbol]\";\n }\n\n // objects\n if (depth > opts.maxDepth) return \"[MaxDepth]\";\n\n if (value instanceof Date) return value.toISOString();\n\n if (value instanceof Error) {\n if (seen.has(value)) {\n return opts.onCircular === \"placeholder\" ? \"[Circular]\" : \"[Circular]\";\n }\n seen.add(value);\n const result = serializeError(value, opts, seen, depth);\n seen.delete(value);\n return result;\n }\n\n if (value instanceof Map) {\n if (seen.has(value)) return \"[Circular]\";\n seen.add(value);\n const obj: Record<string, unknown> = {};\n let keyCount = 0;\n for (const [k, v] of value) {\n if (keyCount >= opts.maxObjectKeys) break;\n const keyStr = String(k);\n obj[keyStr] = isRedactedKey(keyStr, opts)\n ? opts.replacement\n : walk(v, opts, seen, depth + 1);\n keyCount++;\n }\n seen.delete(value);\n return obj;\n }\n\n if (value instanceof Set) {\n if (seen.has(value)) return \"[Circular]\";\n seen.add(value);\n const arr = [...value].slice(0, opts.maxArrayLength);\n const result = arr.map((v) => walk(v, opts, seen, depth + 1));\n if (value.size > opts.maxArrayLength) {\n result.push(`[Truncated ${value.size - opts.maxArrayLength} more items]`);\n }\n seen.delete(value);\n return result;\n }\n\n if (Array.isArray(value)) {\n if (seen.has(value)) return \"[Circular]\";\n seen.add(value);\n const slice = value.slice(0, opts.maxArrayLength);\n const result = slice.map((v) => walk(v, opts, seen, depth + 1));\n if (value.length > opts.maxArrayLength) {\n result.push(`[Truncated ${value.length - opts.maxArrayLength} more items]`);\n }\n seen.delete(value);\n return result;\n }\n\n if (isPlainObject(value)) {\n if (seen.has(value)) return \"[Circular]\";\n seen.add(value);\n\n const keys = opts.stable ? sortedKeys(value) : Object.keys(value);\n const result: Record<string, unknown> = {};\n let keyCount = 0;\n\n for (const key of keys) {\n if (keyCount >= opts.maxObjectKeys) break;\n if (isRedactedKey(key, opts)) {\n result[key] = opts.replacement;\n } else {\n const walked = walk(value[key], opts, seen, depth + 1);\n if (walked !== undefined) {\n result[key] = walked;\n }\n }\n keyCount++;\n }\n\n seen.delete(value);\n return result;\n }\n\n // non-plain objects (class instances) — treat as plain, extract own enumerable keys\n if (typeof value === \"object\") {\n if (seen.has(value as object)) return \"[Circular]\";\n seen.add(value as object);\n\n const keys = opts.stable\n ? Object.keys(value as object).sort()\n : Object.keys(value as object);\n const result: Record<string, unknown> = {};\n let keyCount = 0;\n\n for (const key of keys) {\n if (keyCount >= opts.maxObjectKeys) break;\n if (isRedactedKey(key, opts)) {\n result[key] = opts.replacement;\n } else {\n const walked = walk(\n (value as Record<string, unknown>)[key],\n opts,\n seen,\n depth + 1\n );\n if (walked !== undefined) {\n result[key] = walked;\n }\n }\n keyCount++;\n }\n\n seen.delete(value as object);\n return result;\n }\n\n return value;\n}\n\nexport function safeClone(value: unknown, options?: SafeJsonOptions): unknown {\n const opts = resolveOptions(options);\n const seen = new WeakSet<object>();\n return walk(value, opts, seen, 0);\n}\n","import type { SafeJsonOptions } from \"./types.js\";\nimport { safeClone, resolveOptions } from \"./safe-clone.js\";\n\nexport function safeStringify(value: unknown, options?: SafeJsonOptions): string {\n const opts = resolveOptions(options);\n const cloned = safeClone(value, options);\n const indent = opts.pretty === true ? 2 : opts.pretty === false ? undefined : opts.pretty;\n return JSON.stringify(cloned, null, indent) ?? \"undefined\";\n}\n","import type { SafeJsonOptions } from \"./types.js\";\nimport { safeClone } from \"./safe-clone.js\";\n\nexport type RedactOptions = {\n keys?: string[];\n pattern?: RegExp[];\n replacement?: string;\n};\n\nexport function redact(value: unknown, options?: RedactOptions): unknown {\n const opts: SafeJsonOptions = {};\n if (options?.keys !== undefined) opts.redactKeys = options.keys;\n if (options?.pattern !== undefined) opts.redactByPattern = options.pattern;\n if (options?.replacement !== undefined) opts.replacement = options.replacement;\n return safeClone(value, opts);\n}\n","import type { SafeJsonOptions } from \"./types.js\";\n\nexport const presets = {\n log: {\n maxDepth: 5,\n maxArrayLength: 50,\n maxStringLength: 2000,\n includeErrorStack: false,\n stable: false,\n } satisfies SafeJsonOptions,\n\n debug: {\n maxDepth: 8,\n maxArrayLength: 200,\n maxStringLength: 8000,\n includeErrorStack: true,\n stable: false,\n } satisfies SafeJsonOptions,\n\n http: {\n maxDepth: 5,\n maxArrayLength: 50,\n maxStringLength: 2000,\n includeErrorStack: false,\n stable: false,\n redactKeys: [\"headers\", \"cookie\", \"set-cookie\", \"authorization\"],\n } satisfies SafeJsonOptions,\n\n audit: {\n maxDepth: 5,\n maxArrayLength: 100,\n maxStringLength: 4000,\n includeErrorStack: false,\n stable: true,\n } satisfies SafeJsonOptions,\n} as const;\n","import type { SafeJsonOptions, SafeJsonInstance } from \"./types.js\";\nimport { safeClone } from \"./safe-clone.js\";\nimport { safeStringify } from \"./safe-stringify.js\";\nimport { presets } from \"./presets.js\";\n\nexport function createSafeJson(base: SafeJsonOptions = {}): SafeJsonInstance {\n function merge(overrides?: SafeJsonOptions): SafeJsonOptions {\n if (!overrides) return base;\n const mergedKeys = [\n ...(base.redactKeys ?? []),\n ...(overrides.redactKeys ?? []),\n ];\n const mergedPatterns = [\n ...(base.redactByPattern ?? []),\n ...(overrides.redactByPattern ?? []),\n ];\n const merged: SafeJsonOptions = { ...base, ...overrides };\n if (mergedKeys.length > 0) merged.redactKeys = mergedKeys;\n if (mergedPatterns.length > 0) merged.redactByPattern = mergedPatterns;\n return merged;\n }\n\n return {\n stringify(value, overrides) {\n return safeStringify(value, merge(overrides));\n },\n clone(value, overrides) {\n return safeClone(value, merge(overrides));\n },\n forLog(value) {\n return safeClone(value, merge(presets.log));\n },\n forDebug(value) {\n return safeClone(value, merge(presets.debug));\n },\n forHttp(value) {\n return safeClone(value, merge(presets.http));\n },\n forAudit(value) {\n return safeClone(value, merge(presets.audit));\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/is-plain-object.ts","../src/utils/stable-sort.ts","../src/safe-clone.ts","../src/safe-stringify.ts","../src/redact.ts","../src/presets.ts","../src/create-safe-json.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto = Object.getPrototypeOf(value) as unknown;\n return proto === Object.prototype || proto === null;\n}\n","export function sortedKeys(obj: Record<string, unknown>): string[] {\n return Object.keys(obj).sort();\n}\n","import type { ResolvedOptions, SafeJsonOptions } from \"./types.js\";\nimport { isPlainObject } from \"./utils/is-plain-object.js\";\nimport { sortedKeys } from \"./utils/stable-sort.js\";\n\nconst DEFAULT_REDACT_KEYS = [\n \"password\",\n \"pass\",\n \"pwd\",\n \"secret\",\n \"token\",\n \"accesstoken\",\n \"refreshtoken\",\n \"authorization\",\n \"cookie\",\n \"set-cookie\",\n \"apikey\",\n \"privatekey\",\n \"otp\",\n \"pin\",\n \"cardnumber\",\n \"cvv\",\n];\n\nconst DEFAULTS: ResolvedOptions = {\n redactKeys: DEFAULT_REDACT_KEYS,\n redactByPattern: [],\n replacement: \"[REDACTED]\",\n maxDepth: 6,\n maxArrayLength: 100,\n maxObjectKeys: 100,\n maxStringLength: 4000,\n includeErrorStack: false,\n stable: false,\n pretty: false,\n handleBigInt: \"string\",\n handleFunction: \"omit\",\n handleSymbol: \"omit\",\n onCircular: \"placeholder\",\n};\n\nexport function resolveOptions(options?: SafeJsonOptions): ResolvedOptions {\n if (!options) return DEFAULTS;\n\n const userKeys = options.redactKeys?.map((k) => k.toLowerCase()) ?? [];\n const mergedKeys = [...DEFAULT_REDACT_KEYS, ...userKeys];\n\n return {\n redactKeys: mergedKeys,\n redactByPattern: options.redactByPattern ?? DEFAULTS.redactByPattern,\n replacement: options.replacement ?? DEFAULTS.replacement,\n maxDepth: options.maxDepth ?? DEFAULTS.maxDepth,\n maxArrayLength: options.maxArrayLength ?? DEFAULTS.maxArrayLength,\n maxObjectKeys: options.maxObjectKeys ?? DEFAULTS.maxObjectKeys,\n maxStringLength: options.maxStringLength ?? DEFAULTS.maxStringLength,\n includeErrorStack: options.includeErrorStack ?? DEFAULTS.includeErrorStack,\n stable: options.stable ?? DEFAULTS.stable,\n pretty: options.pretty ?? DEFAULTS.pretty,\n handleBigInt: options.handleBigInt ?? DEFAULTS.handleBigInt,\n handleFunction: options.handleFunction ?? DEFAULTS.handleFunction,\n handleSymbol: options.handleSymbol ?? DEFAULTS.handleSymbol,\n onCircular: options.onCircular ?? DEFAULTS.onCircular,\n };\n}\n\nfunction isRedactedKey(key: string, opts: ResolvedOptions): boolean {\n const lower = key.toLowerCase();\n if (opts.redactKeys.includes(lower)) return true;\n for (const pattern of opts.redactByPattern) {\n if (pattern.test(key)) return true;\n }\n return false;\n}\n\nfunction circularRef(\n opts: ResolvedOptions,\n seen: WeakMap<object, string>,\n obj: object\n): string {\n if (opts.onCircular === \"path\") {\n return `[Circular: ${seen.get(obj) ?? \"?\"}]`;\n }\n return \"[Circular]\";\n}\n\nfunction serializeError(\n err: Error,\n opts: ResolvedOptions,\n seen: WeakMap<object, string>,\n depth: number,\n path: string\n): Record<string, unknown> {\n const result: Record<string, unknown> = {\n name: err.name,\n message: err.message,\n };\n\n if (opts.includeErrorStack && err.stack) {\n result[\"stack\"] =\n err.stack.length > opts.maxStringLength\n ? err.stack.slice(0, opts.maxStringLength) + \"...[Truncated]\"\n : err.stack;\n }\n\n if (err.cause !== undefined) {\n result[\"cause\"] = walk(err.cause, opts, seen, depth + 1, `${path}.cause`);\n }\n\n for (const key of Object.keys(err)) {\n if (key in result) continue;\n if (isRedactedKey(key, opts)) {\n result[key] = opts.replacement;\n } else {\n result[key] = walk(\n (err as unknown as Record<string, unknown>)[key],\n opts,\n seen,\n depth + 1,\n `${path}.${key}`\n );\n }\n }\n\n return result;\n}\n\nfunction walk(\n value: unknown,\n opts: ResolvedOptions,\n seen: WeakMap<object, string>,\n depth: number,\n path: string\n): unknown {\n // primitives\n if (value === null) return null;\n if (value === undefined) return undefined;\n\n if (typeof value === \"boolean\" || typeof value === \"number\") return value;\n\n if (typeof value === \"string\") {\n if (value.length > opts.maxStringLength) {\n return value.slice(0, opts.maxStringLength) + \"...[Truncated]\";\n }\n return value;\n }\n\n if (typeof value === \"bigint\") {\n if (opts.handleBigInt === \"redact\") return opts.replacement;\n if (opts.handleBigInt === \"number\") return Number(value);\n return value.toString();\n }\n\n if (typeof value === \"function\") {\n if (opts.handleFunction === \"omit\") return undefined;\n if (opts.handleFunction === \"name\")\n return value.name ? `[Function: ${value.name}]` : \"[Function]\";\n return \"[Function]\";\n }\n\n if (typeof value === \"symbol\") {\n if (opts.handleSymbol === \"omit\") return undefined;\n if (opts.handleSymbol === \"description\")\n return value.description ?? \"[Symbol]\";\n return \"[Symbol]\";\n }\n\n // objects\n if (depth > opts.maxDepth) return \"[MaxDepth]\";\n\n if (value instanceof Date) return value.toISOString();\n\n if (value instanceof Error) {\n if (seen.has(value)) return circularRef(opts, seen, value);\n seen.set(value, path);\n const result = serializeError(value, opts, seen, depth, path);\n seen.delete(value);\n return result;\n }\n\n if (value instanceof Map) {\n if (seen.has(value)) return circularRef(opts, seen, value);\n seen.set(value, path);\n const obj: Record<string, unknown> = {};\n let keyCount = 0;\n for (const [k, v] of value) {\n if (keyCount >= opts.maxObjectKeys) break;\n const keyStr = String(k);\n obj[keyStr] = isRedactedKey(keyStr, opts)\n ? opts.replacement\n : walk(v, opts, seen, depth + 1, `${path}.${keyStr}`);\n keyCount++;\n }\n seen.delete(value);\n return obj;\n }\n\n if (value instanceof Set) {\n if (seen.has(value)) return circularRef(opts, seen, value);\n seen.set(value, path);\n const arr = [...value].slice(0, opts.maxArrayLength);\n const result = arr.map((v, i) => walk(v, opts, seen, depth + 1, `${path}[${i}]`));\n if (value.size > opts.maxArrayLength) {\n result.push(`[Truncated ${value.size - opts.maxArrayLength} more items]`);\n }\n seen.delete(value);\n return result;\n }\n\n if (Array.isArray(value)) {\n if (seen.has(value)) return circularRef(opts, seen, value);\n seen.set(value, path);\n const slice = value.slice(0, opts.maxArrayLength);\n const result = slice.map((v, i) => walk(v, opts, seen, depth + 1, `${path}[${i}]`));\n if (value.length > opts.maxArrayLength) {\n result.push(`[Truncated ${value.length - opts.maxArrayLength} more items]`);\n }\n seen.delete(value);\n return result;\n }\n\n if (isPlainObject(value)) {\n if (seen.has(value)) return circularRef(opts, seen, value);\n seen.set(value, path);\n\n const keys = opts.stable ? sortedKeys(value) : Object.keys(value);\n const result: Record<string, unknown> = {};\n let keyCount = 0;\n\n for (const key of keys) {\n if (keyCount >= opts.maxObjectKeys) break;\n if (isRedactedKey(key, opts)) {\n result[key] = opts.replacement;\n } else {\n const walked = walk(value[key], opts, seen, depth + 1, `${path}.${key}`);\n if (walked !== undefined) {\n result[key] = walked;\n }\n }\n keyCount++;\n }\n\n seen.delete(value);\n return result;\n }\n\n // non-plain objects (class instances) — treat as plain, extract own enumerable keys\n if (typeof value === \"object\") {\n if (seen.has(value as object)) return circularRef(opts, seen, value as object);\n seen.set(value as object, path);\n\n const keys = opts.stable\n ? Object.keys(value as object).sort()\n : Object.keys(value as object);\n const result: Record<string, unknown> = {};\n let keyCount = 0;\n\n for (const key of keys) {\n if (keyCount >= opts.maxObjectKeys) break;\n if (isRedactedKey(key, opts)) {\n result[key] = opts.replacement;\n } else {\n const walked = walk(\n (value as Record<string, unknown>)[key],\n opts,\n seen,\n depth + 1,\n `${path}.${key}`\n );\n if (walked !== undefined) {\n result[key] = walked;\n }\n }\n keyCount++;\n }\n\n seen.delete(value as object);\n return result;\n }\n\n return value;\n}\n\nexport function safeCloneResolved(value: unknown, opts: ResolvedOptions): unknown {\n const seen = new WeakMap<object, string>();\n return walk(value, opts, seen, 0, \"$\");\n}\n\nexport function safeClone(value: unknown, options?: SafeJsonOptions): unknown {\n return safeCloneResolved(value, resolveOptions(options));\n}\n","import type { SafeJsonOptions } from \"./types.js\";\nimport { resolveOptions, safeCloneResolved } from \"./safe-clone.js\";\n\nexport function safeStringify(value: unknown, options?: SafeJsonOptions): string {\n const opts = resolveOptions(options);\n const cloned = safeCloneResolved(value, opts);\n const indent = opts.pretty === true ? 2 : opts.pretty === false ? undefined : opts.pretty;\n return JSON.stringify(cloned, null, indent) ?? \"undefined\";\n}\n","import type { SafeJsonOptions } from \"./types.js\";\nimport { safeClone } from \"./safe-clone.js\";\n\nexport type RedactOptions = {\n keys?: string[];\n pattern?: RegExp[];\n replacement?: string;\n};\n\nexport function redact(value: unknown, options?: RedactOptions): unknown {\n const opts: SafeJsonOptions = {};\n if (options?.keys !== undefined) opts.redactKeys = options.keys;\n if (options?.pattern !== undefined) opts.redactByPattern = options.pattern;\n if (options?.replacement !== undefined) opts.replacement = options.replacement;\n return safeClone(value, opts);\n}\n","import type { SafeJsonOptions } from \"./types.js\";\n\nexport const presets = {\n log: {\n maxDepth: 5,\n maxArrayLength: 50,\n maxStringLength: 2000,\n includeErrorStack: false,\n stable: false,\n } satisfies SafeJsonOptions,\n\n debug: {\n maxDepth: 8,\n maxArrayLength: 200,\n maxStringLength: 8000,\n includeErrorStack: true,\n stable: false,\n } satisfies SafeJsonOptions,\n\n http: {\n maxDepth: 5,\n maxArrayLength: 50,\n maxStringLength: 2000,\n includeErrorStack: false,\n stable: false,\n redactKeys: [\"headers\", \"cookie\", \"set-cookie\", \"authorization\"],\n } satisfies SafeJsonOptions,\n\n audit: {\n maxDepth: 5,\n maxArrayLength: 100,\n maxStringLength: 4000,\n includeErrorStack: false,\n stable: true,\n } satisfies SafeJsonOptions,\n} as const;\n","import type { SafeJsonOptions, SafeJsonInstance } from \"./types.js\";\nimport { safeClone } from \"./safe-clone.js\";\nimport { safeStringify } from \"./safe-stringify.js\";\nimport { presets } from \"./presets.js\";\n\nexport function createSafeJson(base: SafeJsonOptions = {}): SafeJsonInstance {\n function merge(overrides?: SafeJsonOptions): SafeJsonOptions {\n if (!overrides) return base;\n const mergedKeys = [\n ...(base.redactKeys ?? []),\n ...(overrides.redactKeys ?? []),\n ];\n const mergedPatterns = [\n ...(base.redactByPattern ?? []),\n ...(overrides.redactByPattern ?? []),\n ];\n const merged: SafeJsonOptions = { ...base, ...overrides };\n if (mergedKeys.length > 0) merged.redactKeys = mergedKeys;\n if (mergedPatterns.length > 0) merged.redactByPattern = mergedPatterns;\n return merged;\n }\n\n return {\n stringify(value, overrides) {\n return safeStringify(value, merge(overrides));\n },\n clone(value, overrides) {\n return safeClone(value, merge(overrides));\n },\n forLog(value) {\n return safeClone(value, merge(presets.log));\n },\n forDebug(value) {\n return safeClone(value, merge(presets.debug));\n },\n forHttp(value) {\n return safeClone(value, merge(presets.http));\n },\n forAudit(value) {\n return safeClone(value, merge(presets.audit));\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ohbee-safe-json",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "JSON.stringify for production logs: safe, lightweight, redacted, bounded, and predictable.",
5
5
  "keywords": [
6
6
  "json",
@@ -13,6 +13,10 @@
13
13
  ],
14
14
  "license": "MIT",
15
15
  "author": "Ohbee",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/ohbee-labs/-ohbee-safe-json"
19
+ },
16
20
  "type": "module",
17
21
  "main": "./dist/index.cjs",
18
22
  "module": "./dist/index.js",