@effected/yaml 0.1.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.
@@ -0,0 +1,181 @@
1
+ import { YamlNode } from "./YamlNode.js";
2
+ import { composeAllDocuments, composeFirstDocument } from "./internal/composer/document.js";
3
+ import { isFatalCode } from "./internal/diagnostics.js";
4
+ import { StringifyDepthExceeded, StringifyFailure, stringifyDocument } from "./internal/stringifier.js";
5
+ import { YamlDiagnostic } from "./YamlDiagnostic.js";
6
+ import { YamlParseError, YamlStringifyError } from "./Yaml.js";
7
+ import { Effect, Option, Schema, SchemaIssue, SchemaTransformation } from "effect";
8
+
9
+ //#region src/YamlDocument.ts
10
+ /**
11
+ * A YAML directive appearing before a document (e.g. `%YAML 1.2` or
12
+ * `%TAG ! tag:example.com,2000:`). `"YAML"` and `"TAG"` are the YAML 1.2
13
+ * spec-defined directives; any other name is a reserved directive preserved
14
+ * for round-trip fidelity.
15
+ *
16
+ * @public
17
+ */
18
+ var YamlDirective = class extends Schema.Class("YamlDirective")({
19
+ name: Schema.String,
20
+ parameters: Schema.Array(Schema.String)
21
+ }) {};
22
+ /**
23
+ * A parsed YAML document: the root {@link (YamlNode:type)} (or `null` when
24
+ * empty), recovered `errors` and `warnings` as {@link YamlDiagnostic} data,
25
+ * the {@link YamlDirective} list, an optional document-level comment, and the
26
+ * `---`/`...` framing flags (absent flags read as `false`).
27
+ *
28
+ * Construct via `YamlDocument.parse` / `parseAll`; `YamlDocument.make` is for
29
+ * synthetic documents.
30
+ *
31
+ * @public
32
+ */
33
+ var YamlDocument = class YamlDocument extends Schema.Class("YamlDocument")({
34
+ contents: Schema.NullOr(Schema.suspend(() => YamlNode)),
35
+ errors: Schema.Array(YamlDiagnostic),
36
+ warnings: Schema.Array(YamlDiagnostic),
37
+ directives: Schema.Array(YamlDirective),
38
+ comment: Schema.optionalKey(Schema.String),
39
+ hasDocumentStart: Schema.optionalKey(Schema.Boolean),
40
+ hasDocumentEnd: Schema.optionalKey(Schema.Boolean),
41
+ hasDocumentStartTab: Schema.optionalKey(Schema.Boolean)
42
+ }) {
43
+ /**
44
+ * Parse a single YAML document, keeping the full AST, directives and
45
+ * recovered diagnostics. Fails with the aggregate {@link YamlParseError}
46
+ * when any fatal-code diagnostic is present; non-fatal diagnostics are
47
+ * data on the returned document.
48
+ */
49
+ static parse = Effect.fn("YamlDocument.parse")(function* (text, options) {
50
+ const raw = composeFirstDocument(text, toParseInput(options));
51
+ const fatal = raw.errors.filter((e) => isFatalCode(e.code));
52
+ if (fatal.length > 0) return yield* new YamlParseError({
53
+ diagnostics: fatal.map((e) => YamlDiagnostic.fromRaw(e, text)),
54
+ input: text
55
+ });
56
+ return fromRawDocument(raw, text);
57
+ });
58
+ /**
59
+ * Parse a multi-document YAML stream into one {@link YamlDocument} per
60
+ * document. Any fatal diagnostic in any document — or a stream-level
61
+ * directive-placement error — fails the whole Effect.
62
+ */
63
+ static parseAll = Effect.fn("YamlDocument.parseAll")(function* (text, options) {
64
+ const { documents, streamErrors } = composeAllDocuments(text, toParseInput(options));
65
+ const fatal = [...streamErrors.filter((e) => e.code === "InvalidDirective"), ...documents.flatMap((d) => d.errors.filter((e) => isFatalCode(e.code)))];
66
+ if (fatal.length > 0) return yield* new YamlParseError({
67
+ diagnostics: fatal.map((e) => YamlDiagnostic.fromRaw(e, text)),
68
+ input: text
69
+ });
70
+ return documents.map((raw) => fromRawDocument(raw, text));
71
+ });
72
+ /**
73
+ * A `Schema<YamlDocument, string>` decoding YAML text into a full
74
+ * document (AST, directives, diagnostics) and encoding a document back to
75
+ * YAML text.
76
+ *
77
+ * Schema-producing: each call returns a fresh schema whose derivation
78
+ * caches are not shared across calls; bind the result to a `const` on hot
79
+ * paths.
80
+ */
81
+ static schema(options) {
82
+ return Schema.String.pipe(Schema.decodeTo(Schema.instanceOf(YamlDocument), SchemaTransformation.transformOrFail({
83
+ decode: (input) => YamlDocument.parse(input, options).pipe(Effect.mapError((error) => new SchemaIssue.InvalidValue(Option.some(input), { message: error.message }))),
84
+ encode: (doc) => doc.stringify().pipe(Effect.mapError((error) => new SchemaIssue.InvalidValue(Option.some(doc), { message: error.message })))
85
+ })));
86
+ }
87
+ /**
88
+ * Stringify this document (contents, directives and framing) as YAML.
89
+ * Fails with {@link YamlStringifyError} on circular references introduced
90
+ * into a synthetic AST (`CircularReference`) or on a synthetic AST nested
91
+ * deeper than the stringifier's recursion budget (`NestingDepthExceeded`)
92
+ * — both surface through the typed error channel rather than as an
93
+ * unhandled stack-overflow defect.
94
+ */
95
+ stringify(options) {
96
+ return Effect.try({
97
+ try: () => stringifyDocument(toRawDocument(this), toStringifyInput(options)),
98
+ catch: (defect) => {
99
+ if (defect instanceof StringifyFailure) return new YamlStringifyError({
100
+ diagnostics: [YamlDiagnostic.make({
101
+ code: "CircularReference",
102
+ message: defect.reason,
103
+ offset: 0,
104
+ length: 0,
105
+ line: 0,
106
+ character: 0
107
+ })],
108
+ value: this
109
+ });
110
+ if (defect instanceof StringifyDepthExceeded) return new YamlStringifyError({
111
+ diagnostics: [YamlDiagnostic.make({
112
+ code: "NestingDepthExceeded",
113
+ message: defect.message,
114
+ offset: 0,
115
+ length: 0,
116
+ line: 0,
117
+ character: 0
118
+ })],
119
+ value: this
120
+ });
121
+ throw defect;
122
+ }
123
+ });
124
+ }
125
+ /**
126
+ * Reconstruct the plain JavaScript value of this document's contents,
127
+ * resolving anchors and aliases. `null` for an empty document. Pure and
128
+ * total.
129
+ */
130
+ toValue() {
131
+ if (this.contents === null) return null;
132
+ const anchors = /* @__PURE__ */ new Map();
133
+ return this.contents.toValue(anchors);
134
+ }
135
+ };
136
+ const toParseInput = (options) => options === void 0 ? {} : {
137
+ strict: options.strict,
138
+ maxAliasCount: options.maxAliasCount,
139
+ uniqueKeys: options.uniqueKeys
140
+ };
141
+ const toStringifyInput = (options) => options === void 0 ? {} : {
142
+ indent: options.indent,
143
+ lineWidth: options.lineWidth,
144
+ defaultScalarStyle: options.defaultScalarStyle,
145
+ defaultCollectionStyle: options.defaultCollectionStyle,
146
+ sortKeys: options.sortKeys,
147
+ finalNewline: options.finalNewline,
148
+ forceDefaultStyles: options.forceDefaultStyles
149
+ };
150
+ /** Materialize a raw engine document into the public class. */
151
+ function fromRawDocument(raw, text) {
152
+ return new YamlDocument({
153
+ contents: raw.contents,
154
+ errors: raw.errors.map((e) => YamlDiagnostic.fromRaw(e, text)),
155
+ warnings: raw.warnings.map((w) => YamlDiagnostic.fromRaw(w, text)),
156
+ directives: raw.directives.map((d) => new YamlDirective({
157
+ name: d.name,
158
+ parameters: d.parameters
159
+ })),
160
+ ...raw.comment !== void 0 ? { comment: raw.comment } : {},
161
+ hasDocumentStart: raw.hasDocumentStart,
162
+ hasDocumentEnd: raw.hasDocumentEnd,
163
+ hasDocumentStartTab: raw.hasDocumentStartTab
164
+ });
165
+ }
166
+ /** Project the public class back onto the raw shape the engine consumes. */
167
+ function toRawDocument(doc) {
168
+ return {
169
+ contents: doc.contents,
170
+ errors: [],
171
+ warnings: [],
172
+ directives: doc.directives,
173
+ ...doc.comment !== void 0 ? { comment: doc.comment } : {},
174
+ hasDocumentStart: doc.hasDocumentStart ?? false,
175
+ hasDocumentEnd: doc.hasDocumentEnd ?? false,
176
+ hasDocumentStartTab: doc.hasDocumentStartTab ?? false
177
+ };
178
+ }
179
+
180
+ //#endregion
181
+ export { YamlDirective, YamlDocument };
package/YamlEdit.js ADDED
@@ -0,0 +1,45 @@
1
+ import { Schema } from "effect";
2
+
3
+ //#region src/YamlEdit.ts
4
+ /**
5
+ * A range within a YAML document, expressed as a zero-based character
6
+ * `offset` and a `length` in UTF-16 code units. Pass to `YamlFormat.format`
7
+ * to restrict formatting to a region.
8
+ *
9
+ * @public
10
+ */
11
+ var YamlRange = class extends Schema.Class("YamlRange")({
12
+ offset: Schema.Number,
13
+ length: Schema.Number
14
+ }) {};
15
+ /**
16
+ * A non-mutating text edit: replace the span `[offset, offset + length)` with
17
+ * `content`. Set `length` to `0` to insert, `content` to `""` to delete.
18
+ *
19
+ * @remarks
20
+ * Structurally identical to `@effected/jsonc`'s edit shape (same field names,
21
+ * types and semantics) per the jsonc/yaml parity convention, so consumer code
22
+ * can be written once over "a document codec's Edit/Range/Path".
23
+ *
24
+ * @public
25
+ */
26
+ var YamlEdit = class extends Schema.Class("YamlEdit")({
27
+ offset: Schema.Number,
28
+ length: Schema.Number,
29
+ content: Schema.String
30
+ }) {
31
+ /**
32
+ * Apply `edits` to `text`, producing a new string. Edits are applied in
33
+ * reverse-offset order so earlier offsets stay valid; the input `edits`
34
+ * array is not mutated. Pure and total.
35
+ */
36
+ static applyAll(text, edits) {
37
+ const sorted = [...edits].sort((a, b) => b.offset - a.offset);
38
+ let result = text;
39
+ for (const edit of sorted) result = result.substring(0, edit.offset) + edit.content + result.substring(edit.offset + edit.length);
40
+ return result;
41
+ }
42
+ };
43
+
44
+ //#endregion
45
+ export { YamlEdit, YamlRange };
package/YamlFormat.js ADDED
@@ -0,0 +1,309 @@
1
+ import { YamlMap, YamlPair, YamlScalar, YamlSeq } from "./YamlNode.js";
2
+ import { composeFirstDocument } from "./internal/composer/document.js";
3
+ import { isFatalCode } from "./internal/diagnostics.js";
4
+ import { stringifyDocument, stripNodeComments } from "./internal/stringifier.js";
5
+ import { YamlDiagnostic } from "./YamlDiagnostic.js";
6
+ import { YamlStringifyOptions } from "./Yaml.js";
7
+ import { YamlEdit, YamlRange } from "./YamlEdit.js";
8
+ import { computeEdits } from "./internal/diff.js";
9
+ import { Effect, Schema } from "effect";
10
+
11
+ //#region src/YamlFormat.ts
12
+ /**
13
+ * Options controlling formatting behavior: every {@link YamlStringifyOptions}
14
+ * field (derived, not hand-duplicated) plus `preserveComments` (default
15
+ * `true`) and `range` (restrict edits to a region; see the module-level
16
+ * remarks on the `range` parameter vs. this field).
17
+ *
18
+ * @public
19
+ */
20
+ var YamlFormattingOptions = class extends Schema.Class("YamlFormattingOptions")({
21
+ ...YamlStringifyOptions.fields,
22
+ preserveComments: Schema.optionalKey(Schema.Boolean),
23
+ range: Schema.optionalKey(YamlRange)
24
+ }) {};
25
+ /**
26
+ * Raised when `YamlFormat.modify` cannot navigate the requested path against
27
+ * the composed AST (a structural mismatch) or the source fails to parse.
28
+ * Carries structured {@link YamlDiagnostic} entries — never a collapsed
29
+ * `reason` string (the structure-preserving-errors house rule).
30
+ *
31
+ * @public
32
+ */
33
+ var YamlModificationError = class extends Schema.TaggedErrorClass()("YamlModificationError", {
34
+ path: Schema.Array(Schema.Union([Schema.String, Schema.Number])),
35
+ diagnostics: Schema.Array(YamlDiagnostic)
36
+ }) {
37
+ get message() {
38
+ const summary = this.diagnostics.map((d) => d.message).join("; ");
39
+ return `Modification failed at path [${this.path.join(", ")}]: ${summary}`;
40
+ }
41
+ };
42
+ /**
43
+ * Thrown by the pure AST-navigation helpers on a structural mismatch.
44
+ * `modify` catches this and materializes {@link YamlModificationError}.
45
+ */
46
+ var ModifyFailure = class extends Error {
47
+ code;
48
+ offset;
49
+ length;
50
+ constructor(code, message, offset, length) {
51
+ super(message);
52
+ this.name = "ModifyFailure";
53
+ this.code = code;
54
+ this.offset = offset;
55
+ this.length = length;
56
+ }
57
+ };
58
+ const toStringifyInput = (options) => options === void 0 ? {} : {
59
+ indent: options.indent,
60
+ lineWidth: options.lineWidth,
61
+ defaultScalarStyle: options.defaultScalarStyle,
62
+ defaultCollectionStyle: options.defaultCollectionStyle,
63
+ sortKeys: options.sortKeys,
64
+ finalNewline: options.finalNewline,
65
+ forceDefaultStyles: options.forceDefaultStyles
66
+ };
67
+ /** Normalize a `format`-positional range and the options-bag fallback into one plain shape (or `undefined`). */
68
+ function resolveRange(positional, fromOptions) {
69
+ const range = positional ?? fromOptions;
70
+ return range === void 0 ? void 0 : {
71
+ offset: range.offset,
72
+ length: range.length
73
+ };
74
+ }
75
+ /** Copy only the defined entries of `fields` — never emits an explicit `undefined` into a v4 `optionalKey` field. */
76
+ function definedFields(fields) {
77
+ const out = {};
78
+ for (const key of Object.keys(fields)) if (fields[key] !== void 0) out[key] = fields[key];
79
+ return out;
80
+ }
81
+ /**
82
+ * Format a document via the parse → stringify round-trip and diff the
83
+ * output against the source, returning `undefined` when the input has a
84
+ * fatal parse error (never corrupt malformed input).
85
+ */
86
+ function formatDocument(text, options) {
87
+ const doc = composeFirstDocument(text, {});
88
+ if (doc.errors.some((e) => isFatalCode(e.code))) return void 0;
89
+ const preserveComments = options?.preserveComments ?? true;
90
+ return stringifyDocument({
91
+ contents: !preserveComments && doc.contents !== null ? stripNodeComments(doc.contents) : doc.contents,
92
+ errors: doc.errors,
93
+ warnings: doc.warnings,
94
+ directives: doc.directives,
95
+ ...preserveComments ? definedFields({ comment: doc.comment }) : {},
96
+ hasDocumentStart: doc.hasDocumentStart,
97
+ hasDocumentEnd: doc.hasDocumentEnd,
98
+ hasDocumentStartTab: doc.hasDocumentStartTab
99
+ }, toStringifyInput(options));
100
+ }
101
+ /** Convert a plain JS scalar value into a synthetic `YamlScalar` (offset/length are irrelevant — immediately re-stringified). */
102
+ function jsValueToNode(value) {
103
+ return YamlScalar.make({
104
+ value,
105
+ style: "plain",
106
+ offset: 0,
107
+ length: 0
108
+ });
109
+ }
110
+ function modifyDocument(doc, path, value) {
111
+ if (path.length === 0) return value === void 0 ? null : jsValueToNode(value);
112
+ if (doc.contents === null) throw new ModifyFailure("EmptyDocument", "Cannot navigate path in empty document", 0, 0);
113
+ return modifyNode(doc.contents, path, 0, value);
114
+ }
115
+ function modifyNode(node, path, depth, value) {
116
+ const segment = path[depth];
117
+ const isLast = depth === path.length - 1;
118
+ if (node instanceof YamlMap) {
119
+ const pairIndex = node.items.findIndex((pair) => pair.key instanceof YamlScalar && pair.key.value === segment);
120
+ if (isLast) {
121
+ if (value === void 0) {
122
+ if (pairIndex < 0) return node;
123
+ const newItems = [...node.items];
124
+ newItems.splice(pairIndex, 1);
125
+ return rebuildMap(node, newItems);
126
+ }
127
+ const newValueNode = jsValueToNode(value);
128
+ if (pairIndex >= 0) {
129
+ const newItems = [...node.items];
130
+ const oldPair = newItems[pairIndex];
131
+ newItems[pairIndex] = YamlPair.make({
132
+ key: oldPair.key,
133
+ value: newValueNode,
134
+ ...definedFields({ comment: oldPair.comment })
135
+ });
136
+ return rebuildMap(node, newItems);
137
+ }
138
+ const keyNode = YamlScalar.make({
139
+ value: String(segment),
140
+ style: "plain",
141
+ offset: 0,
142
+ length: 0
143
+ });
144
+ const newPair = YamlPair.make({
145
+ key: keyNode,
146
+ value: newValueNode
147
+ });
148
+ return rebuildMap(node, [...node.items, newPair]);
149
+ }
150
+ if (pairIndex < 0) throw new ModifyFailure("PathNotFound", `Key "${String(segment)}" not found in mapping`, node.offset, node.length);
151
+ const pair = node.items[pairIndex];
152
+ if (pair.value === null) throw new ModifyFailure("PathNotFound", `Value at key "${String(segment)}" is null`, node.offset, node.length);
153
+ const newValue = modifyNode(pair.value, path, depth + 1, value);
154
+ const newItems = [...node.items];
155
+ newItems[pairIndex] = YamlPair.make({
156
+ key: pair.key,
157
+ value: newValue,
158
+ ...definedFields({ comment: pair.comment })
159
+ });
160
+ return rebuildMap(node, newItems);
161
+ }
162
+ if (node instanceof YamlSeq) {
163
+ const idx = typeof segment === "number" ? segment : Number(segment);
164
+ if (Number.isNaN(idx) || idx < 0) throw new ModifyFailure("InvalidIndex", `Invalid sequence index: ${String(segment)}`, node.offset, node.length);
165
+ if (isLast) {
166
+ const newItems = [...node.items];
167
+ if (value === void 0) {
168
+ if (idx < newItems.length) newItems.splice(idx, 1);
169
+ } else if (idx < newItems.length) newItems[idx] = jsValueToNode(value);
170
+ else newItems.push(jsValueToNode(value));
171
+ return rebuildSeq(node, newItems);
172
+ }
173
+ if (idx >= node.items.length) throw new ModifyFailure("InvalidIndex", `Index ${idx} out of bounds`, node.offset, node.length);
174
+ const child = node.items[idx];
175
+ const newChild = modifyNode(child, path, depth + 1, value);
176
+ const newItems = [...node.items];
177
+ newItems[idx] = newChild;
178
+ return rebuildSeq(node, newItems);
179
+ }
180
+ throw new ModifyFailure("NotNavigable", `Cannot navigate through ${node._tag} at segment "${String(segment)}"`, node.offset, node.length);
181
+ }
182
+ function rebuildMap(node, items) {
183
+ return YamlMap.make({
184
+ items,
185
+ style: node.style,
186
+ ...definedFields({
187
+ tag: node.tag,
188
+ anchor: node.anchor,
189
+ comment: node.comment,
190
+ sourceMultiline: node.sourceMultiline
191
+ }),
192
+ offset: node.offset,
193
+ length: node.length
194
+ });
195
+ }
196
+ function rebuildSeq(node, items) {
197
+ return YamlSeq.make({
198
+ items,
199
+ style: node.style,
200
+ ...definedFields({
201
+ tag: node.tag,
202
+ anchor: node.anchor,
203
+ comment: node.comment,
204
+ sourceMultiline: node.sourceMultiline
205
+ }),
206
+ offset: node.offset,
207
+ length: node.length
208
+ });
209
+ }
210
+ /**
211
+ * Formatting and modification statics. Not instantiable.
212
+ *
213
+ * @remarks
214
+ * `format`/`formatToString` are pure and total (edit computation never fails
215
+ * — malformed input yields no edits rather than corrupting the document).
216
+ * `modify`/`modifyToString` carry a real error channel: navigation failures
217
+ * against the composed AST raise {@link YamlModificationError}, which — per
218
+ * the structure-preserving-errors house rule — carries
219
+ * `diagnostics: ReadonlyArray<YamlDiagnostic>`, never a collapsed `reason`
220
+ * string.
221
+ *
222
+ * @public
223
+ */
224
+ var YamlFormat = class YamlFormat {
225
+ constructor() {}
226
+ /**
227
+ * Compute formatting edits for a YAML document. Non-mutating — apply the
228
+ * result with `YamlEdit.applyAll` (or use {@link YamlFormat.formatToString}).
229
+ * Pure and total: malformed input (a fatal parse error) yields `[]` rather
230
+ * than corrupting the document.
231
+ *
232
+ * @remarks
233
+ * The positional `range` argument takes precedence over
234
+ * `options?.range` when both are given; either accepts a plain
235
+ * `{ offset, length }` object as well as a {@link YamlRange} instance, so
236
+ * callers do not need `YamlRange.make(...)` for the common case.
237
+ */
238
+ static format(text, range, options) {
239
+ const formatted = formatDocument(text, options);
240
+ if (formatted === void 0) return [];
241
+ let edits = computeEdits(text, formatted);
242
+ const effectiveRange = resolveRange(range, options?.range);
243
+ if (effectiveRange !== void 0) {
244
+ const rangeStart = effectiveRange.offset;
245
+ const rangeEnd = effectiveRange.offset + effectiveRange.length;
246
+ edits = edits.filter((e) => e.offset >= rangeStart && e.offset + e.length <= rangeEnd);
247
+ }
248
+ return edits.map((e) => YamlEdit.make(e));
249
+ }
250
+ /**
251
+ * Format `text` and apply the resulting edits in one step
252
+ * (`YamlEdit.applyAll ∘ format`). Pure and total.
253
+ */
254
+ static formatToString(text, range, options) {
255
+ return YamlEdit.applyAll(text, YamlFormat.format(text, range, options));
256
+ }
257
+ /**
258
+ * Compute the edits that insert, replace, or remove a value at `path`.
259
+ * Passing `value === undefined` removes the target key/element; a missing
260
+ * insertion target appends after the last pair/element. Only
261
+ * scalar-compatible values are supported (matching v3 — arbitrary object
262
+ * graphs are not recursively lowered into AST nodes). Fails with
263
+ * {@link YamlModificationError} on a fatal parse error or a structural
264
+ * navigation mismatch.
265
+ *
266
+ * @remarks
267
+ * `options` is a bare {@link YamlStringifyOptions} — it controls only the
268
+ * internal re-stringify step, not a range (there is no range to restrict
269
+ * for a path-targeted modification).
270
+ */
271
+ static modify = Effect.fn("YamlFormat.modify")(function* (text, path, value, options) {
272
+ const doc = composeFirstDocument(text, {});
273
+ const fatal = doc.errors.filter((e) => isFatalCode(e.code));
274
+ if (fatal.length > 0) return yield* new YamlModificationError({
275
+ path,
276
+ diagnostics: fatal.map((e) => YamlDiagnostic.fromRaw(e, text))
277
+ });
278
+ let newContents;
279
+ try {
280
+ newContents = modifyDocument(doc, path, value);
281
+ } catch (err) {
282
+ if (!(err instanceof ModifyFailure)) throw err;
283
+ return yield* new YamlModificationError({
284
+ path,
285
+ diagnostics: [YamlDiagnostic.fromRaw({
286
+ code: err.code,
287
+ message: err.message,
288
+ offset: err.offset,
289
+ length: err.length
290
+ }, text)]
291
+ });
292
+ }
293
+ return computeEdits(text, stringifyDocument({
294
+ ...doc,
295
+ contents: newContents
296
+ }, toStringifyInput(options))).map((e) => YamlEdit.make(e));
297
+ });
298
+ /**
299
+ * Modify `text` and apply the resulting edits in one step
300
+ * (`YamlEdit.applyAll ∘ modify`).
301
+ */
302
+ static modifyToString = Effect.fn("YamlFormat.modifyToString")(function* (text, path, value, options) {
303
+ const edits = yield* YamlFormat.modify(text, path, value, options);
304
+ return YamlEdit.applyAll(text, edits);
305
+ });
306
+ };
307
+
308
+ //#endregion
309
+ export { YamlFormat, YamlFormattingOptions, YamlModificationError };