@effected/yaml 0.23.0 → 0.24.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 +22 -28
- package/YamlDocument.js +124 -49
- package/YamlFormat.js +114 -55
- package/index.d.ts +158 -12
- package/package.json +1 -1
package/Yaml.js
CHANGED
|
@@ -224,8 +224,12 @@ const aliasCountExceededError = (message, text) => new YamlParseError({
|
|
|
224
224
|
/**
|
|
225
225
|
* Map an internal stringifier throw to its typed {@link YamlStringifyError},
|
|
226
226
|
* or return `undefined` for any other defect (which the caller re-throws).
|
|
227
|
-
* Shared by
|
|
228
|
-
*
|
|
227
|
+
* Shared by every stringify path — `Yaml.stringify`/`stringifyResult`, the
|
|
228
|
+
* schema encoders, `YamlDocument#stringifyResult` and `YamlFormat.modify`'s
|
|
229
|
+
* backstop — so all of them surface the hardening guards (circular
|
|
230
|
+
* reference, nesting-depth cap) identically.
|
|
231
|
+
*
|
|
232
|
+
* @internal
|
|
229
233
|
*/
|
|
230
234
|
const stringifyDefectToError = (defect, value) => {
|
|
231
235
|
if (defect instanceof StringifyFailure) return new YamlStringifyError({
|
|
@@ -266,12 +270,13 @@ const parseResultImpl = (text, options) => {
|
|
|
266
270
|
input: text
|
|
267
271
|
}));
|
|
268
272
|
const anchors = /* @__PURE__ */ new Map();
|
|
269
|
-
try
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
273
|
+
return Result.try({
|
|
274
|
+
try: () => nodeToJsValue(doc.contents, anchors, options?.maxAliasCount ?? 100),
|
|
275
|
+
catch: (defect) => {
|
|
276
|
+
if (defect instanceof AliasExpansionBudgetExceeded) return aliasCountExceededError(defect.message, text);
|
|
277
|
+
throw defect;
|
|
278
|
+
}
|
|
279
|
+
});
|
|
275
280
|
};
|
|
276
281
|
/**
|
|
277
282
|
* Synchronous multi-document parse returning a `Result`. Mirrors
|
|
@@ -308,15 +313,14 @@ const parseAllResultImpl = (text, options) => {
|
|
|
308
313
|
* recursion budget yields a `Failure` carrying a typed {@link YamlStringifyError},
|
|
309
314
|
* never a thrown defect.
|
|
310
315
|
*/
|
|
311
|
-
const stringifyResultImpl = (value, options) => {
|
|
312
|
-
try
|
|
313
|
-
|
|
314
|
-
} catch (defect) {
|
|
316
|
+
const stringifyResultImpl = (value, options) => Result.try({
|
|
317
|
+
try: () => stringifyValue(value, toStringifyInput(options)),
|
|
318
|
+
catch: (defect) => {
|
|
315
319
|
const error = stringifyDefectToError(defect, value);
|
|
316
|
-
if (error !== void 0) return
|
|
320
|
+
if (error !== void 0) return error;
|
|
317
321
|
throw defect;
|
|
318
322
|
}
|
|
319
|
-
};
|
|
323
|
+
});
|
|
320
324
|
/**
|
|
321
325
|
* Collect the raw diagnostics that make a composed document a parse failure:
|
|
322
326
|
* every fatal-code error, plus DuplicateKey warnings promoted to errors when
|
|
@@ -328,14 +332,6 @@ const failureRecords = (doc, uniqueKeys) => {
|
|
|
328
332
|
if (fatal.length > 0) return fatal;
|
|
329
333
|
return uniqueKeys ? doc.warnings.filter((w) => w.code === "DuplicateKey") : [];
|
|
330
334
|
};
|
|
331
|
-
const stringifyOrFail = (value, options) => Effect.try({
|
|
332
|
-
try: () => stringifyValue(value, toStringifyInput(options)),
|
|
333
|
-
catch: (defect) => {
|
|
334
|
-
const error = stringifyDefectToError(defect, value);
|
|
335
|
-
if (error !== void 0) return error;
|
|
336
|
-
throw defect;
|
|
337
|
-
}
|
|
338
|
-
});
|
|
339
335
|
/**
|
|
340
336
|
* Static entry points for YAML parsing, stringification, comment stripping,
|
|
341
337
|
* semantic equality and the schema factories. Not instantiable.
|
|
@@ -425,9 +421,7 @@ var Yaml = class Yaml {
|
|
|
425
421
|
* @returns An `Effect` that succeeds with the YAML text, or fails with
|
|
426
422
|
* {@link YamlStringifyError}.
|
|
427
423
|
*/
|
|
428
|
-
static stringify = Effect.fn("Yaml.stringify")(
|
|
429
|
-
return yield* stringifyOrFail(value, options);
|
|
430
|
-
});
|
|
424
|
+
static stringify = Effect.fn("Yaml.stringify")((value, options) => Effect.fromResult(stringifyResultImpl(value, options)));
|
|
431
425
|
/**
|
|
432
426
|
* Synchronous single-document parse, returning a `Result` instead of
|
|
433
427
|
* an `Effect`. A pure escape hatch for config-time callers that cannot
|
|
@@ -631,7 +625,7 @@ var Yaml = class Yaml {
|
|
|
631
625
|
static fromString(options) {
|
|
632
626
|
return Schema.String.pipe(Schema.decodeTo(Schema.Unknown, SchemaTransformation.transformEffect({
|
|
633
627
|
decode: (input) => Yaml.parse(input, options).pipe(Effect.mapError((error) => new SchemaIssue.InvalidValue({ message: error.message }, input))),
|
|
634
|
-
encode: (value) =>
|
|
628
|
+
encode: (value) => Effect.fromResult(stringifyResultImpl(value)).pipe(Effect.mapError((error) => new SchemaIssue.InvalidValue({ message: error.message }, value)))
|
|
635
629
|
})));
|
|
636
630
|
}
|
|
637
631
|
/**
|
|
@@ -655,7 +649,7 @@ var Yaml = class Yaml {
|
|
|
655
649
|
if (values.length === 0) return "";
|
|
656
650
|
const parts = [];
|
|
657
651
|
for (let index = 0; index < values.length; index++) {
|
|
658
|
-
const yaml = yield*
|
|
652
|
+
const yaml = yield* Effect.fromResult(stringifyResultImpl(values[index])).pipe(Effect.mapError((error) => new SchemaIssue.InvalidValue({ message: error.message }, values)));
|
|
659
653
|
parts.push(index > 0 ? `---\n${yaml}` : yaml);
|
|
660
654
|
}
|
|
661
655
|
return parts.join("");
|
|
@@ -774,4 +768,4 @@ function deepEqualValues(a, b) {
|
|
|
774
768
|
return false;
|
|
775
769
|
}
|
|
776
770
|
|
|
777
|
-
export { Yaml, YamlParseError, YamlParseOptions, YamlStringifyError, YamlStringifyOptions };
|
|
771
|
+
export { Yaml, YamlParseError, YamlParseOptions, YamlStringifyError, YamlStringifyOptions, stringifyDefectToError };
|
package/YamlDocument.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { YamlNode } from "./YamlNode.js";
|
|
2
2
|
import { composeAllDocuments, composeFirstDocument } from "./internal/composer/document.js";
|
|
3
3
|
import { isFatalCode } from "./internal/diagnostics.js";
|
|
4
|
-
import {
|
|
4
|
+
import { stringifyDocument } from "./internal/stringifier.js";
|
|
5
5
|
import { YamlDiagnostic } from "./YamlDiagnostic.js";
|
|
6
|
-
import { YamlParseError,
|
|
7
|
-
import { Effect, Schema, SchemaIssue, SchemaTransformation } from "effect";
|
|
6
|
+
import { YamlParseError, stringifyDefectToError } from "./Yaml.js";
|
|
7
|
+
import { Effect, Result, Schema, SchemaIssue, SchemaTransformation } from "effect";
|
|
8
8
|
|
|
9
9
|
// src/YamlDocument.ts
|
|
10
10
|
/**
|
|
@@ -58,11 +58,47 @@ var YamlDocument = class YamlDocument extends Schema.Class("YamlDocument")({
|
|
|
58
58
|
hasDocumentEnd: Schema.optionalKey(Schema.Boolean),
|
|
59
59
|
hasDocumentStartTab: Schema.optionalKey(Schema.Boolean)
|
|
60
60
|
}) {
|
|
61
|
+
/**
|
|
62
|
+
* Synchronous single-document parse, returning a `Result` instead of an
|
|
63
|
+
* `Effect`. This is the primitive {@link YamlDocument.parse} is defined in
|
|
64
|
+
* terms of — a synchronous host can call it without an Effect runtime.
|
|
65
|
+
* Keeps the full AST, directives and recovered diagnostics; fails with the
|
|
66
|
+
* aggregate {@link YamlParseError} when any fatal-code diagnostic is
|
|
67
|
+
* present, and non-fatal diagnostics are data on the returned document.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* import { YamlDocument } from "@effected/yaml";
|
|
72
|
+
* import { Result } from "effect";
|
|
73
|
+
*
|
|
74
|
+
* const result = YamlDocument.parseResult("name: Alice\n");
|
|
75
|
+
* if (Result.isSuccess(result)) {
|
|
76
|
+
* console.log(result.success.toValue()); // => { name: "Alice" }
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* @param text - The YAML source to parse.
|
|
81
|
+
* @param options - Optional {@link YamlParseOptions}; defaults apply for
|
|
82
|
+
* omitted fields.
|
|
83
|
+
* @returns A `Result` succeeding with the {@link YamlDocument}, or failing
|
|
84
|
+
* with {@link YamlParseError}.
|
|
85
|
+
*/
|
|
86
|
+
static parseResult(text, options) {
|
|
87
|
+
const raw = composeFirstDocument(text, toParseInput(options));
|
|
88
|
+
const fatal = raw.errors.filter((e) => isFatalCode(e.code));
|
|
89
|
+
if (fatal.length > 0) return Result.fail(new YamlParseError({
|
|
90
|
+
diagnostics: fatal.map((e) => YamlDiagnostic.fromRaw(e, text)),
|
|
91
|
+
input: text
|
|
92
|
+
}));
|
|
93
|
+
return Result.succeed(fromRawDocument(raw, text));
|
|
94
|
+
}
|
|
61
95
|
/**
|
|
62
96
|
* Parse a single YAML document, keeping the full AST, directives and
|
|
63
97
|
* recovered diagnostics. Fails with the aggregate {@link YamlParseError}
|
|
64
98
|
* when any fatal-code diagnostic is present; non-fatal diagnostics are
|
|
65
|
-
* data on the returned document.
|
|
99
|
+
* data on the returned document. Defined in terms of
|
|
100
|
+
* {@link YamlDocument.parseResult} — synchronous callers can use that
|
|
101
|
+
* variant directly.
|
|
66
102
|
*
|
|
67
103
|
* @param text - The YAML source to parse.
|
|
68
104
|
* @param options - Optional {@link YamlParseOptions}; defaults apply for
|
|
@@ -70,19 +106,46 @@ var YamlDocument = class YamlDocument extends Schema.Class("YamlDocument")({
|
|
|
70
106
|
* @returns An `Effect` that succeeds with the {@link YamlDocument}, or fails
|
|
71
107
|
* with {@link YamlParseError}.
|
|
72
108
|
*/
|
|
73
|
-
static parse = Effect.fn("YamlDocument.parse")(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
109
|
+
static parse = Effect.fn("YamlDocument.parse")((text, options) => Effect.fromResult(YamlDocument.parseResult(text, options)));
|
|
110
|
+
/**
|
|
111
|
+
* Synchronous multi-document parse, returning a `Result` instead of an
|
|
112
|
+
* `Effect` — the primitive {@link YamlDocument.parseAll} is defined in
|
|
113
|
+
* terms of. Any fatal diagnostic in any document — or a stream-level
|
|
114
|
+
* directive-placement error — fails the whole parse with one aggregate
|
|
115
|
+
* {@link YamlParseError}.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* import { YamlDocument } from "@effected/yaml";
|
|
120
|
+
* import { Result } from "effect";
|
|
121
|
+
*
|
|
122
|
+
* const result = YamlDocument.parseAllResult("a: 1\n---\nb: 2\n");
|
|
123
|
+
* if (Result.isSuccess(result)) {
|
|
124
|
+
* console.log(result.success.length); // => 2
|
|
125
|
+
* }
|
|
126
|
+
* ```
|
|
127
|
+
*
|
|
128
|
+
* @param text - The YAML stream to parse.
|
|
129
|
+
* @param options - Optional {@link YamlParseOptions}; defaults apply for
|
|
130
|
+
* omitted fields.
|
|
131
|
+
* @returns A `Result` succeeding with one {@link YamlDocument} per
|
|
132
|
+
* document, or failing with {@link YamlParseError}.
|
|
133
|
+
*/
|
|
134
|
+
static parseAllResult(text, options) {
|
|
135
|
+
const { documents, streamErrors } = composeAllDocuments(text, toParseInput(options));
|
|
136
|
+
const fatal = [...streamErrors.filter((e) => e.code === "InvalidDirective"), ...documents.flatMap((d) => d.errors.filter((e) => isFatalCode(e.code)))];
|
|
137
|
+
if (fatal.length > 0) return Result.fail(new YamlParseError({
|
|
77
138
|
diagnostics: fatal.map((e) => YamlDiagnostic.fromRaw(e, text)),
|
|
78
139
|
input: text
|
|
79
|
-
});
|
|
80
|
-
return fromRawDocument(raw, text);
|
|
81
|
-
}
|
|
140
|
+
}));
|
|
141
|
+
return Result.succeed(documents.map((raw) => fromRawDocument(raw, text)));
|
|
142
|
+
}
|
|
82
143
|
/**
|
|
83
144
|
* Parse a multi-document YAML stream into one {@link YamlDocument} per
|
|
84
145
|
* document. Any fatal diagnostic in any document — or a stream-level
|
|
85
|
-
* directive-placement error — fails the whole Effect.
|
|
146
|
+
* directive-placement error — fails the whole Effect. Defined in terms of
|
|
147
|
+
* {@link YamlDocument.parseAllResult} — synchronous callers can use that
|
|
148
|
+
* variant directly.
|
|
86
149
|
*
|
|
87
150
|
* @param text - The YAML stream to parse.
|
|
88
151
|
* @param options - Optional {@link YamlParseOptions}; defaults apply for
|
|
@@ -90,15 +153,7 @@ var YamlDocument = class YamlDocument extends Schema.Class("YamlDocument")({
|
|
|
90
153
|
* @returns An `Effect` that succeeds with one {@link YamlDocument} per
|
|
91
154
|
* document, or fails with {@link YamlParseError}.
|
|
92
155
|
*/
|
|
93
|
-
static parseAll = Effect.fn("YamlDocument.parseAll")(
|
|
94
|
-
const { documents, streamErrors } = composeAllDocuments(text, toParseInput(options));
|
|
95
|
-
const fatal = [...streamErrors.filter((e) => e.code === "InvalidDirective"), ...documents.flatMap((d) => d.errors.filter((e) => isFatalCode(e.code)))];
|
|
96
|
-
if (fatal.length > 0) return yield* new YamlParseError({
|
|
97
|
-
diagnostics: fatal.map((e) => YamlDiagnostic.fromRaw(e, text)),
|
|
98
|
-
input: text
|
|
99
|
-
});
|
|
100
|
-
return documents.map((raw) => fromRawDocument(raw, text));
|
|
101
|
-
});
|
|
156
|
+
static parseAll = Effect.fn("YamlDocument.parseAll")((text, options) => Effect.fromResult(YamlDocument.parseAllResult(text, options)));
|
|
102
157
|
/**
|
|
103
158
|
* A `Schema<YamlDocument, string>` decoding YAML text into a full
|
|
104
159
|
* document (AST, directives, diagnostics) and encoding a document back to
|
|
@@ -119,11 +174,16 @@ var YamlDocument = class YamlDocument extends Schema.Class("YamlDocument")({
|
|
|
119
174
|
}
|
|
120
175
|
/**
|
|
121
176
|
* Stringify this document (contents, directives and framing) as YAML.
|
|
122
|
-
* Fails with {@link YamlStringifyError} on
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
177
|
+
* Fails with {@link YamlStringifyError} (`NestingDepthExceeded`) on a
|
|
178
|
+
* synthetic AST nested deeper than the stringifier's recursion budget. A
|
|
179
|
+
* cycle introduced into a synthetic AST fails the same way: the node path
|
|
180
|
+
* keeps no ancestor set, so the cycle is caught by the depth cap rather
|
|
181
|
+
* than reported as `CircularReference`. Either way the failure surfaces
|
|
182
|
+
* through the typed error channel, never as an unhandled stack-overflow
|
|
183
|
+
* defect.
|
|
184
|
+
* Defined in terms of {@link YamlDocument.stringifyResult} behind a
|
|
185
|
+
* `YamlDocument.stringify` span — synchronous callers can use that variant
|
|
186
|
+
* directly.
|
|
127
187
|
*
|
|
128
188
|
* @remarks
|
|
129
189
|
* `YamlStringifyOptions.lineWidth` is not honored here: column-based
|
|
@@ -142,31 +202,46 @@ var YamlDocument = class YamlDocument extends Schema.Class("YamlDocument")({
|
|
|
142
202
|
* {@link YamlStringifyError}.
|
|
143
203
|
*/
|
|
144
204
|
stringify(options) {
|
|
145
|
-
return Effect.
|
|
205
|
+
return Effect.suspend(() => Effect.fromResult(this.stringifyResult(options))).pipe(Effect.withSpan("YamlDocument.stringify"));
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Synchronous stringify, returning a `Result` instead of an `Effect` — the
|
|
209
|
+
* primitive {@link YamlDocument.stringify} is defined in terms of, so a
|
|
210
|
+
* synchronous host can round-trip a document parsed with
|
|
211
|
+
* {@link YamlDocument.parseResult} without an Effect runtime. Fails with
|
|
212
|
+
* {@link YamlStringifyError} exactly where `stringify` does: a synthetic
|
|
213
|
+
* AST nested deeper than the stringifier's recursion budget, or one
|
|
214
|
+
* containing a cycle, both as `NestingDepthExceeded` (the node path keeps
|
|
215
|
+
* no ancestor set, so a cycle is caught by the depth cap, not reported as
|
|
216
|
+
* `CircularReference`).
|
|
217
|
+
*
|
|
218
|
+
* @remarks
|
|
219
|
+
* `YamlStringifyOptions.lineWidth` is not honored here, for the reason
|
|
220
|
+
* given on {@link YamlDocument.stringify}.
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```ts
|
|
224
|
+
* import { YamlDocument } from "@effected/yaml";
|
|
225
|
+
* import { Result } from "effect";
|
|
226
|
+
*
|
|
227
|
+
* const parsed = YamlDocument.parseResult("# keep\nname: Alice\n");
|
|
228
|
+
* if (Result.isSuccess(parsed)) {
|
|
229
|
+
* const text = parsed.success.stringifyResult();
|
|
230
|
+
* if (Result.isSuccess(text)) console.log(text.success); // => "# keep\nname: Alice\n"
|
|
231
|
+
* }
|
|
232
|
+
* ```
|
|
233
|
+
*
|
|
234
|
+
* @param options - Optional {@link YamlStringifyOptions}; defaults apply for
|
|
235
|
+
* omitted fields.
|
|
236
|
+
* @returns A `Result` succeeding with the YAML text, or failing with
|
|
237
|
+
* {@link YamlStringifyError}.
|
|
238
|
+
*/
|
|
239
|
+
stringifyResult(options) {
|
|
240
|
+
return Result.try({
|
|
146
241
|
try: () => stringifyDocument(toRawDocument(this), toStringifyInput(options)),
|
|
147
242
|
catch: (defect) => {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
code: "CircularReference",
|
|
151
|
-
message: defect.reason,
|
|
152
|
-
offset: 0,
|
|
153
|
-
length: 0,
|
|
154
|
-
line: 0,
|
|
155
|
-
character: 0
|
|
156
|
-
})],
|
|
157
|
-
value: this
|
|
158
|
-
});
|
|
159
|
-
if (defect instanceof StringifyDepthExceeded) return new YamlStringifyError({
|
|
160
|
-
diagnostics: [YamlDiagnostic.make({
|
|
161
|
-
code: "NestingDepthExceeded",
|
|
162
|
-
message: defect.message,
|
|
163
|
-
offset: 0,
|
|
164
|
-
length: 0,
|
|
165
|
-
line: 0,
|
|
166
|
-
character: 0
|
|
167
|
-
})],
|
|
168
|
-
value: this
|
|
169
|
-
});
|
|
243
|
+
const error = stringifyDefectToError(defect, this);
|
|
244
|
+
if (error !== void 0) return error;
|
|
170
245
|
throw defect;
|
|
171
246
|
}
|
|
172
247
|
});
|
package/YamlFormat.js
CHANGED
|
@@ -3,11 +3,11 @@ import { EMPTY_DOCUMENT, composeAllDocuments, composeFirstDocumentCounted } from
|
|
|
3
3
|
import { isFatalCode } from "./internal/diagnostics.js";
|
|
4
4
|
import { renderDoubleQuoted, renderSingleQuoted, stringifyDocument, stringifyValue, stripNodeComments } from "./internal/stringifier.js";
|
|
5
5
|
import { YamlDiagnostic } from "./YamlDiagnostic.js";
|
|
6
|
-
import { YamlStringifyOptions } from "./Yaml.js";
|
|
6
|
+
import { YamlStringifyOptions, stringifyDefectToError } from "./Yaml.js";
|
|
7
7
|
import { YamlEdit, YamlRange } from "./YamlEdit.js";
|
|
8
8
|
import { computeEdits } from "./internal/diff.js";
|
|
9
9
|
import { requoteScalarText } from "./internal/requote.js";
|
|
10
|
-
import { Effect, Schema } from "effect";
|
|
10
|
+
import { Effect, Result, Schema } from "effect";
|
|
11
11
|
|
|
12
12
|
// src/YamlFormat.ts
|
|
13
13
|
/**
|
|
@@ -263,7 +263,10 @@ function formatStream(text, documents, streamErrors, options) {
|
|
|
263
263
|
*
|
|
264
264
|
* The two conditions with no finite rendering fail typed rather than hanging
|
|
265
265
|
* or overflowing the stack: a cycle raises `CircularReference` and a graph
|
|
266
|
-
* deeper than `MAX_NESTING_DEPTH`
|
|
266
|
+
* that would sit deeper than `MAX_NESTING_DEPTH` in the output document
|
|
267
|
+
* raises `NestingDepthExceeded`. `depth` is measured in the stringifier's own
|
|
268
|
+
* units — one per node from the document root — so the caller passes the
|
|
269
|
+
* target's depth, not zero. `seen` holds
|
|
267
270
|
* the ancestors of the value being lowered, so a value repeated across
|
|
268
271
|
* siblings (a shared, acyclic sub-object) is lowered twice rather than
|
|
269
272
|
* rejected.
|
|
@@ -306,12 +309,17 @@ function jsValueToNode(value, seen, depth) {
|
|
|
306
309
|
length: 0
|
|
307
310
|
});
|
|
308
311
|
}
|
|
309
|
-
/**
|
|
310
|
-
|
|
311
|
-
|
|
312
|
+
/**
|
|
313
|
+
* Entry point for {@link jsValueToNode}: one `seen` set per lowering, counting
|
|
314
|
+
* depth from `targetDepth` — the depth the value will occupy in the output
|
|
315
|
+
* document (the path length: a root replacement sits at 0, a value one key
|
|
316
|
+
* down at 1).
|
|
317
|
+
*/
|
|
318
|
+
function lowerValue(value, targetDepth) {
|
|
319
|
+
return jsValueToNode(value, /* @__PURE__ */ new Set(), targetDepth);
|
|
312
320
|
}
|
|
313
321
|
function modifyDocument(doc, path, value) {
|
|
314
|
-
if (path.length === 0) return value === void 0 ? null : lowerValue(value);
|
|
322
|
+
if (path.length === 0) return value === void 0 ? null : lowerValue(value, 0);
|
|
315
323
|
if (doc.contents === null) throw new ModifyFailure("EmptyDocument", "Cannot navigate path in empty document", 0, 0);
|
|
316
324
|
return modifyNode(doc.contents, path, 0, value);
|
|
317
325
|
}
|
|
@@ -327,7 +335,7 @@ function modifyNode(node, path, depth, value) {
|
|
|
327
335
|
newItems.splice(pairIndex, 1);
|
|
328
336
|
return rebuildMap(node, newItems);
|
|
329
337
|
}
|
|
330
|
-
const newValueNode = lowerValue(value);
|
|
338
|
+
const newValueNode = lowerValue(value, depth + 1);
|
|
331
339
|
if (pairIndex >= 0) {
|
|
332
340
|
const newItems = [...node.items];
|
|
333
341
|
const oldPair = newItems[pairIndex];
|
|
@@ -367,8 +375,8 @@ function modifyNode(node, path, depth, value) {
|
|
|
367
375
|
const newItems = [...node.items];
|
|
368
376
|
if (value === void 0) {
|
|
369
377
|
if (idx < newItems.length) newItems.splice(idx, 1);
|
|
370
|
-
} else if (idx < newItems.length) newItems[idx] = lowerValue(value);
|
|
371
|
-
else newItems.push(lowerValue(value));
|
|
378
|
+
} else if (idx < newItems.length) newItems[idx] = lowerValue(value, depth + 1);
|
|
379
|
+
else newItems.push(lowerValue(value, depth + 1));
|
|
372
380
|
return rebuildSeq(node, newItems);
|
|
373
381
|
}
|
|
374
382
|
if (idx >= node.items.length) throw new ModifyFailure("InvalidIndex", `Index ${idx} out of bounds`, node.offset, node.length);
|
|
@@ -678,7 +686,9 @@ var YamlFormat = class YamlFormat {
|
|
|
678
686
|
return YamlEdit.applyAll(text, YamlFormat.format(text, range, options));
|
|
679
687
|
}
|
|
680
688
|
/**
|
|
681
|
-
* Compute the edits that insert, replace, or remove a value at `path
|
|
689
|
+
* Compute the edits that insert, replace, or remove a value at `path`,
|
|
690
|
+
* synchronously — the primitive {@link YamlFormat.modify} is defined in
|
|
691
|
+
* terms of, so a synchronous host can call it without an Effect runtime.
|
|
682
692
|
* Passing `value === undefined` removes the target key/element; a missing
|
|
683
693
|
* insertion target appends after the last pair/element. Fails with
|
|
684
694
|
* {@link YamlModificationError} on a fatal parse error or a structural
|
|
@@ -714,8 +724,10 @@ var YamlFormat = class YamlFormat {
|
|
|
714
724
|
*
|
|
715
725
|
* Two replacement values have no finite rendering and fail typed rather
|
|
716
726
|
* than hanging or overflowing the stack: one containing a circular
|
|
717
|
-
* reference (`CircularReference`) and one
|
|
718
|
-
* (`NestingDepthExceeded`).
|
|
727
|
+
* reference (`CircularReference`) and one that would sit deeper than 256
|
|
728
|
+
* levels in the output document (`NestingDepthExceeded`). The depth is
|
|
729
|
+
* counted from the document root, so the same value can fit at `[]` and
|
|
730
|
+
* fail a few keys down.
|
|
719
731
|
*
|
|
720
732
|
* **Single-document contract.** A `path` carries no document index, so on
|
|
721
733
|
* a multi-document stream there is no rule for which document it names —
|
|
@@ -740,63 +752,109 @@ var YamlFormat = class YamlFormat {
|
|
|
740
752
|
* target instead.
|
|
741
753
|
* @param options - Optional {@link YamlStringifyOptions} for the
|
|
742
754
|
* re-stringify step.
|
|
743
|
-
* @returns
|
|
744
|
-
* `YamlEdit.applyAll`), or
|
|
755
|
+
* @returns A `Result` succeeding with the edits to apply (via
|
|
756
|
+
* `YamlEdit.applyAll`), or failing with {@link YamlModificationError}.
|
|
745
757
|
*
|
|
746
758
|
* @remarks
|
|
747
759
|
* `options` is a bare {@link YamlStringifyOptions} — it controls only the
|
|
748
760
|
* internal re-stringify step, not a range (there is no range to restrict
|
|
749
761
|
* for a path-targeted modification).
|
|
750
762
|
*/
|
|
751
|
-
static
|
|
752
|
-
const
|
|
753
|
-
if (documentCount > 1) return yield* new YamlModificationError({
|
|
763
|
+
static modifyResult(text, path, value, options) {
|
|
764
|
+
const fail = (diagnostics) => Result.fail(new YamlModificationError({
|
|
754
765
|
path,
|
|
755
|
-
diagnostics
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
}
|
|
761
|
-
|
|
766
|
+
diagnostics
|
|
767
|
+
}));
|
|
768
|
+
const { document: doc, documentCount } = composeFirstDocumentCounted(text, {});
|
|
769
|
+
if (documentCount > 1) return fail([YamlDiagnostic.fromRaw({
|
|
770
|
+
code: "MultiDocumentStream",
|
|
771
|
+
message: `Cannot modify a multi-document stream (${documentCount} documents): modify re-emits exactly one document`,
|
|
772
|
+
offset: 0,
|
|
773
|
+
length: 0
|
|
774
|
+
}, text)]);
|
|
762
775
|
const fatal = doc.errors.filter((e) => isFatalCode(e.code));
|
|
763
|
-
if (fatal.length > 0) return
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
code: "DirectiveCarryingDocument",
|
|
771
|
-
message: "Cannot modify a document carrying %YAML/%TAG directives: modify does not re-emit directive lines, and dropping a %TAG orphans the shorthand tags that depend on it",
|
|
772
|
-
offset: 0,
|
|
773
|
-
length: 0
|
|
774
|
-
}, text)]
|
|
775
|
-
});
|
|
776
|
+
if (fatal.length > 0) return fail(fatal.map((e) => YamlDiagnostic.fromRaw(e, text)));
|
|
777
|
+
if (doc.directives.length > 0) return fail([YamlDiagnostic.fromRaw({
|
|
778
|
+
code: "DirectiveCarryingDocument",
|
|
779
|
+
message: "Cannot modify a document carrying %YAML/%TAG directives: modify does not re-emit directive lines, and dropping a %TAG orphans the shorthand tags that depend on it",
|
|
780
|
+
offset: 0,
|
|
781
|
+
length: 0
|
|
782
|
+
}, text)]);
|
|
776
783
|
const regional = tryRegionalScalarEdit(text, doc, path, value, options);
|
|
777
|
-
if (regional !== void 0) return regional.map((e) => YamlEdit.make(e));
|
|
784
|
+
if (regional !== void 0) return Result.succeed(regional.map((e) => YamlEdit.make(e)));
|
|
778
785
|
let newContents;
|
|
779
786
|
try {
|
|
780
787
|
newContents = modifyDocument(doc, path, value);
|
|
781
788
|
} catch (err) {
|
|
782
789
|
if (!(err instanceof ModifyFailure)) throw err;
|
|
783
|
-
return
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
length: err.length
|
|
790
|
-
}, text)]
|
|
791
|
-
});
|
|
790
|
+
return fail([YamlDiagnostic.fromRaw({
|
|
791
|
+
code: err.code,
|
|
792
|
+
message: err.message,
|
|
793
|
+
offset: err.offset,
|
|
794
|
+
length: err.length
|
|
795
|
+
}, text)]);
|
|
792
796
|
}
|
|
793
797
|
const outputDoc = {
|
|
794
798
|
...doc,
|
|
795
799
|
contents: newContents
|
|
796
800
|
};
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
801
|
+
let formatted;
|
|
802
|
+
try {
|
|
803
|
+
formatted = stringifyDocument(outputDoc, toStringifyInput(options));
|
|
804
|
+
} catch (defect) {
|
|
805
|
+
const error = stringifyDefectToError(defect, value);
|
|
806
|
+
if (error === void 0) throw defect;
|
|
807
|
+
return fail(error.diagnostics);
|
|
808
|
+
}
|
|
809
|
+
return Result.succeed(computeEdits(text, withSourceBom(text, formatted)).map((e) => YamlEdit.make(e)));
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Compute the edits that insert, replace, or remove a value at `path`.
|
|
813
|
+
* Defined in terms of {@link YamlFormat.modifyResult}, which carries the
|
|
814
|
+
* full contract — value lowering, region-confined scalar replacement, the
|
|
815
|
+
* single-document contract and the directive refusal — behind a
|
|
816
|
+
* `YamlFormat.modify` span; synchronous callers can use that variant
|
|
817
|
+
* directly.
|
|
818
|
+
*
|
|
819
|
+
* @param text - The YAML source to modify.
|
|
820
|
+
* @param path - The location to insert, replace or remove.
|
|
821
|
+
* @param value - The JavaScript value to write; `undefined` removes the
|
|
822
|
+
* target instead.
|
|
823
|
+
* @param options - Optional {@link YamlStringifyOptions} for the
|
|
824
|
+
* re-stringify step.
|
|
825
|
+
* @returns An `Effect` that succeeds with the edits to apply (via
|
|
826
|
+
* `YamlEdit.applyAll`), or fails with {@link YamlModificationError}.
|
|
827
|
+
*/
|
|
828
|
+
static modify = Effect.fn("YamlFormat.modify")((text, path, value, options) => Effect.fromResult(YamlFormat.modifyResult(text, path, value, options)));
|
|
829
|
+
/**
|
|
830
|
+
* Synchronous {@link YamlFormat.modifyToString}: modify `text` and apply the
|
|
831
|
+
* resulting edits in one step (`YamlEdit.applyAll ∘ modifyResult`),
|
|
832
|
+
* returning a `Result`. Inherits the {@link YamlFormat.modifyResult} error
|
|
833
|
+
* channel.
|
|
834
|
+
*
|
|
835
|
+
* @example
|
|
836
|
+
* ```ts
|
|
837
|
+
* import { YamlFormat } from "@effected/yaml";
|
|
838
|
+
* import { Result } from "effect";
|
|
839
|
+
*
|
|
840
|
+
* const result = YamlFormat.modifyToStringResult("port: 3000 # dev\n", ["port"], 8080);
|
|
841
|
+
* if (Result.isSuccess(result)) {
|
|
842
|
+
* console.log(result.success); // => "port: 8080 # dev\n"
|
|
843
|
+
* }
|
|
844
|
+
* ```
|
|
845
|
+
*
|
|
846
|
+
* @param text - The YAML source to modify.
|
|
847
|
+
* @param path - The location to insert, replace or remove.
|
|
848
|
+
* @param value - The JavaScript value to write; `undefined` removes the
|
|
849
|
+
* target instead.
|
|
850
|
+
* @param options - Optional {@link YamlStringifyOptions} for the
|
|
851
|
+
* re-stringify step.
|
|
852
|
+
* @returns A `Result` succeeding with the modified text, or failing with
|
|
853
|
+
* {@link YamlModificationError}.
|
|
854
|
+
*/
|
|
855
|
+
static modifyToStringResult(text, path, value, options) {
|
|
856
|
+
return Result.map(YamlFormat.modifyResult(text, path, value, options), (edits) => YamlEdit.applyAll(text, edits));
|
|
857
|
+
}
|
|
800
858
|
/**
|
|
801
859
|
* Modify `text` and apply the resulting edits in one step
|
|
802
860
|
* (`YamlEdit.applyAll ∘ modify`). Inherits the {@link YamlFormat.modify}
|
|
@@ -812,11 +870,12 @@ var YamlFormat = class YamlFormat {
|
|
|
812
870
|
* re-stringify step.
|
|
813
871
|
* @returns An `Effect` that succeeds with the modified text, or fails with
|
|
814
872
|
* {@link YamlModificationError}.
|
|
873
|
+
*
|
|
874
|
+
* @remarks
|
|
875
|
+
* Defined in terms of {@link YamlFormat.modifyToStringResult}; it opens its
|
|
876
|
+
* own span, with no nested `YamlFormat.modify` child span.
|
|
815
877
|
*/
|
|
816
|
-
static modifyToString = Effect.fn("YamlFormat.modifyToString")(
|
|
817
|
-
const edits = yield* YamlFormat.modify(text, path, value, options);
|
|
818
|
-
return YamlEdit.applyAll(text, edits);
|
|
819
|
-
});
|
|
878
|
+
static modifyToString = Effect.fn("YamlFormat.modifyToString")((text, path, value, options) => Effect.fromResult(YamlFormat.modifyToStringResult(text, path, value, options)));
|
|
820
879
|
};
|
|
821
880
|
|
|
822
881
|
export { YamlFormat, YamlFormattingOptions, YamlModificationError };
|
package/index.d.ts
CHANGED
|
@@ -1036,11 +1036,39 @@ declare const YamlDocument_base: Schema.Class<YamlDocument, Schema.Struct<{
|
|
|
1036
1036
|
* @public
|
|
1037
1037
|
*/
|
|
1038
1038
|
export declare class YamlDocument extends YamlDocument_base {
|
|
1039
|
+
/**
|
|
1040
|
+
* Synchronous single-document parse, returning a `Result` instead of an
|
|
1041
|
+
* `Effect`. This is the primitive {@link YamlDocument.parse} is defined in
|
|
1042
|
+
* terms of — a synchronous host can call it without an Effect runtime.
|
|
1043
|
+
* Keeps the full AST, directives and recovered diagnostics; fails with the
|
|
1044
|
+
* aggregate {@link YamlParseError} when any fatal-code diagnostic is
|
|
1045
|
+
* present, and non-fatal diagnostics are data on the returned document.
|
|
1046
|
+
*
|
|
1047
|
+
* @example
|
|
1048
|
+
* ```ts
|
|
1049
|
+
* import { YamlDocument } from "@effected/yaml";
|
|
1050
|
+
* import { Result } from "effect";
|
|
1051
|
+
*
|
|
1052
|
+
* const result = YamlDocument.parseResult("name: Alice\n");
|
|
1053
|
+
* if (Result.isSuccess(result)) {
|
|
1054
|
+
* console.log(result.success.toValue()); // => { name: "Alice" }
|
|
1055
|
+
* }
|
|
1056
|
+
* ```
|
|
1057
|
+
*
|
|
1058
|
+
* @param text - The YAML source to parse.
|
|
1059
|
+
* @param options - Optional {@link YamlParseOptions}; defaults apply for
|
|
1060
|
+
* omitted fields.
|
|
1061
|
+
* @returns A `Result` succeeding with the {@link YamlDocument}, or failing
|
|
1062
|
+
* with {@link YamlParseError}.
|
|
1063
|
+
*/
|
|
1064
|
+
static parseResult(text: string, options?: YamlParseOptions): Result.Result<YamlDocument, YamlParseError>;
|
|
1039
1065
|
/**
|
|
1040
1066
|
* Parse a single YAML document, keeping the full AST, directives and
|
|
1041
1067
|
* recovered diagnostics. Fails with the aggregate {@link YamlParseError}
|
|
1042
1068
|
* when any fatal-code diagnostic is present; non-fatal diagnostics are
|
|
1043
|
-
* data on the returned document.
|
|
1069
|
+
* data on the returned document. Defined in terms of
|
|
1070
|
+
* {@link YamlDocument.parseResult} — synchronous callers can use that
|
|
1071
|
+
* variant directly.
|
|
1044
1072
|
*
|
|
1045
1073
|
* @param text - The YAML source to parse.
|
|
1046
1074
|
* @param options - Optional {@link YamlParseOptions}; defaults apply for
|
|
@@ -1049,10 +1077,37 @@ export declare class YamlDocument extends YamlDocument_base {
|
|
|
1049
1077
|
* with {@link YamlParseError}.
|
|
1050
1078
|
*/
|
|
1051
1079
|
static readonly parse: (text: string, options?: YamlParseOptions | undefined) => Effect.Effect<YamlDocument, YamlParseError, never>;
|
|
1080
|
+
/**
|
|
1081
|
+
* Synchronous multi-document parse, returning a `Result` instead of an
|
|
1082
|
+
* `Effect` — the primitive {@link YamlDocument.parseAll} is defined in
|
|
1083
|
+
* terms of. Any fatal diagnostic in any document — or a stream-level
|
|
1084
|
+
* directive-placement error — fails the whole parse with one aggregate
|
|
1085
|
+
* {@link YamlParseError}.
|
|
1086
|
+
*
|
|
1087
|
+
* @example
|
|
1088
|
+
* ```ts
|
|
1089
|
+
* import { YamlDocument } from "@effected/yaml";
|
|
1090
|
+
* import { Result } from "effect";
|
|
1091
|
+
*
|
|
1092
|
+
* const result = YamlDocument.parseAllResult("a: 1\n---\nb: 2\n");
|
|
1093
|
+
* if (Result.isSuccess(result)) {
|
|
1094
|
+
* console.log(result.success.length); // => 2
|
|
1095
|
+
* }
|
|
1096
|
+
* ```
|
|
1097
|
+
*
|
|
1098
|
+
* @param text - The YAML stream to parse.
|
|
1099
|
+
* @param options - Optional {@link YamlParseOptions}; defaults apply for
|
|
1100
|
+
* omitted fields.
|
|
1101
|
+
* @returns A `Result` succeeding with one {@link YamlDocument} per
|
|
1102
|
+
* document, or failing with {@link YamlParseError}.
|
|
1103
|
+
*/
|
|
1104
|
+
static parseAllResult(text: string, options?: YamlParseOptions): Result.Result<ReadonlyArray<YamlDocument>, YamlParseError>;
|
|
1052
1105
|
/**
|
|
1053
1106
|
* Parse a multi-document YAML stream into one {@link YamlDocument} per
|
|
1054
1107
|
* document. Any fatal diagnostic in any document — or a stream-level
|
|
1055
|
-
* directive-placement error — fails the whole Effect.
|
|
1108
|
+
* directive-placement error — fails the whole Effect. Defined in terms of
|
|
1109
|
+
* {@link YamlDocument.parseAllResult} — synchronous callers can use that
|
|
1110
|
+
* variant directly.
|
|
1056
1111
|
*
|
|
1057
1112
|
* @param text - The YAML stream to parse.
|
|
1058
1113
|
* @param options - Optional {@link YamlParseOptions}; defaults apply for
|
|
@@ -1076,11 +1131,16 @@ export declare class YamlDocument extends YamlDocument_base {
|
|
|
1076
1131
|
static schema(options?: YamlParseOptions): Schema.Codec<YamlDocument, string>;
|
|
1077
1132
|
/**
|
|
1078
1133
|
* Stringify this document (contents, directives and framing) as YAML.
|
|
1079
|
-
* Fails with {@link YamlStringifyError} on
|
|
1080
|
-
*
|
|
1081
|
-
*
|
|
1082
|
-
*
|
|
1083
|
-
*
|
|
1134
|
+
* Fails with {@link YamlStringifyError} (`NestingDepthExceeded`) on a
|
|
1135
|
+
* synthetic AST nested deeper than the stringifier's recursion budget. A
|
|
1136
|
+
* cycle introduced into a synthetic AST fails the same way: the node path
|
|
1137
|
+
* keeps no ancestor set, so the cycle is caught by the depth cap rather
|
|
1138
|
+
* than reported as `CircularReference`. Either way the failure surfaces
|
|
1139
|
+
* through the typed error channel, never as an unhandled stack-overflow
|
|
1140
|
+
* defect.
|
|
1141
|
+
* Defined in terms of {@link YamlDocument.stringifyResult} behind a
|
|
1142
|
+
* `YamlDocument.stringify` span — synchronous callers can use that variant
|
|
1143
|
+
* directly.
|
|
1084
1144
|
*
|
|
1085
1145
|
* @remarks
|
|
1086
1146
|
* `YamlStringifyOptions.lineWidth` is not honored here: column-based
|
|
@@ -1099,6 +1159,39 @@ export declare class YamlDocument extends YamlDocument_base {
|
|
|
1099
1159
|
* {@link YamlStringifyError}.
|
|
1100
1160
|
*/
|
|
1101
1161
|
stringify(options?: YamlStringifyOptions): Effect.Effect<string, YamlStringifyError>;
|
|
1162
|
+
/**
|
|
1163
|
+
* Synchronous stringify, returning a `Result` instead of an `Effect` — the
|
|
1164
|
+
* primitive {@link YamlDocument.stringify} is defined in terms of, so a
|
|
1165
|
+
* synchronous host can round-trip a document parsed with
|
|
1166
|
+
* {@link YamlDocument.parseResult} without an Effect runtime. Fails with
|
|
1167
|
+
* {@link YamlStringifyError} exactly where `stringify` does: a synthetic
|
|
1168
|
+
* AST nested deeper than the stringifier's recursion budget, or one
|
|
1169
|
+
* containing a cycle, both as `NestingDepthExceeded` (the node path keeps
|
|
1170
|
+
* no ancestor set, so a cycle is caught by the depth cap, not reported as
|
|
1171
|
+
* `CircularReference`).
|
|
1172
|
+
*
|
|
1173
|
+
* @remarks
|
|
1174
|
+
* `YamlStringifyOptions.lineWidth` is not honored here, for the reason
|
|
1175
|
+
* given on {@link YamlDocument.stringify}.
|
|
1176
|
+
*
|
|
1177
|
+
* @example
|
|
1178
|
+
* ```ts
|
|
1179
|
+
* import { YamlDocument } from "@effected/yaml";
|
|
1180
|
+
* import { Result } from "effect";
|
|
1181
|
+
*
|
|
1182
|
+
* const parsed = YamlDocument.parseResult("# keep\nname: Alice\n");
|
|
1183
|
+
* if (Result.isSuccess(parsed)) {
|
|
1184
|
+
* const text = parsed.success.stringifyResult();
|
|
1185
|
+
* if (Result.isSuccess(text)) console.log(text.success); // => "# keep\nname: Alice\n"
|
|
1186
|
+
* }
|
|
1187
|
+
* ```
|
|
1188
|
+
*
|
|
1189
|
+
* @param options - Optional {@link YamlStringifyOptions}; defaults apply for
|
|
1190
|
+
* omitted fields.
|
|
1191
|
+
* @returns A `Result` succeeding with the YAML text, or failing with
|
|
1192
|
+
* {@link YamlStringifyError}.
|
|
1193
|
+
*/
|
|
1194
|
+
stringifyResult(options?: YamlStringifyOptions): Result.Result<string, YamlStringifyError>;
|
|
1102
1195
|
/**
|
|
1103
1196
|
* Reconstruct the plain JavaScript value of this document's contents,
|
|
1104
1197
|
* resolving anchors and aliases. `null` for an empty document. Pure and
|
|
@@ -1315,7 +1408,9 @@ export declare class YamlFormat {
|
|
|
1315
1408
|
*/
|
|
1316
1409
|
static formatToString(text: string, range?: YamlRangeLike, options?: YamlFormattingOptions): string;
|
|
1317
1410
|
/**
|
|
1318
|
-
* Compute the edits that insert, replace, or remove a value at `path
|
|
1411
|
+
* Compute the edits that insert, replace, or remove a value at `path`,
|
|
1412
|
+
* synchronously — the primitive {@link YamlFormat.modify} is defined in
|
|
1413
|
+
* terms of, so a synchronous host can call it without an Effect runtime.
|
|
1319
1414
|
* Passing `value === undefined` removes the target key/element; a missing
|
|
1320
1415
|
* insertion target appends after the last pair/element. Fails with
|
|
1321
1416
|
* {@link YamlModificationError} on a fatal parse error or a structural
|
|
@@ -1351,8 +1446,10 @@ export declare class YamlFormat {
|
|
|
1351
1446
|
*
|
|
1352
1447
|
* Two replacement values have no finite rendering and fail typed rather
|
|
1353
1448
|
* than hanging or overflowing the stack: one containing a circular
|
|
1354
|
-
* reference (`CircularReference`) and one
|
|
1355
|
-
* (`NestingDepthExceeded`).
|
|
1449
|
+
* reference (`CircularReference`) and one that would sit deeper than 256
|
|
1450
|
+
* levels in the output document (`NestingDepthExceeded`). The depth is
|
|
1451
|
+
* counted from the document root, so the same value can fit at `[]` and
|
|
1452
|
+
* fail a few keys down.
|
|
1356
1453
|
*
|
|
1357
1454
|
* **Single-document contract.** A `path` carries no document index, so on
|
|
1358
1455
|
* a multi-document stream there is no rule for which document it names —
|
|
@@ -1377,15 +1474,60 @@ export declare class YamlFormat {
|
|
|
1377
1474
|
* target instead.
|
|
1378
1475
|
* @param options - Optional {@link YamlStringifyOptions} for the
|
|
1379
1476
|
* re-stringify step.
|
|
1380
|
-
* @returns
|
|
1381
|
-
* `YamlEdit.applyAll`), or
|
|
1477
|
+
* @returns A `Result` succeeding with the edits to apply (via
|
|
1478
|
+
* `YamlEdit.applyAll`), or failing with {@link YamlModificationError}.
|
|
1382
1479
|
*
|
|
1383
1480
|
* @remarks
|
|
1384
1481
|
* `options` is a bare {@link YamlStringifyOptions} — it controls only the
|
|
1385
1482
|
* internal re-stringify step, not a range (there is no range to restrict
|
|
1386
1483
|
* for a path-targeted modification).
|
|
1387
1484
|
*/
|
|
1485
|
+
static modifyResult(text: string, path: YamlPath, value: unknown, options?: YamlStringifyOptions): Result.Result<ReadonlyArray<YamlEdit>, YamlModificationError>;
|
|
1486
|
+
/**
|
|
1487
|
+
* Compute the edits that insert, replace, or remove a value at `path`.
|
|
1488
|
+
* Defined in terms of {@link YamlFormat.modifyResult}, which carries the
|
|
1489
|
+
* full contract — value lowering, region-confined scalar replacement, the
|
|
1490
|
+
* single-document contract and the directive refusal — behind a
|
|
1491
|
+
* `YamlFormat.modify` span; synchronous callers can use that variant
|
|
1492
|
+
* directly.
|
|
1493
|
+
*
|
|
1494
|
+
* @param text - The YAML source to modify.
|
|
1495
|
+
* @param path - The location to insert, replace or remove.
|
|
1496
|
+
* @param value - The JavaScript value to write; `undefined` removes the
|
|
1497
|
+
* target instead.
|
|
1498
|
+
* @param options - Optional {@link YamlStringifyOptions} for the
|
|
1499
|
+
* re-stringify step.
|
|
1500
|
+
* @returns An `Effect` that succeeds with the edits to apply (via
|
|
1501
|
+
* `YamlEdit.applyAll`), or fails with {@link YamlModificationError}.
|
|
1502
|
+
*/
|
|
1388
1503
|
static readonly modify: (text: string, path: YamlPath, value: unknown, options?: YamlStringifyOptions | undefined) => Effect.Effect<readonly YamlEdit[], YamlModificationError, never>;
|
|
1504
|
+
/**
|
|
1505
|
+
* Synchronous {@link YamlFormat.modifyToString}: modify `text` and apply the
|
|
1506
|
+
* resulting edits in one step (`YamlEdit.applyAll ∘ modifyResult`),
|
|
1507
|
+
* returning a `Result`. Inherits the {@link YamlFormat.modifyResult} error
|
|
1508
|
+
* channel.
|
|
1509
|
+
*
|
|
1510
|
+
* @example
|
|
1511
|
+
* ```ts
|
|
1512
|
+
* import { YamlFormat } from "@effected/yaml";
|
|
1513
|
+
* import { Result } from "effect";
|
|
1514
|
+
*
|
|
1515
|
+
* const result = YamlFormat.modifyToStringResult("port: 3000 # dev\n", ["port"], 8080);
|
|
1516
|
+
* if (Result.isSuccess(result)) {
|
|
1517
|
+
* console.log(result.success); // => "port: 8080 # dev\n"
|
|
1518
|
+
* }
|
|
1519
|
+
* ```
|
|
1520
|
+
*
|
|
1521
|
+
* @param text - The YAML source to modify.
|
|
1522
|
+
* @param path - The location to insert, replace or remove.
|
|
1523
|
+
* @param value - The JavaScript value to write; `undefined` removes the
|
|
1524
|
+
* target instead.
|
|
1525
|
+
* @param options - Optional {@link YamlStringifyOptions} for the
|
|
1526
|
+
* re-stringify step.
|
|
1527
|
+
* @returns A `Result` succeeding with the modified text, or failing with
|
|
1528
|
+
* {@link YamlModificationError}.
|
|
1529
|
+
*/
|
|
1530
|
+
static modifyToStringResult(text: string, path: YamlPath, value: unknown, options?: YamlStringifyOptions): Result.Result<string, YamlModificationError>;
|
|
1389
1531
|
/**
|
|
1390
1532
|
* Modify `text` and apply the resulting edits in one step
|
|
1391
1533
|
* (`YamlEdit.applyAll ∘ modify`). Inherits the {@link YamlFormat.modify}
|
|
@@ -1401,6 +1543,10 @@ export declare class YamlFormat {
|
|
|
1401
1543
|
* re-stringify step.
|
|
1402
1544
|
* @returns An `Effect` that succeeds with the modified text, or fails with
|
|
1403
1545
|
* {@link YamlModificationError}.
|
|
1546
|
+
*
|
|
1547
|
+
* @remarks
|
|
1548
|
+
* Defined in terms of {@link YamlFormat.modifyToStringResult}; it opens its
|
|
1549
|
+
* own span, with no nested `YamlFormat.modify` child span.
|
|
1404
1550
|
*/
|
|
1405
1551
|
static readonly modifyToString: (text: string, path: YamlPath, value: unknown, options?: YamlStringifyOptions | undefined) => Effect.Effect<string, YamlModificationError, never>;
|
|
1406
1552
|
}
|