@helpers4/json 0.0.0-stage → 3.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +160 -0
- package/README.md +96 -2
- package/lib/index.d.ts +463 -0
- package/lib/index.js +928 -0
- package/lib/index.js.map +1 -0
- package/llms.txt +699 -0
- package/meta/api.json +662 -0
- package/meta/category.json +6 -0
- package/meta/examples.json +185 -0
- package/meta/licenses.json +4 -0
- package/package.json +52 -3
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of helpers4.
|
|
3
|
+
* Copyright (C) 2025 baxyz
|
|
4
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Parses JSON permissively: strict JSON, JSONC (the dialect of `tsconfig.json` and VS Code's
|
|
8
|
+
* `settings.json`, also known as HuJSON or JWCC) and JSON5 — each a superset of the one before.
|
|
9
|
+
*
|
|
10
|
+
* **Accepts:**
|
|
11
|
+
* - everything {@link parseStrict} accepts (strict JSON, RFC 8259)
|
|
12
|
+
* - comments: `// …` to the end of the line, and `/* … *\/`
|
|
13
|
+
* - one trailing comma after the last item of an object or array
|
|
14
|
+
* - object keys without quotes, when they are ECMAScript identifiers (`{ name: 1 }`, `{ $id: 1 }`)
|
|
15
|
+
* - strings in single quotes, and in either quote: the escapes `\'`, `\v`, `\0` and `\xHH`, any
|
|
16
|
+
* other escaped character standing for itself, and a backslash before a line break to continue
|
|
17
|
+
* the string on the next line
|
|
18
|
+
* - numbers with a leading `+`, a leading or trailing dot (`.5`, `5.`), in hexadecimal (`0x1F`),
|
|
19
|
+
* and `Infinity`, `-Infinity` and `NaN`
|
|
20
|
+
* - any Unicode whitespace between tokens, including a leading byte order mark (U+FEFF)
|
|
21
|
+
*
|
|
22
|
+
* **Rejects:** more than one trailing comma in a row, leading zeros (`01`), octal or binary
|
|
23
|
+
* numbers, unquoted keys that aren't identifiers (`{ my-key: 1 }`), raw line breaks inside a
|
|
24
|
+
* string, an unterminated comment or string, `undefined`, and more than one value.
|
|
25
|
+
*
|
|
26
|
+
* **On invalid input:** throws a `SyntaxError` naming the line and column of the first problem.
|
|
27
|
+
*
|
|
28
|
+
* Strict JSON goes straight to the native `JSON.parse`, and JSONC to `JSON.parse` after its
|
|
29
|
+
* comments are blanked out; only text that is neither goes through the JSON5 reader (written for
|
|
30
|
+
* helpers4 from the JSON5 1.0.0 specification), so the common cases cost nothing extra.
|
|
31
|
+
*
|
|
32
|
+
* Values are built as `JSON.parse` builds them: the last of duplicate keys wins, and a
|
|
33
|
+
* `__proto__` key is an own property, never the prototype. `NaN` and `Infinity` have no JSON
|
|
34
|
+
* representation — {@link stringify} writes them as `null`.
|
|
35
|
+
*
|
|
36
|
+
* @param text - The JSON, JSONC or JSON5 text to parse
|
|
37
|
+
* @returns The parsed value, typed as `T`
|
|
38
|
+
* @throws {SyntaxError} When `text` isn't JSON5 (and so neither JSONC nor JSON)
|
|
39
|
+
* @see {@link safeParse} — same parsing, returns `null` or a fallback instead of throwing
|
|
40
|
+
* @see {@link parseStrict} — strict JSON only, e.g. to validate an API payload
|
|
41
|
+
* @see {@link parseLines} — one value per line (NDJSON, JSON Lines)
|
|
42
|
+
* @see {@link parseSequence} — JSON text sequences (RFC 7464)
|
|
43
|
+
* @example
|
|
44
|
+
* parse('{"a":1}') // => { a: 1 }
|
|
45
|
+
* @example
|
|
46
|
+
* parse(`{
|
|
47
|
+
* // the output directory
|
|
48
|
+
* "outDir": "dist",
|
|
49
|
+
* }`) // => { outDir: 'dist' }
|
|
50
|
+
* @example
|
|
51
|
+
* parse("{ name: 'app', retries: 0x3, ratio: .5, }") // => { name: 'app', retries: 3, ratio: 0.5 }
|
|
52
|
+
* @since 3.1.3
|
|
53
|
+
*/
|
|
54
|
+
declare function parse<T = unknown>(text: string): T;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* This file is part of helpers4.
|
|
58
|
+
* Copyright (C) 2025 baxyz
|
|
59
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
60
|
+
*/
|
|
61
|
+
/**
|
|
62
|
+
* Options for {@link parseLines} and {@link safeParseLines}.
|
|
63
|
+
* @since 3.1.3
|
|
64
|
+
*/
|
|
65
|
+
interface ParseLinesOptions {
|
|
66
|
+
/**
|
|
67
|
+
* What to do with a blank (empty or whitespace-only) line:
|
|
68
|
+
* - `'skip'` (default) — ignore it, as NDJSON allows
|
|
69
|
+
* - `'fail'` — treat it as invalid, as JSON Lines requires (*"a blank line is not"* a valid value)
|
|
70
|
+
*
|
|
71
|
+
* A single line break at the very end of the text is a terminator, not a blank line, and is
|
|
72
|
+
* always accepted.
|
|
73
|
+
*/
|
|
74
|
+
blankLines?: 'skip' | 'fail';
|
|
75
|
+
/**
|
|
76
|
+
* What to do with a line that isn't valid JSON:
|
|
77
|
+
* - `'fail'` (default) — the whole parse fails, as NDJSON says a parser should
|
|
78
|
+
* - `'skip'` — drop that line and keep the others, e.g. for a log whose last line was
|
|
79
|
+
* truncated by a crash
|
|
80
|
+
*/
|
|
81
|
+
invalidLines?: 'fail' | 'skip';
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Parses newline-delimited JSON — one JSON value per line. Covers both NDJSON
|
|
85
|
+
* (`application/x-ndjson`, `.ndjson`) and JSON Lines (`.jsonl`), which are the same format.
|
|
86
|
+
*
|
|
87
|
+
* **Accepts:**
|
|
88
|
+
* - one strict JSON value per line (each line is read like {@link parseStrict})
|
|
89
|
+
* - `\n` and `\r\n` line endings
|
|
90
|
+
* - a trailing line break after the last value, or none
|
|
91
|
+
* - blank lines, skipped by default (see {@link ParseLinesOptions.blankLines})
|
|
92
|
+
* - an empty text, which holds zero values
|
|
93
|
+
*
|
|
94
|
+
* **Rejects:** comments, trailing commas and any other non-strict JSON on a line, a value spread
|
|
95
|
+
* over several lines, and a leading byte order mark (JSON Lines forbids it).
|
|
96
|
+
*
|
|
97
|
+
* **On invalid input:** throws a `SyntaxError` naming the 1-based line number, with the
|
|
98
|
+
* original parse error as its `cause` — unless `invalidLines`/`blankLines` say to skip it.
|
|
99
|
+
*
|
|
100
|
+
* @param text - The newline-delimited JSON text
|
|
101
|
+
* @param options - How to handle blank and invalid lines — see {@link ParseLinesOptions}
|
|
102
|
+
* @returns The parsed values, in line order, typed as `T[]`
|
|
103
|
+
* @throws {SyntaxError} When a line isn't valid JSON (or is blank with `blankLines: 'fail'`)
|
|
104
|
+
* @see {@link safeParseLines} — same parsing, returns `null` or a fallback instead of throwing
|
|
105
|
+
* @see {@link stringifyLines} — the reverse operation
|
|
106
|
+
* @see {@link parseSequence} — JSON text sequences (RFC 7464), the record-separator variant
|
|
107
|
+
* @see {@link parse} — a single JSON or JSONC value
|
|
108
|
+
* @example
|
|
109
|
+
* parseLines('{"id":1}\n{"id":2}\n') // => [{ id: 1 }, { id: 2 }]
|
|
110
|
+
* @example
|
|
111
|
+
* parseLines('{"id":1}\n{"id":', { invalidLines: 'skip' }) // => [{ id: 1 }]
|
|
112
|
+
* @since 3.1.3
|
|
113
|
+
*/
|
|
114
|
+
declare function parseLines<T = unknown>(text: string, options?: ParseLinesOptions): T[];
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* This file is part of helpers4.
|
|
118
|
+
* Copyright (C) 2025 baxyz
|
|
119
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
120
|
+
*/
|
|
121
|
+
/**
|
|
122
|
+
* Options for {@link parseSequence} and {@link safeParseSequence}.
|
|
123
|
+
* @since 3.1.3
|
|
124
|
+
*/
|
|
125
|
+
interface ParseSequenceOptions {
|
|
126
|
+
/**
|
|
127
|
+
* What to do with a record that isn't a valid, complete JSON text:
|
|
128
|
+
* - `'fail'` (default) — the whole parse fails, like every other `parse*` helper
|
|
129
|
+
* - `'skip'` — drop that record and keep the others. RFC 7464 recommends this (*"parsers should
|
|
130
|
+
* not abort when an octet string contains a malformed JSON text"*), for logs whose records
|
|
131
|
+
* may have been truncated by a crash.
|
|
132
|
+
*/
|
|
133
|
+
invalidRecords?: 'fail' | 'skip';
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Parses a JSON text sequence (RFC 7464, `application/json-seq`): records that each start with
|
|
137
|
+
* the ASCII record separator (RS, U+001E) and hold one JSON text, as written by `jq --seq`.
|
|
138
|
+
*
|
|
139
|
+
* **Accepts:**
|
|
140
|
+
* - one strict JSON value per record (each record is read like {@link parseStrict})
|
|
141
|
+
* - JSON values spread over several lines inside a record — unlike {@link parseLines}
|
|
142
|
+
* - several RS in a row (empty records are ignored, as the RFC's grammar allows)
|
|
143
|
+
* - an empty text, which holds zero records
|
|
144
|
+
*
|
|
145
|
+
* **Rejects (as invalid records):**
|
|
146
|
+
* - anything before the first RS
|
|
147
|
+
* - a record that isn't strict JSON, or holds only whitespace
|
|
148
|
+
* - a top-level number, `true`, `false` or `null` not followed by whitespace — RFC 7464 §2.4
|
|
149
|
+
* requires dropping it, since it may have been truncated
|
|
150
|
+
*
|
|
151
|
+
* **On invalid input:** throws a `SyntaxError` naming the 1-based record number, with the
|
|
152
|
+
* original parse error (if any) as its `cause` — unless `invalidRecords: 'skip'` says to drop it.
|
|
153
|
+
*
|
|
154
|
+
* @param text - The JSON text sequence
|
|
155
|
+
* @param options - How to handle invalid records — see {@link ParseSequenceOptions}
|
|
156
|
+
* @returns The parsed values, in record order, typed as `T[]`
|
|
157
|
+
* @throws {SyntaxError} When a record is invalid and `invalidRecords` is `'fail'`
|
|
158
|
+
* @see {@link safeParseSequence} — same parsing, returns `null` or a fallback instead of throwing
|
|
159
|
+
* @see {@link stringifySequence} — the reverse operation
|
|
160
|
+
* @see {@link parseLines} — newline-delimited JSON (NDJSON, JSON Lines)
|
|
161
|
+
* @example
|
|
162
|
+
* parseSequence('\u001E{"id":1}\n\u001E{"id":2}\n') // => [{ id: 1 }, { id: 2 }]
|
|
163
|
+
* @example
|
|
164
|
+
* // A crash cut the last record: skip it, as RFC 7464 recommends
|
|
165
|
+
* parseSequence('\u001E{"id":1}\n\u001E{"id', { invalidRecords: 'skip' }) // => [{ id: 1 }]
|
|
166
|
+
* @since 3.1.3
|
|
167
|
+
*/
|
|
168
|
+
declare function parseSequence<T = unknown>(text: string, options?: ParseSequenceOptions): T[];
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* This file is part of helpers4.
|
|
172
|
+
* Copyright (C) 2025 baxyz
|
|
173
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
174
|
+
*/
|
|
175
|
+
/**
|
|
176
|
+
* Parses strict JSON (RFC 8259) — exactly what `JSON.parse` accepts, nothing more.
|
|
177
|
+
*
|
|
178
|
+
* **Accepts:** standard JSON only — double-quoted strings and keys, finite decimal numbers,
|
|
179
|
+
* `true`/`false`/`null`, objects and arrays, surrounding whitespace.
|
|
180
|
+
*
|
|
181
|
+
* **Rejects:** comments, trailing commas, single quotes, unquoted keys, hexadecimal numbers,
|
|
182
|
+
* `NaN`/`Infinity`, a leading byte order mark (U+FEFF), and anything else that isn't strict JSON.
|
|
183
|
+
*
|
|
184
|
+
* **On invalid input:** throws the native `SyntaxError` from `JSON.parse`.
|
|
185
|
+
*
|
|
186
|
+
* Use it to validate input that must be strict JSON, e.g. an API payload. To also read config
|
|
187
|
+
* files with comments or JSON5, use {@link parse}. To never throw, use {@link safeParseStrict}.
|
|
188
|
+
*
|
|
189
|
+
* @param text - The JSON text to parse
|
|
190
|
+
* @returns The parsed value, typed as `T`
|
|
191
|
+
* @throws {SyntaxError} When `text` isn't strict JSON
|
|
192
|
+
* @see {@link safeParseStrict} — same parsing, returns `null` or a fallback instead of throwing
|
|
193
|
+
* @see {@link parse} — also accepts JSONC and JSON5
|
|
194
|
+
* @see {@link parseLines} — one value per line (NDJSON, JSON Lines)
|
|
195
|
+
* @see {@link parseSequence} — JSON text sequences (RFC 7464)
|
|
196
|
+
* @example
|
|
197
|
+
* parseStrict<{ a: number }>('{"a":1}') // => { a: 1 }
|
|
198
|
+
* parseStrict('{"a":1,}') // throws SyntaxError (trailing comma)
|
|
199
|
+
* @since 3.1.3
|
|
200
|
+
*/
|
|
201
|
+
declare function parseStrict<T = unknown>(text: string): T;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* This file is part of helpers4.
|
|
205
|
+
* Copyright (C) 2025 baxyz
|
|
206
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
207
|
+
*/
|
|
208
|
+
/**
|
|
209
|
+
* Parses JSON permissively like {@link parse} — strict JSON, JSONC (HuJSON, JWCC) and JSON5 —
|
|
210
|
+
* but returns `null` (or `fallback`) instead of throwing on invalid input.
|
|
211
|
+
*
|
|
212
|
+
* **Accepts / rejects:** exactly what {@link parse} does — see there for the full list.
|
|
213
|
+
*
|
|
214
|
+
* **On invalid input:** returns `fallback` when one is given — even `undefined`, which is told
|
|
215
|
+
* apart from an omitted argument — and `null` otherwise. Never throws.
|
|
216
|
+
*
|
|
217
|
+
* @param text - The JSON, JSONC or JSON5 text to parse
|
|
218
|
+
* @param fallback - Value returned on invalid input. Defaults to `null` when omitted.
|
|
219
|
+
* @returns The parsed value typed as `T`, or `fallback` on invalid input
|
|
220
|
+
* @see {@link parse} — same parsing, throws a `SyntaxError` instead
|
|
221
|
+
* @see {@link safeParseStrict} — strict JSON only
|
|
222
|
+
* @see {@link safeParseLines} — one value per line (NDJSON, JSON Lines)
|
|
223
|
+
* @example
|
|
224
|
+
* safeParse('{"a":1, /* note *\/}') // => { a: 1 }
|
|
225
|
+
* safeParse("{ a: 'x' }") // => { a: 'x' } (JSON5)
|
|
226
|
+
* safeParse('not json') // => null
|
|
227
|
+
* safeParse('not json', {}) // => {}
|
|
228
|
+
* @since 3.1.3
|
|
229
|
+
*/
|
|
230
|
+
declare function safeParse<T = unknown>(text: string): T | null;
|
|
231
|
+
declare function safeParse<T = unknown, F = T>(text: string, fallback: F): T | F;
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* This file is part of helpers4.
|
|
235
|
+
* Copyright (C) 2025 baxyz
|
|
236
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
237
|
+
*/
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Parses newline-delimited JSON (NDJSON, JSON Lines) like {@link parseLines}, but returns `null`
|
|
241
|
+
* (or `fallback`) instead of throwing on invalid input.
|
|
242
|
+
*
|
|
243
|
+
* **Accepts / rejects:** exactly what {@link parseLines} does, with the same
|
|
244
|
+
* {@link ParseLinesOptions}.
|
|
245
|
+
*
|
|
246
|
+
* **On invalid input:** returns `fallback` when one is given — even `undefined`, which is told
|
|
247
|
+
* apart from an omitted argument — and `null` otherwise. Never throws. To pass `options` without
|
|
248
|
+
* a fallback, pass `null` as the fallback.
|
|
249
|
+
*
|
|
250
|
+
* @param text - The newline-delimited JSON text
|
|
251
|
+
* @param fallback - Value returned on invalid input. Defaults to `null` when omitted.
|
|
252
|
+
* @param options - How to handle blank and invalid lines — see {@link ParseLinesOptions}
|
|
253
|
+
* @returns The parsed values typed as `T[]`, or `fallback` on invalid input
|
|
254
|
+
* @see {@link parseLines} — same parsing, throws a `SyntaxError` instead
|
|
255
|
+
* @see {@link safeParseSequence} — JSON text sequences (RFC 7464)
|
|
256
|
+
* @example
|
|
257
|
+
* safeParseLines('{"id":1}\n{"id":2}') // => [{ id: 1 }, { id: 2 }]
|
|
258
|
+
* safeParseLines('{"id":1}\n{"id":') // => null
|
|
259
|
+
* safeParseLines('{"id":1}\n\n', null, { blankLines: 'fail' }) // => null
|
|
260
|
+
* @since 3.1.3
|
|
261
|
+
*/
|
|
262
|
+
declare function safeParseLines<T = unknown>(text: string): T[] | null;
|
|
263
|
+
declare function safeParseLines<T = unknown, F = T[]>(text: string, fallback: F, options?: ParseLinesOptions): T[] | F;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* This file is part of helpers4.
|
|
267
|
+
* Copyright (C) 2025 baxyz
|
|
268
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
269
|
+
*/
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Parses a JSON text sequence (RFC 7464) like {@link parseSequence}, but returns `null` (or
|
|
273
|
+
* `fallback`) instead of throwing on invalid input.
|
|
274
|
+
*
|
|
275
|
+
* **Accepts / rejects:** exactly what {@link parseSequence} does, with the same
|
|
276
|
+
* {@link ParseSequenceOptions}.
|
|
277
|
+
*
|
|
278
|
+
* **On invalid input:** returns `fallback` when one is given — even `undefined`, which is told
|
|
279
|
+
* apart from an omitted argument — and `null` otherwise. Never throws. To pass `options` without
|
|
280
|
+
* a fallback, pass `null` as the fallback.
|
|
281
|
+
*
|
|
282
|
+
* @param text - The JSON text sequence
|
|
283
|
+
* @param fallback - Value returned on invalid input. Defaults to `null` when omitted.
|
|
284
|
+
* @param options - How to handle invalid records — see {@link ParseSequenceOptions}
|
|
285
|
+
* @returns The parsed values typed as `T[]`, or `fallback` on invalid input
|
|
286
|
+
* @see {@link parseSequence} — same parsing, throws a `SyntaxError` instead
|
|
287
|
+
* @see {@link safeParseLines} — newline-delimited JSON (NDJSON, JSON Lines)
|
|
288
|
+
* @example
|
|
289
|
+
* safeParseSequence('\u001E{"id":1}\n') // => [{ id: 1 }]
|
|
290
|
+
* safeParseSequence('\u001E{"id"\n') // => null
|
|
291
|
+
* safeParseSequence('\u001E{"id"\n', []) // => []
|
|
292
|
+
* @since 3.1.3
|
|
293
|
+
*/
|
|
294
|
+
declare function safeParseSequence<T = unknown>(text: string): T[] | null;
|
|
295
|
+
declare function safeParseSequence<T = unknown, F = T[]>(text: string, fallback: F, options?: ParseSequenceOptions): T[] | F;
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* This file is part of helpers4.
|
|
299
|
+
* Copyright (C) 2025 baxyz
|
|
300
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
301
|
+
*/
|
|
302
|
+
/**
|
|
303
|
+
* Parses strict JSON like {@link parseStrict}, but returns `null` (or `fallback`) instead of
|
|
304
|
+
* throwing on invalid input.
|
|
305
|
+
*
|
|
306
|
+
* **Accepts / rejects:** exactly what {@link parseStrict} does — standard JSON only, no comments,
|
|
307
|
+
* no trailing commas, no JSON5 syntax, no leading byte order mark.
|
|
308
|
+
*
|
|
309
|
+
* **On invalid input:** returns `fallback` when one is given — even `undefined`, which is told
|
|
310
|
+
* apart from an omitted argument — and `null` otherwise. Never throws.
|
|
311
|
+
*
|
|
312
|
+
* @param text - The JSON text to parse
|
|
313
|
+
* @param fallback - Value returned on invalid input. Defaults to `null` when omitted.
|
|
314
|
+
* @returns The parsed value typed as `T`, or `fallback` on invalid input
|
|
315
|
+
* @see {@link parseStrict} — same parsing, throws a `SyntaxError` instead
|
|
316
|
+
* @see {@link safeParse} — also accepts JSONC and JSON5
|
|
317
|
+
* @example
|
|
318
|
+
* safeParseStrict<{ a: number }>('{"a":1}') // => { a: 1 }
|
|
319
|
+
* safeParseStrict('{"a":1,}') // => null
|
|
320
|
+
* safeParseStrict('oops', {}) // => {}
|
|
321
|
+
* @since 3.1.3
|
|
322
|
+
*/
|
|
323
|
+
declare function safeParseStrict<T = unknown>(text: string): T | null;
|
|
324
|
+
declare function safeParseStrict<T = unknown, F = T>(text: string, fallback: F): T | F;
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* This file is part of helpers4.
|
|
328
|
+
* Copyright (C) 2025 baxyz
|
|
329
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
330
|
+
*/
|
|
331
|
+
/**
|
|
332
|
+
* How {@link stringify} lays out its output:
|
|
333
|
+
* - `{ indent }` — pretty-printed with `indent` spaces per level (`0` for a compact single line)
|
|
334
|
+
* - `'canonical'` — canonical JSON (RFC 8785), byte-for-byte reproducible
|
|
335
|
+
* @since 3.1.3
|
|
336
|
+
*/
|
|
337
|
+
type StringifyFormatting = 'canonical' | {
|
|
338
|
+
indent?: number;
|
|
339
|
+
};
|
|
340
|
+
/**
|
|
341
|
+
* Serializes a value to JSON text — pretty-printed with 2 spaces by default, or canonical.
|
|
342
|
+
*
|
|
343
|
+
* **Formatting:**
|
|
344
|
+
* - default — indented with 2 spaces, like a hand-written config file
|
|
345
|
+
* - `{ indent: n }` — indented with `n` spaces (an integer from 0 to 10); `{ indent: 0 }` gives a
|
|
346
|
+
* compact single line, the same as `JSON.stringify(value)`
|
|
347
|
+
* - `'canonical'` — canonical JSON (RFC 8785, JSON Canonicalization Scheme): object keys sorted
|
|
348
|
+
* by UTF-16 code units, no whitespace at all, numbers in their shortest ECMAScript form. Two
|
|
349
|
+
* equal values always give the same bytes, so the output can be hashed, signed or compared.
|
|
350
|
+
* Canonical output can't be indented — the RFC fixes every byte.
|
|
351
|
+
*
|
|
352
|
+
* **Same as `JSON.stringify`:** `toJSON()` is called (a `Date` becomes its ISO string),
|
|
353
|
+
* `undefined`, functions and symbols are dropped from objects and become `null` in arrays, and
|
|
354
|
+
* `Number`/`String`/`Boolean` objects are unwrapped. Outside `'canonical'`, `NaN` and `±Infinity`
|
|
355
|
+
* silently become `null`, as there.
|
|
356
|
+
*
|
|
357
|
+
* **Throws** instead of returning `undefined` or dropping data silently:
|
|
358
|
+
* - a `TypeError` when `value` itself is `undefined`, a function or a symbol
|
|
359
|
+
* - a `TypeError` on a circular structure or a `BigInt` (like `JSON.stringify`)
|
|
360
|
+
* - with `'canonical'`, a `RangeError` on `NaN`, `±Infinity` or a string with a lone surrogate,
|
|
361
|
+
* which canonical JSON can't hold
|
|
362
|
+
* - a `RangeError` when `indent` isn't an integer from 0 to 10
|
|
363
|
+
*
|
|
364
|
+
* The output is strict JSON, so it is also valid JSONC and JSON5.
|
|
365
|
+
*
|
|
366
|
+
* @param value - The value to serialize
|
|
367
|
+
* @param formatting - `{ indent }` (default `{ indent: 2 }`) or `'canonical'` — see {@link StringifyFormatting}
|
|
368
|
+
* @returns The JSON text
|
|
369
|
+
* @throws {TypeError} When `value` can't be represented as JSON
|
|
370
|
+
* @throws {RangeError} On an invalid `indent`, or a value canonical JSON can't hold
|
|
371
|
+
* @see {@link parse} / {@link parseStrict} — the reverse operation
|
|
372
|
+
* @see {@link stringifyLines} — one value per line (NDJSON, JSON Lines)
|
|
373
|
+
* @see {@link stringifySequence} — JSON text sequences (RFC 7464)
|
|
374
|
+
* @example
|
|
375
|
+
* stringify({ b: 1, a: [true] })
|
|
376
|
+
* // => '{\n "b": 1,\n "a": [\n true\n ]\n}'
|
|
377
|
+
* @example
|
|
378
|
+
* stringify({ b: 1, a: [true] }, { indent: 0 }) // => '{"b":1,"a":[true]}'
|
|
379
|
+
* stringify({ b: 1, a: [true] }, 'canonical') // => '{"a":[true],"b":1}'
|
|
380
|
+
* @since 3.1.3
|
|
381
|
+
*/
|
|
382
|
+
declare function stringify(value: unknown, formatting?: StringifyFormatting): string;
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* This file is part of helpers4.
|
|
386
|
+
* Copyright (C) 2025 baxyz
|
|
387
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
388
|
+
*/
|
|
389
|
+
/**
|
|
390
|
+
* Serializes values as newline-delimited JSON — one compact JSON value per line, each followed
|
|
391
|
+
* by `\n`. The output is both NDJSON and JSON Lines (`.jsonl`), which are the same format.
|
|
392
|
+
*
|
|
393
|
+
* **Formatting:**
|
|
394
|
+
* - default — each value compact, like `JSON.stringify(value)`
|
|
395
|
+
* - `'canonical'` — each value as canonical JSON (RFC 8785): sorted keys, reproducible bytes, for
|
|
396
|
+
* hashing or diffing logs line by line
|
|
397
|
+
*
|
|
398
|
+
* Indentation isn't available: a line break inside a value would split it across lines. String
|
|
399
|
+
* values can't break a line either — `JSON.stringify` escapes `\n` and `\r` inside them.
|
|
400
|
+
*
|
|
401
|
+
* **Output:** every value is followed by `\n`, including the last one (NDJSON requires it, and
|
|
402
|
+
* JSON Lines recommends it, so files can be concatenated). An empty array gives `''`.
|
|
403
|
+
*
|
|
404
|
+
* **Throws** a `TypeError` when `values` isn't an array, or when one of them has no JSON
|
|
405
|
+
* representation (`undefined`, a function, a symbol, a `BigInt`, a circular structure) — rather
|
|
406
|
+
* than writing a line that would read back as something else. With `'canonical'`, also a
|
|
407
|
+
* `RangeError` on `NaN`, `±Infinity` or a lone surrogate (see {@link stringify}).
|
|
408
|
+
*
|
|
409
|
+
* @param values - The values to write, one per line
|
|
410
|
+
* @param formatting - `'canonical'` for canonical JSON lines; compact JSON by default
|
|
411
|
+
* @returns The newline-delimited JSON text
|
|
412
|
+
* @throws {TypeError} When `values` isn't an array, or a value has no JSON representation
|
|
413
|
+
* @throws {RangeError} With `'canonical'`, on a value canonical JSON can't hold
|
|
414
|
+
* @see {@link parseLines} — the reverse operation
|
|
415
|
+
* @see {@link stringifySequence} — JSON text sequences (RFC 7464)
|
|
416
|
+
* @see {@link stringify} — a single, possibly indented, JSON value
|
|
417
|
+
* @example
|
|
418
|
+
* stringifyLines([{ id: 1 }, { id: 2 }]) // => '{"id":1}\n{"id":2}\n'
|
|
419
|
+
* @example
|
|
420
|
+
* stringifyLines([{ b: 1, a: 2 }], 'canonical') // => '{"a":2,"b":1}\n'
|
|
421
|
+
* @since 3.1.3
|
|
422
|
+
*/
|
|
423
|
+
declare function stringifyLines(values: readonly unknown[], formatting?: 'canonical'): string;
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* This file is part of helpers4.
|
|
427
|
+
* Copyright (C) 2025 baxyz
|
|
428
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
429
|
+
*/
|
|
430
|
+
/**
|
|
431
|
+
* Serializes values as a JSON text sequence (RFC 7464, `application/json-seq`): each value is
|
|
432
|
+
* written as the ASCII record separator (RS, U+001E), the compact JSON text, then `\n` — the
|
|
433
|
+
* exact framing the RFC requires of encoders, as `jq --seq` writes it.
|
|
434
|
+
*
|
|
435
|
+
* **Formatting:**
|
|
436
|
+
* - default — each value compact, like `JSON.stringify(value)`
|
|
437
|
+
* - `'canonical'` — each value as canonical JSON (RFC 8785): sorted keys, reproducible bytes
|
|
438
|
+
*
|
|
439
|
+
* Indentation isn't offered, for symmetry with {@link stringifyLines}: the trailing `\n` is what
|
|
440
|
+
* lets a reader detect a truncated top-level number, `true`, `false` or `null` (RFC 7464 §2.4).
|
|
441
|
+
*
|
|
442
|
+
* **Output:** an empty array gives `''`.
|
|
443
|
+
*
|
|
444
|
+
* **Throws** a `TypeError` when `values` isn't an array, or when one of them has no JSON
|
|
445
|
+
* representation (`undefined`, a function, a symbol, a `BigInt`, a circular structure). With
|
|
446
|
+
* `'canonical'`, also a `RangeError` on `NaN`, `±Infinity` or a lone surrogate (see
|
|
447
|
+
* {@link stringify}).
|
|
448
|
+
*
|
|
449
|
+
* @param values - The values to write, one per record
|
|
450
|
+
* @param formatting - `'canonical'` for canonical JSON records; compact JSON by default
|
|
451
|
+
* @returns The JSON text sequence
|
|
452
|
+
* @throws {TypeError} When `values` isn't an array, or a value has no JSON representation
|
|
453
|
+
* @throws {RangeError} With `'canonical'`, on a value canonical JSON can't hold
|
|
454
|
+
* @see {@link parseSequence} — the reverse operation
|
|
455
|
+
* @see {@link stringifyLines} — newline-delimited JSON (NDJSON, JSON Lines)
|
|
456
|
+
* @example
|
|
457
|
+
* stringifySequence([{ id: 1 }, 2]) // => '\u001E{"id":1}\n\u001E2\n'
|
|
458
|
+
* @since 3.1.3
|
|
459
|
+
*/
|
|
460
|
+
declare function stringifySequence(values: readonly unknown[], formatting?: 'canonical'): string;
|
|
461
|
+
|
|
462
|
+
export { parse, parseLines, parseSequence, parseStrict, safeParse, safeParseLines, safeParseSequence, safeParseStrict, stringify, stringifyLines, stringifySequence };
|
|
463
|
+
export type { ParseLinesOptions, ParseSequenceOptions, StringifyFormatting };
|