@effected/yaml 0.24.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Yaml.js +26 -18
- package/YamlDiagnostic.js +4 -1
- package/YamlDocument.js +14 -12
- package/YamlFormat.js +28 -13
- package/index.d.ts +54 -37
- package/internal/composer/scalars.js +1 -0
- package/internal/diagnostics.js +18 -11
- package/internal/stringifier.js +31 -9
- package/package.json +1 -1
package/Yaml.js
CHANGED
|
@@ -171,11 +171,14 @@ var YamlParseError = class extends Schema.TaggedError()("YamlParseError", {
|
|
|
171
171
|
}
|
|
172
172
|
};
|
|
173
173
|
/**
|
|
174
|
-
* Stringification failure
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
174
|
+
* Stringification failure, carrying structured {@link YamlDiagnostic} entries
|
|
175
|
+
* and the offending value. Raised by {@link Yaml.stringify},
|
|
176
|
+
* `YamlDocument#stringify` and the encode direction of the schema factories
|
|
177
|
+
* on a circular reference (`CircularReference`), a value nested past the
|
|
178
|
+
* stringifier's recursion budget (`NestingDepthExceeded`) or a value with no
|
|
179
|
+
* YAML representation (`UnrepresentableValue` — a function or a symbol). The
|
|
180
|
+
* error itself has no `code` field: read the code from the diagnostics —
|
|
181
|
+
* `error.diagnostics[0].code` is the primary failure.
|
|
179
182
|
*
|
|
180
183
|
* @public
|
|
181
184
|
*/
|
|
@@ -227,14 +230,14 @@ const aliasCountExceededError = (message, text) => new YamlParseError({
|
|
|
227
230
|
* Shared by every stringify path — `Yaml.stringify`/`stringifyResult`, the
|
|
228
231
|
* schema encoders, `YamlDocument#stringifyResult` and `YamlFormat.modify`'s
|
|
229
232
|
* backstop — so all of them surface the hardening guards (circular
|
|
230
|
-
* reference, nesting-depth cap) identically.
|
|
233
|
+
* reference, unrepresentable value, nesting-depth cap) identically.
|
|
231
234
|
*
|
|
232
235
|
* @internal
|
|
233
236
|
*/
|
|
234
237
|
const stringifyDefectToError = (defect, value) => {
|
|
235
238
|
if (defect instanceof StringifyFailure) return new YamlStringifyError({
|
|
236
239
|
diagnostics: [YamlDiagnostic.make({
|
|
237
|
-
code:
|
|
240
|
+
code: defect.code,
|
|
238
241
|
message: defect.reason,
|
|
239
242
|
offset: 0,
|
|
240
243
|
length: 0,
|
|
@@ -309,9 +312,9 @@ const parseAllResultImpl = (text, options) => {
|
|
|
309
312
|
};
|
|
310
313
|
/**
|
|
311
314
|
* Synchronous stringify returning a `Result`. Mirrors {@link Yaml.stringify}
|
|
312
|
-
* without the Effect wrapper: a circular reference
|
|
313
|
-
* recursion budget yields a `Failure`
|
|
314
|
-
* never a thrown defect.
|
|
315
|
+
* without the Effect wrapper: a circular reference, a function or symbol
|
|
316
|
+
* value, or a value nested past the recursion budget yields a `Failure`
|
|
317
|
+
* carrying a typed {@link YamlStringifyError}, never a thrown defect.
|
|
315
318
|
*/
|
|
316
319
|
const stringifyResultImpl = (value, options) => Result.try({
|
|
317
320
|
try: () => stringifyValue(value, toStringifyInput(options)),
|
|
@@ -401,10 +404,14 @@ var Yaml = class Yaml {
|
|
|
401
404
|
static parseAll = Effect.fn("Yaml.parseAll")((text, options) => Effect.fromResult(Yaml.parseAllResult(text, options)));
|
|
402
405
|
/**
|
|
403
406
|
* Stringify a plain JavaScript value as YAML. Fails with
|
|
404
|
-
* {@link YamlStringifyError} on circular references (`CircularReference`)
|
|
405
|
-
*
|
|
406
|
-
* (`NestingDepthExceeded`)
|
|
407
|
-
*
|
|
407
|
+
* {@link YamlStringifyError} on circular references (`CircularReference`),
|
|
408
|
+
* on a value nested deeper than the stringifier's recursion budget
|
|
409
|
+
* (`NestingDepthExceeded`) and on a function or symbol anywhere in the
|
|
410
|
+
* value (`UnrepresentableValue`) — all surface through the typed error
|
|
411
|
+
* channel, never as a stack-overflow defect and never as the function's
|
|
412
|
+
* source text or `Symbol(s)` written into the document as a string. A
|
|
413
|
+
* `bigint` is an integer and renders bare, exactly as `YamlFormat.modify`
|
|
414
|
+
* writes one; `null` and `undefined` both render as `null`.
|
|
408
415
|
*
|
|
409
416
|
* @remarks
|
|
410
417
|
* A `"<<"` object key is emitted **quoted** (`'<<': …`). This is the
|
|
@@ -504,10 +511,11 @@ var Yaml = class Yaml {
|
|
|
504
511
|
* The pure counterpart to {@link Yaml.stringify} for config-time callers
|
|
505
512
|
* that cannot `await`.
|
|
506
513
|
*
|
|
507
|
-
* Preserves the package contract — a circular reference (`CircularReference`)
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
* thrown
|
|
514
|
+
* Preserves the package contract — a circular reference (`CircularReference`),
|
|
515
|
+
* a value nested past the recursion budget (`NestingDepthExceeded`) or a
|
|
516
|
+
* function or symbol value (`UnrepresentableValue`) yields a `Failure`
|
|
517
|
+
* carrying a {@link YamlStringifyError} rather than a thrown defect; the
|
|
518
|
+
* method never throws.
|
|
511
519
|
*
|
|
512
520
|
* @example
|
|
513
521
|
* ```ts
|
package/YamlDiagnostic.js
CHANGED
|
@@ -21,7 +21,10 @@ const YamlParseErrorCode = Schema.Literals(YAML_PARSE_ERROR_CODES);
|
|
|
21
21
|
*/
|
|
22
22
|
const YamlComposerErrorCode = Schema.Literals(YAML_COMPOSE_ERROR_CODES);
|
|
23
23
|
/**
|
|
24
|
-
* Error codes emitted by the stringifier (the
|
|
24
|
+
* Error codes emitted by the stringifier: `CircularReference` (the value or
|
|
25
|
+
* synthetic AST points back at itself) and `UnrepresentableValue` (a function
|
|
26
|
+
* or symbol, which has no YAML rendering and is never written as its
|
|
27
|
+
* `String()` form).
|
|
25
28
|
*
|
|
26
29
|
* @public
|
|
27
30
|
*/
|
package/YamlDocument.js
CHANGED
|
@@ -174,13 +174,16 @@ var YamlDocument = class YamlDocument extends Schema.Class("YamlDocument")({
|
|
|
174
174
|
}
|
|
175
175
|
/**
|
|
176
176
|
* Stringify this document (contents, directives and framing) as YAML.
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
177
|
+
* A parsed document always stringifies; the failures belong to hand-built
|
|
178
|
+
* ASTs and surface as {@link YamlStringifyError} through the typed error
|
|
179
|
+
* channel, never as an unhandled stack-overflow defect or as corrupted
|
|
180
|
+
* output: a cycle in the AST fails `CircularReference` on the first
|
|
181
|
+
* re-entry of an ancestor collection (the node path keeps the same
|
|
182
|
+
* ancestor set the value path does), a tree nested deeper than the
|
|
183
|
+
* stringifier's recursion budget fails `NestingDepthExceeded`, and a
|
|
184
|
+
* scalar node holding anything but `null`, a boolean, a number, a bigint
|
|
185
|
+
* or a string — a function, a symbol, an object — fails
|
|
186
|
+
* `UnrepresentableValue` rather than being written as its `String()` form.
|
|
184
187
|
* Defined in terms of {@link YamlDocument.stringifyResult} behind a
|
|
185
188
|
* `YamlDocument.stringify` span — synchronous callers can use that variant
|
|
186
189
|
* directly.
|
|
@@ -209,11 +212,10 @@ var YamlDocument = class YamlDocument extends Schema.Class("YamlDocument")({
|
|
|
209
212
|
* primitive {@link YamlDocument.stringify} is defined in terms of, so a
|
|
210
213
|
* synchronous host can round-trip a document parsed with
|
|
211
214
|
* {@link YamlDocument.parseResult} without an Effect runtime. Fails with
|
|
212
|
-
* {@link YamlStringifyError} exactly where `stringify` does: a
|
|
213
|
-
* AST
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
* `CircularReference`).
|
|
215
|
+
* {@link YamlStringifyError} exactly where `stringify` does: a hand-built
|
|
216
|
+
* AST containing a cycle (`CircularReference`), one nested deeper than the
|
|
217
|
+
* stringifier's recursion budget (`NestingDepthExceeded`) or one whose
|
|
218
|
+
* scalar node holds a value with no YAML form (`UnrepresentableValue`).
|
|
217
219
|
*
|
|
218
220
|
* @remarks
|
|
219
221
|
* `YamlStringifyOptions.lineWidth` is not honored here, for the reason
|
package/YamlFormat.js
CHANGED
|
@@ -259,12 +259,16 @@ function formatStream(text, documents, streamErrors, options) {
|
|
|
259
259
|
* Before this was recursive, a mapping or sequence value fell through to the
|
|
260
260
|
* node stringifier's `String(value)` fallback and landed in the document as
|
|
261
261
|
* the literal text `[object Object]` — a silent corruption that only surfaced
|
|
262
|
-
* on the next read.
|
|
262
|
+
* on the next read. Every other value becomes a plain {@link YamlScalar} and
|
|
263
|
+
* renders exactly as the value path renders it: a `bigint` bare, `undefined`
|
|
264
|
+
* as `null`.
|
|
263
265
|
*
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
266
|
+
* Three conditions fail typed rather than hanging, overflowing the stack or
|
|
267
|
+
* corrupting the document: a cycle raises `CircularReference`, a graph that
|
|
268
|
+
* would sit deeper than `MAX_NESTING_DEPTH` in the output document raises
|
|
269
|
+
* `NestingDepthExceeded`, and a function or symbol — which has no YAML
|
|
270
|
+
* rendering, and whose `String()` form the value path refuses to write too —
|
|
271
|
+
* raises `UnrepresentableValue`. `depth` is measured in the stringifier's own
|
|
268
272
|
* units — one per node from the document root — so the caller passes the
|
|
269
273
|
* target's depth, not zero. `seen` holds
|
|
270
274
|
* the ancestors of the value being lowered, so a value repeated across
|
|
@@ -302,7 +306,14 @@ function jsValueToNode(value, seen, depth) {
|
|
|
302
306
|
seen.delete(value);
|
|
303
307
|
}
|
|
304
308
|
}
|
|
305
|
-
|
|
309
|
+
if (typeof value === "function" || typeof value === "symbol") throw new ModifyFailure("UnrepresentableValue", `A ${typeof value} value has no YAML representation`, 0, 0);
|
|
310
|
+
return value === null || value === void 0 ? YamlScalar.make({
|
|
311
|
+
value: null,
|
|
312
|
+
style: "plain",
|
|
313
|
+
raw: "null",
|
|
314
|
+
offset: 0,
|
|
315
|
+
length: 0
|
|
316
|
+
}) : YamlScalar.make({
|
|
306
317
|
value,
|
|
307
318
|
style: "plain",
|
|
308
319
|
offset: 0,
|
|
@@ -698,7 +709,10 @@ var YamlFormat = class YamlFormat {
|
|
|
698
709
|
* sequence and any other non-null object as a block mapping over its own
|
|
699
710
|
* enumerable string keys, recursively — the same lowering
|
|
700
711
|
* {@link Yaml.stringify} applies to the same value, so `modify` and
|
|
701
|
-
* `stringify` agree on what a given JavaScript value means
|
|
712
|
+
* `stringify` agree on what a given JavaScript value means: a `bigint`
|
|
713
|
+
* renders bare (`a: 10`, never `a: "10"`), `null` renders as `null`, and a
|
|
714
|
+
* function or symbol fails `UnrepresentableValue` on both paths rather
|
|
715
|
+
* than landing in the document as its `String()` form. For a synthesized
|
|
702
716
|
* subtree (an object/array value) only the surrounding document is
|
|
703
717
|
* preserved byte-for-byte; the subtree carries no comments and takes the
|
|
704
718
|
* stringifier's styles.
|
|
@@ -722,12 +736,13 @@ var YamlFormat = class YamlFormat {
|
|
|
722
736
|
* whole document, which normalises line endings to LF, applies those
|
|
723
737
|
* options, and renders the replacement in the stringifier's styles.
|
|
724
738
|
*
|
|
725
|
-
*
|
|
726
|
-
*
|
|
727
|
-
* reference (`CircularReference`)
|
|
728
|
-
* levels in the output document
|
|
729
|
-
*
|
|
730
|
-
*
|
|
739
|
+
* Three replacement values have no rendering and fail typed rather than
|
|
740
|
+
* hanging, overflowing the stack or corrupting the document: one
|
|
741
|
+
* containing a circular reference (`CircularReference`), one that would
|
|
742
|
+
* sit deeper than 256 levels in the output document
|
|
743
|
+
* (`NestingDepthExceeded`) and one containing a function or symbol
|
|
744
|
+
* (`UnrepresentableValue`). The depth is counted from the document root,
|
|
745
|
+
* so the same value can fit at `[]` and fail a few keys down.
|
|
731
746
|
*
|
|
732
747
|
* **Single-document contract.** A `path` carries no document index, so on
|
|
733
748
|
* a multi-document stream there is no rule for which document it names —
|
package/index.d.ts
CHANGED
|
@@ -36,11 +36,14 @@ export declare const YamlComposerErrorCode: Schema.Literals<readonly ["Undefined
|
|
|
36
36
|
*/
|
|
37
37
|
export type YamlComposerErrorCode = typeof YamlComposerErrorCode.Type;
|
|
38
38
|
/**
|
|
39
|
-
* Error codes emitted by the stringifier (the
|
|
39
|
+
* Error codes emitted by the stringifier: `CircularReference` (the value or
|
|
40
|
+
* synthetic AST points back at itself) and `UnrepresentableValue` (a function
|
|
41
|
+
* or symbol, which has no YAML rendering and is never written as its
|
|
42
|
+
* `String()` form).
|
|
40
43
|
*
|
|
41
44
|
* @public
|
|
42
45
|
*/
|
|
43
|
-
export declare const YamlStringifyErrorCode: Schema.Literals<readonly ["CircularReference"]>;
|
|
46
|
+
export declare const YamlStringifyErrorCode: Schema.Literals<readonly ["CircularReference", "UnrepresentableValue"]>;
|
|
44
47
|
/**
|
|
45
48
|
* The union of all stringifier-stage error code string literals.
|
|
46
49
|
*
|
|
@@ -53,7 +56,7 @@ export type YamlStringifyErrorCode = typeof YamlStringifyErrorCode.Type;
|
|
|
53
56
|
*
|
|
54
57
|
* @public
|
|
55
58
|
*/
|
|
56
|
-
export declare const YamlModifyErrorCode: Schema.Literals<readonly ["EmptyDocument", "PathNotFound", "InvalidIndex", "NotNavigable", "MultiDocumentStream", "DirectiveCarryingDocument", "CircularReference", "NestingDepthExceeded"]>;
|
|
59
|
+
export declare const YamlModifyErrorCode: Schema.Literals<readonly ["EmptyDocument", "PathNotFound", "InvalidIndex", "NotNavigable", "MultiDocumentStream", "DirectiveCarryingDocument", "CircularReference", "NestingDepthExceeded", "UnrepresentableValue"]>;
|
|
57
60
|
/**
|
|
58
61
|
* The union of all modify-stage error code string literals.
|
|
59
62
|
*
|
|
@@ -66,7 +69,7 @@ export type YamlModifyErrorCode = typeof YamlModifyErrorCode.Type;
|
|
|
66
69
|
*
|
|
67
70
|
* @public
|
|
68
71
|
*/
|
|
69
|
-
export declare const YamlErrorCode: Schema.Union<readonly [Schema.Literals<readonly ["UnexpectedCharacter", "UnterminatedString", "InvalidEscapeSequence", "InvalidUnicode", "UnterminatedBlockScalar", "UnterminatedFlowCollection", "InvalidDirective", "InvalidTagHandle", "InvalidAnchorName", "UnexpectedByteOrderMark"]>, Schema.Literals<readonly ["InvalidIndentation", "DuplicateKey", "UnexpectedToken", "MissingValue", "MissingKey", "TabIndentation", "InvalidBlockStructure", "MalformedFlowCollection", "NestingDepthExceeded"]>, Schema.Literals<readonly ["UndefinedAlias", "DuplicateAnchor", "CircularAlias", "UnresolvedTag", "InvalidTagValue", "AliasCountExceeded", "InvalidDirective"]>, Schema.Literals<readonly ["CircularReference"]>, Schema.Literals<readonly ["EmptyDocument", "PathNotFound", "InvalidIndex", "NotNavigable", "MultiDocumentStream", "DirectiveCarryingDocument", "CircularReference", "NestingDepthExceeded"]>]>;
|
|
72
|
+
export declare const YamlErrorCode: Schema.Union<readonly [Schema.Literals<readonly ["UnexpectedCharacter", "UnterminatedString", "InvalidEscapeSequence", "InvalidUnicode", "UnterminatedBlockScalar", "UnterminatedFlowCollection", "InvalidDirective", "InvalidTagHandle", "InvalidAnchorName", "UnexpectedByteOrderMark"]>, Schema.Literals<readonly ["InvalidIndentation", "DuplicateKey", "UnexpectedToken", "MissingValue", "MissingKey", "TabIndentation", "InvalidBlockStructure", "MalformedFlowCollection", "NestingDepthExceeded"]>, Schema.Literals<readonly ["UndefinedAlias", "DuplicateAnchor", "CircularAlias", "UnresolvedTag", "InvalidTagValue", "AliasCountExceeded", "InvalidDirective"]>, Schema.Literals<readonly ["CircularReference", "UnrepresentableValue"]>, Schema.Literals<readonly ["EmptyDocument", "PathNotFound", "InvalidIndex", "NotNavigable", "MultiDocumentStream", "DirectiveCarryingDocument", "CircularReference", "NestingDepthExceeded", "UnrepresentableValue"]>]>;
|
|
70
73
|
/**
|
|
71
74
|
* The union of all YAML error code string literals.
|
|
72
75
|
*
|
|
@@ -74,7 +77,7 @@ export declare const YamlErrorCode: Schema.Union<readonly [Schema.Literals<reado
|
|
|
74
77
|
*/
|
|
75
78
|
export type YamlErrorCode = typeof YamlErrorCode.Type;
|
|
76
79
|
declare const YamlDiagnostic_base: Schema.Class<YamlDiagnostic, Schema.Struct<{
|
|
77
|
-
readonly code: Schema.Union<readonly [Schema.Literals<readonly ["UnexpectedCharacter", "UnterminatedString", "InvalidEscapeSequence", "InvalidUnicode", "UnterminatedBlockScalar", "UnterminatedFlowCollection", "InvalidDirective", "InvalidTagHandle", "InvalidAnchorName", "UnexpectedByteOrderMark"]>, Schema.Literals<readonly ["InvalidIndentation", "DuplicateKey", "UnexpectedToken", "MissingValue", "MissingKey", "TabIndentation", "InvalidBlockStructure", "MalformedFlowCollection", "NestingDepthExceeded"]>, Schema.Literals<readonly ["UndefinedAlias", "DuplicateAnchor", "CircularAlias", "UnresolvedTag", "InvalidTagValue", "AliasCountExceeded", "InvalidDirective"]>, Schema.Literals<readonly ["CircularReference"]>, Schema.Literals<readonly ["EmptyDocument", "PathNotFound", "InvalidIndex", "NotNavigable", "MultiDocumentStream", "DirectiveCarryingDocument", "CircularReference", "NestingDepthExceeded"]>]>;
|
|
80
|
+
readonly code: Schema.Union<readonly [Schema.Literals<readonly ["UnexpectedCharacter", "UnterminatedString", "InvalidEscapeSequence", "InvalidUnicode", "UnterminatedBlockScalar", "UnterminatedFlowCollection", "InvalidDirective", "InvalidTagHandle", "InvalidAnchorName", "UnexpectedByteOrderMark"]>, Schema.Literals<readonly ["InvalidIndentation", "DuplicateKey", "UnexpectedToken", "MissingValue", "MissingKey", "TabIndentation", "InvalidBlockStructure", "MalformedFlowCollection", "NestingDepthExceeded"]>, Schema.Literals<readonly ["UndefinedAlias", "DuplicateAnchor", "CircularAlias", "UnresolvedTag", "InvalidTagValue", "AliasCountExceeded", "InvalidDirective"]>, Schema.Literals<readonly ["CircularReference", "UnrepresentableValue"]>, Schema.Literals<readonly ["EmptyDocument", "PathNotFound", "InvalidIndex", "NotNavigable", "MultiDocumentStream", "DirectiveCarryingDocument", "CircularReference", "NestingDepthExceeded", "UnrepresentableValue"]>]>;
|
|
78
81
|
readonly message: Schema.String;
|
|
79
82
|
readonly offset: Schema.Number;
|
|
80
83
|
readonly length: Schema.Number;
|
|
@@ -288,11 +291,14 @@ declare const YamlStringifyError_base: Schema.Class<YamlStringifyError, Schema.T
|
|
|
288
291
|
readonly value: Schema.Unknown;
|
|
289
292
|
}>, import("effect/Cause").YieldableError>;
|
|
290
293
|
/**
|
|
291
|
-
* Stringification failure
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
294
|
+
* Stringification failure, carrying structured {@link YamlDiagnostic} entries
|
|
295
|
+
* and the offending value. Raised by {@link Yaml.stringify},
|
|
296
|
+
* `YamlDocument#stringify` and the encode direction of the schema factories
|
|
297
|
+
* on a circular reference (`CircularReference`), a value nested past the
|
|
298
|
+
* stringifier's recursion budget (`NestingDepthExceeded`) or a value with no
|
|
299
|
+
* YAML representation (`UnrepresentableValue` — a function or a symbol). The
|
|
300
|
+
* error itself has no `code` field: read the code from the diagnostics —
|
|
301
|
+
* `error.diagnostics[0].code` is the primary failure.
|
|
296
302
|
*
|
|
297
303
|
* @public
|
|
298
304
|
*/
|
|
@@ -384,10 +390,14 @@ export declare class Yaml {
|
|
|
384
390
|
static readonly parseAll: (text: string, options?: YamlParseOptions | undefined) => Effect.Effect<readonly unknown[], YamlParseError, never>;
|
|
385
391
|
/**
|
|
386
392
|
* Stringify a plain JavaScript value as YAML. Fails with
|
|
387
|
-
* {@link YamlStringifyError} on circular references (`CircularReference`)
|
|
388
|
-
*
|
|
389
|
-
* (`NestingDepthExceeded`)
|
|
390
|
-
*
|
|
393
|
+
* {@link YamlStringifyError} on circular references (`CircularReference`),
|
|
394
|
+
* on a value nested deeper than the stringifier's recursion budget
|
|
395
|
+
* (`NestingDepthExceeded`) and on a function or symbol anywhere in the
|
|
396
|
+
* value (`UnrepresentableValue`) — all surface through the typed error
|
|
397
|
+
* channel, never as a stack-overflow defect and never as the function's
|
|
398
|
+
* source text or `Symbol(s)` written into the document as a string. A
|
|
399
|
+
* `bigint` is an integer and renders bare, exactly as `YamlFormat.modify`
|
|
400
|
+
* writes one; `null` and `undefined` both render as `null`.
|
|
391
401
|
*
|
|
392
402
|
* @remarks
|
|
393
403
|
* A `"<<"` object key is emitted **quoted** (`'<<': …`). This is the
|
|
@@ -483,10 +493,11 @@ export declare class Yaml {
|
|
|
483
493
|
* The pure counterpart to {@link Yaml.stringify} for config-time callers
|
|
484
494
|
* that cannot `await`.
|
|
485
495
|
*
|
|
486
|
-
* Preserves the package contract — a circular reference (`CircularReference`)
|
|
487
|
-
*
|
|
488
|
-
*
|
|
489
|
-
* thrown
|
|
496
|
+
* Preserves the package contract — a circular reference (`CircularReference`),
|
|
497
|
+
* a value nested past the recursion budget (`NestingDepthExceeded`) or a
|
|
498
|
+
* function or symbol value (`UnrepresentableValue`) yields a `Failure`
|
|
499
|
+
* carrying a {@link YamlStringifyError} rather than a thrown defect; the
|
|
500
|
+
* method never throws.
|
|
490
501
|
*
|
|
491
502
|
* @example
|
|
492
503
|
* ```ts
|
|
@@ -1131,13 +1142,16 @@ export declare class YamlDocument extends YamlDocument_base {
|
|
|
1131
1142
|
static schema(options?: YamlParseOptions): Schema.Codec<YamlDocument, string>;
|
|
1132
1143
|
/**
|
|
1133
1144
|
* Stringify this document (contents, directives and framing) as YAML.
|
|
1134
|
-
*
|
|
1135
|
-
*
|
|
1136
|
-
*
|
|
1137
|
-
*
|
|
1138
|
-
*
|
|
1139
|
-
*
|
|
1140
|
-
*
|
|
1145
|
+
* A parsed document always stringifies; the failures belong to hand-built
|
|
1146
|
+
* ASTs and surface as {@link YamlStringifyError} through the typed error
|
|
1147
|
+
* channel, never as an unhandled stack-overflow defect or as corrupted
|
|
1148
|
+
* output: a cycle in the AST fails `CircularReference` on the first
|
|
1149
|
+
* re-entry of an ancestor collection (the node path keeps the same
|
|
1150
|
+
* ancestor set the value path does), a tree nested deeper than the
|
|
1151
|
+
* stringifier's recursion budget fails `NestingDepthExceeded`, and a
|
|
1152
|
+
* scalar node holding anything but `null`, a boolean, a number, a bigint
|
|
1153
|
+
* or a string — a function, a symbol, an object — fails
|
|
1154
|
+
* `UnrepresentableValue` rather than being written as its `String()` form.
|
|
1141
1155
|
* Defined in terms of {@link YamlDocument.stringifyResult} behind a
|
|
1142
1156
|
* `YamlDocument.stringify` span — synchronous callers can use that variant
|
|
1143
1157
|
* directly.
|
|
@@ -1164,11 +1178,10 @@ export declare class YamlDocument extends YamlDocument_base {
|
|
|
1164
1178
|
* primitive {@link YamlDocument.stringify} is defined in terms of, so a
|
|
1165
1179
|
* synchronous host can round-trip a document parsed with
|
|
1166
1180
|
* {@link YamlDocument.parseResult} without an Effect runtime. Fails with
|
|
1167
|
-
* {@link YamlStringifyError} exactly where `stringify` does: a
|
|
1168
|
-
* AST
|
|
1169
|
-
*
|
|
1170
|
-
*
|
|
1171
|
-
* `CircularReference`).
|
|
1181
|
+
* {@link YamlStringifyError} exactly where `stringify` does: a hand-built
|
|
1182
|
+
* AST containing a cycle (`CircularReference`), one nested deeper than the
|
|
1183
|
+
* stringifier's recursion budget (`NestingDepthExceeded`) or one whose
|
|
1184
|
+
* scalar node holds a value with no YAML form (`UnrepresentableValue`).
|
|
1172
1185
|
*
|
|
1173
1186
|
* @remarks
|
|
1174
1187
|
* `YamlStringifyOptions.lineWidth` is not honored here, for the reason
|
|
@@ -1420,7 +1433,10 @@ export declare class YamlFormat {
|
|
|
1420
1433
|
* sequence and any other non-null object as a block mapping over its own
|
|
1421
1434
|
* enumerable string keys, recursively — the same lowering
|
|
1422
1435
|
* {@link Yaml.stringify} applies to the same value, so `modify` and
|
|
1423
|
-
* `stringify` agree on what a given JavaScript value means
|
|
1436
|
+
* `stringify` agree on what a given JavaScript value means: a `bigint`
|
|
1437
|
+
* renders bare (`a: 10`, never `a: "10"`), `null` renders as `null`, and a
|
|
1438
|
+
* function or symbol fails `UnrepresentableValue` on both paths rather
|
|
1439
|
+
* than landing in the document as its `String()` form. For a synthesized
|
|
1424
1440
|
* subtree (an object/array value) only the surrounding document is
|
|
1425
1441
|
* preserved byte-for-byte; the subtree carries no comments and takes the
|
|
1426
1442
|
* stringifier's styles.
|
|
@@ -1444,12 +1460,13 @@ export declare class YamlFormat {
|
|
|
1444
1460
|
* whole document, which normalises line endings to LF, applies those
|
|
1445
1461
|
* options, and renders the replacement in the stringifier's styles.
|
|
1446
1462
|
*
|
|
1447
|
-
*
|
|
1448
|
-
*
|
|
1449
|
-
* reference (`CircularReference`)
|
|
1450
|
-
* levels in the output document
|
|
1451
|
-
*
|
|
1452
|
-
*
|
|
1463
|
+
* Three replacement values have no rendering and fail typed rather than
|
|
1464
|
+
* hanging, overflowing the stack or corrupting the document: one
|
|
1465
|
+
* containing a circular reference (`CircularReference`), one that would
|
|
1466
|
+
* sit deeper than 256 levels in the output document
|
|
1467
|
+
* (`NestingDepthExceeded`) and one containing a function or symbol
|
|
1468
|
+
* (`UnrepresentableValue`). The depth is counted from the document root,
|
|
1469
|
+
* so the same value can fit at `[]` and fail a few keys down.
|
|
1453
1470
|
*
|
|
1454
1471
|
* **Single-document contract.** A `path` carries no document index, so on
|
|
1455
1472
|
* a multi-document stream there is no rule for which document it names —
|
|
@@ -927,6 +927,7 @@ function shouldPreserveRaw(rawValue, value) {
|
|
|
927
927
|
if (Number.isNaN(value) || !Number.isFinite(value)) return false;
|
|
928
928
|
return rawValue !== String(value);
|
|
929
929
|
}
|
|
930
|
+
if (typeof value === "bigint") return rawValue !== value.toString();
|
|
930
931
|
return false;
|
|
931
932
|
}
|
|
932
933
|
|
package/internal/diagnostics.js
CHANGED
|
@@ -35,13 +35,18 @@ const YAML_COMPOSE_ERROR_CODES = [
|
|
|
35
35
|
"InvalidDirective"
|
|
36
36
|
];
|
|
37
37
|
/**
|
|
38
|
-
* Error codes for the stringifier stage. The engine's
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* `
|
|
42
|
-
* `
|
|
38
|
+
* Error codes for the stringifier stage. The engine's deliberate stringify
|
|
39
|
+
* failures are the circular-reference guard and the unrepresentable-value
|
|
40
|
+
* guard (a function or symbol on the value path, or a synthetic scalar node
|
|
41
|
+
* holding anything but `null`, a boolean, a number, a bigint or a string),
|
|
42
|
+
* both thrown as `StringifyFailure` carrying one of these codes; the facade
|
|
43
|
+
* materializes them so `YamlStringifyError` carries structured diagnostics
|
|
44
|
+
* rather than a `reason` string. `UnrepresentableValue` exists because the
|
|
45
|
+
* alternative — writing `String(value)` into the document — turned a function's
|
|
46
|
+
* source text or `Symbol(s)` into a quoted string that only surfaced on the
|
|
47
|
+
* next read.
|
|
43
48
|
*/
|
|
44
|
-
const YAML_STRINGIFY_ERROR_CODES = ["CircularReference"];
|
|
49
|
+
const YAML_STRINGIFY_ERROR_CODES = ["CircularReference", "UnrepresentableValue"];
|
|
45
50
|
/**
|
|
46
51
|
* Error codes for the modify stage (`YamlFormat.modify`'s guards and path
|
|
47
52
|
* navigation against an already-composed AST). Not raised by the
|
|
@@ -53,10 +58,11 @@ const YAML_STRINGIFY_ERROR_CODES = ["CircularReference"];
|
|
|
53
58
|
* without its `%TAG` orphans every shorthand tag that depends on it — the
|
|
54
59
|
* output would be unparseable — so modify fails typed rather than corrupting.
|
|
55
60
|
*
|
|
56
|
-
* `CircularReference` and `
|
|
57
|
-
* replacement value itself: `modify` lowers a plain
|
|
58
|
-
* AST nodes, and an object graph that points back at
|
|
59
|
-
* than `MAX_NESTING_DEPTH` has no finite YAML
|
|
61
|
+
* `CircularReference`, `NestingDepthExceeded` and `UnrepresentableValue` are
|
|
62
|
+
* the three limits on the replacement value itself: `modify` lowers a plain
|
|
63
|
+
* JavaScript value into AST nodes, and an object graph that points back at
|
|
64
|
+
* itself or nests deeper than `MAX_NESTING_DEPTH` has no finite YAML
|
|
65
|
+
* rendering, while a function or symbol has none at all. All three names are
|
|
60
66
|
* deliberately the ones the stringify and compose stages already use for the
|
|
61
67
|
* same conditions, so `YamlErrorCode` gains no member.
|
|
62
68
|
*/
|
|
@@ -68,7 +74,8 @@ const YAML_MODIFY_ERROR_CODES = [
|
|
|
68
74
|
"MultiDocumentStream",
|
|
69
75
|
"DirectiveCarryingDocument",
|
|
70
76
|
"CircularReference",
|
|
71
|
-
"NestingDepthExceeded"
|
|
77
|
+
"NestingDepthExceeded",
|
|
78
|
+
"UnrepresentableValue"
|
|
72
79
|
];
|
|
73
80
|
/**
|
|
74
81
|
* The single source of truth for which diagnostic codes are fatal to a
|
package/internal/stringifier.js
CHANGED
|
@@ -3,18 +3,32 @@ import { foldRenderedScalar, hasInteriorTrailingWhitespace, hasNewlineSpacesTab,
|
|
|
3
3
|
|
|
4
4
|
// src/internal/stringifier.ts
|
|
5
5
|
/**
|
|
6
|
-
* Thrown by the stringifier on its failure paths
|
|
7
|
-
*
|
|
6
|
+
* Thrown by the stringifier on its two deliberate failure paths: a circular
|
|
7
|
+
* reference (`CircularReference`) and a value with no YAML representation
|
|
8
|
+
* (`UnrepresentableValue` — a function or symbol on the value path, or a
|
|
9
|
+
* synthetic scalar node holding anything but `null`, a boolean, a number, a
|
|
10
|
+
* bigint or a string). The facade catches this and materializes the public
|
|
11
|
+
* stringify error under `code`.
|
|
8
12
|
*/
|
|
9
13
|
var StringifyFailure = class extends Error {
|
|
14
|
+
code;
|
|
10
15
|
reason;
|
|
11
|
-
constructor(reason) {
|
|
16
|
+
constructor(code, reason) {
|
|
12
17
|
super(reason);
|
|
13
18
|
this.name = "StringifyFailure";
|
|
19
|
+
this.code = code;
|
|
14
20
|
this.reason = reason;
|
|
15
21
|
}
|
|
16
22
|
};
|
|
17
23
|
/**
|
|
24
|
+
* Build the unrepresentable-value failure for a value of `kind` (its
|
|
25
|
+
* `typeof`). Shared by the value path and the node path so the two report
|
|
26
|
+
* the same condition in the same words.
|
|
27
|
+
*/
|
|
28
|
+
function unrepresentable(kind) {
|
|
29
|
+
return new StringifyFailure("UnrepresentableValue", `A ${kind} value has no YAML representation`);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
18
32
|
* Thrown by the value-stringifier trio when its mutual recursion exceeds
|
|
19
33
|
* {@link MAX_NESTING_DEPTH}. A deeply-nested acyclic value (e.g. a 50 000-deep
|
|
20
34
|
* array) would otherwise overflow the call stack as an unhandled `RangeError`
|
|
@@ -305,7 +319,7 @@ function renderNumber(n) {
|
|
|
305
319
|
*/
|
|
306
320
|
function detectCircular(value, seen) {
|
|
307
321
|
if (value !== null && typeof value === "object") {
|
|
308
|
-
if (seen.has(value)) throw new StringifyFailure("Circular reference detected");
|
|
322
|
+
if (seen.has(value)) throw new StringifyFailure("CircularReference", "Circular reference detected");
|
|
309
323
|
}
|
|
310
324
|
}
|
|
311
325
|
/** Resolves optional stringify options into a fully-defaulted context. */
|
|
@@ -360,7 +374,7 @@ function stringifyLines(value, ctx, depth, allowFold = true) {
|
|
|
360
374
|
ctx.seen.delete(value);
|
|
361
375
|
}
|
|
362
376
|
}
|
|
363
|
-
|
|
377
|
+
throw unrepresentable(typeof value);
|
|
364
378
|
}
|
|
365
379
|
/**
|
|
366
380
|
* Stringifies a JavaScript array into YAML sequence lines (no leading indent).
|
|
@@ -603,8 +617,15 @@ function stripNodeComments(node) {
|
|
|
603
617
|
function stringifyNodeLines(node, ctx, depth) {
|
|
604
618
|
if (depth > 256) throw new StringifyDepthExceeded();
|
|
605
619
|
if (node instanceof YamlScalar) return stringifyScalarNodeLines(node, ctx);
|
|
606
|
-
if (node instanceof YamlMap
|
|
607
|
-
|
|
620
|
+
if (node instanceof YamlMap || node instanceof YamlSeq) {
|
|
621
|
+
if (ctx.seen.has(node)) throw new StringifyFailure("CircularReference", "Circular reference detected in the document AST");
|
|
622
|
+
ctx.seen.add(node);
|
|
623
|
+
try {
|
|
624
|
+
return node instanceof YamlMap ? stringifyMapNodeLines(node, ctx, depth) : stringifySeqNodeLines(node, ctx, depth);
|
|
625
|
+
} finally {
|
|
626
|
+
ctx.seen.delete(node);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
608
629
|
if (node instanceof YamlAlias) return [`*${node.name}`];
|
|
609
630
|
return ["null"];
|
|
610
631
|
}
|
|
@@ -623,12 +644,13 @@ function stringifyScalarNodeLines(node, ctx) {
|
|
|
623
644
|
}
|
|
624
645
|
let lines;
|
|
625
646
|
if (val === null || val === void 0) {
|
|
626
|
-
if (isEmpty) lines = [""];
|
|
647
|
+
if (isEmpty && node.raw === void 0) lines = [""];
|
|
627
648
|
else lines = ["null"];
|
|
628
649
|
} else if (typeof val === "boolean") lines = [val ? "true" : "false"];
|
|
629
650
|
else if (typeof val === "number") lines = [node.raw !== void 0 ? node.raw : renderNumber(val)];
|
|
630
651
|
else if (typeof val === "string") lines = renderString(val, style, " ".repeat(ctx.indent), !!node.tag, ctx.forceDefaultStyles, node.chomp, ctx.parentPosition, ctx.quoteStyle, node.blockIndent, ctx.quoteCompat, ctx.inFlow).split("\n");
|
|
631
|
-
else lines = [
|
|
652
|
+
else if (typeof val === "bigint") lines = [node.raw !== void 0 ? node.raw : val.toString()];
|
|
653
|
+
else throw unrepresentable(typeof val);
|
|
632
654
|
if (node.tag) lines[0] = `${node.tag} ${lines[0]}`;
|
|
633
655
|
if (node.anchor) lines[0] = `&${node.anchor} ${lines[0]}`;
|
|
634
656
|
return lines;
|