@effected/yaml 0.11.0 → 0.12.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/README.md CHANGED
@@ -193,10 +193,29 @@ The `requoteScalars: true` half of the `singleQuote` row is what buys full parit
193
193
 
194
194
  Multi-document streams — a Kubernetes manifest, or the two-document `pnpm-lock.yaml` pnpm 11 writes under `configDependencies` — format whole: every document is re-emitted in order with its own `---`/`...` framing and comments, so no document is ever dropped. Document detection is CST-level, so a `---` inside a block scalar or quoted string is content and formats normally. The formatter leaves input byte-identical rather than corrupting it in exactly two cases: a fatal parse error in any document, and a stream carrying `%YAML`/`%TAG` directives (which the emitter cannot re-emit faithfully). Validate a whole stream with `Yaml.parseAllResult`, which fails typed when any document carries a fatal diagnostic; `YamlFormat.modify` stays single-document, since a path names no particular document of a stream.
195
195
 
196
+ ## Emitting for a YAML 1.1 consumer
197
+
198
+ YAML 1.2's Core Schema resolves fewer plain scalars to non-strings than YAML 1.1 does. A plain `on` or `yes` round-trips as a string under this package's own parser but becomes a boolean the moment a YAML 1.1 consumer — js-yaml, PyYAML, libyaml, the `yaml` npm package's YAML 1.1 schema, most CI systems' native YAML support — reads it back: the "Norway problem". `quoteCompat: "yaml-1.1"` closes that gap on the way out, quoting every plain scalar a 1.1 resolver would re-type: the extended booleans (`y`/`yes`/`no`/`on`/`off` and case variants), 1.1 timestamps, sexagesimal numbers (`1:30`), underscore-grouped numbers (`1_000`) and the octal/hex/binary integer forms (`0777`, `0x_FF`, `0b1010_0111`). It is strictly additive — nothing the 1.2 rules already quote loses a quote, and no string outside that list gains one — and composes with `quoteStyle` for the quote character and `lineWidth` for folding:
199
+
200
+ ```ts
201
+ import { Yaml, YamlStringifyOptions } from "@effected/yaml";
202
+ import { Effect } from "effect";
203
+
204
+ const frontmatter = { node: "on", released: "2024-01-15", port: "yes" };
205
+ const options = YamlStringifyOptions.make({ lineWidth: 0, quoteCompat: "yaml-1.1", quoteStyle: "double" });
206
+
207
+ Effect.runPromise(Yaml.stringify(frontmatter, options)).then(console.log);
208
+ // node: "on"
209
+ // released: "2024-01-15"
210
+ // port: "yes"
211
+ ```
212
+
213
+ That combination — `lineWidth: 0` (no folding), `quoteCompat: "yaml-1.1"`, `quoteStyle: "double"` — is the shape to reach for when stringifying frontmatter destined for YAML-1.1 tooling: Markdown frontmatter parsers and most static-site generators still resolve on the older rules. The option applies on both the value path (`Yaml.stringify`, `Yaml.stringifyResult`) and the node path (`YamlDocument#stringify`, `YamlFormat`), and scalars carrying an explicit tag are exempt, exactly like the 1.2 type-conflict check it extends.
214
+
196
215
  ## Features
197
216
 
198
217
  - `Yaml.parse` / `Yaml.parseAll` — error-recovery parsing of a single document or a `---`-separated stream into plain values, resolving anchors and aliases and aggregating every diagnostic into one `YamlParseError`.
199
- - `Yaml.stringify` — serialize a plain value back to YAML, failing typed with `YamlStringifyError` on circular references or on excessively deep nesting; a block-mapping key too long to render on one line spills into explicit-key form (`? key` / `: value`) so strict parsers still accept the output.
218
+ - `Yaml.stringify` — serialize a plain value back to YAML, failing typed with `YamlStringifyError` on circular references or on excessively deep nesting; a block-mapping key too long to render on one line spills into explicit-key form (`? key` / `: value`) so strict parsers still accept the output; `quoteCompat: "yaml-1.1"` additionally quotes plain scalars a YAML 1.1 resolver would re-type.
200
219
  - `Yaml.parseResult` / `Yaml.parseAllResult` / `Yaml.stringifyResult` — the pure synchronous counterparts, returning a `Result` instead of an `Effect` for config-time callers that cannot await; each runs the same engine call as its `Effect` variant, so the two forms cannot diverge, and a fatal diagnostic, a duplicate key, an alias bomb or a circular reference still fails typed rather than throwing. `parseAllResult` doubles as a whole-stream validity check: it fails when any document in the stream is invalid.
201
220
  - `Yaml.stripComments` — quote-aware comment removal that keeps line numbers stable, or every byte offset stable when given a replacement character.
202
221
  - `Yaml.equals` / `Yaml.equalsValue` — semantic equality that ignores comments, whitespace, formatting and mapping key order while keeping sequence order significant.
package/Yaml.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AliasExpansionBudgetExceeded, CollectionStyle, QuoteStyle, ScalarStyle, nodeToJsValue } from "./YamlNode.js";
1
+ import { AliasExpansionBudgetExceeded, CollectionStyle, QuoteCompat, QuoteStyle, ScalarStyle, nodeToJsValue } from "./YamlNode.js";
2
2
  import { composeAllDocuments, composeFirstDocument } from "./internal/composer/document.js";
3
3
  import { isFatalCode } from "./internal/diagnostics.js";
4
4
  import { StringifyDepthExceeded, StringifyFailure, stringifyValue } from "./internal/stringifier.js";
@@ -35,8 +35,9 @@ var YamlParseOptions = class extends Schema.Class("YamlParseOptions")({
35
35
  * Options controlling stringify behavior. All fields are omissible; absent
36
36
  * fields resolve to `indent` `2`, `lineWidth` `0`, `defaultScalarStyle`
37
37
  * `"plain"`, `defaultCollectionStyle` `"block"`, `sortKeys` `false`,
38
- * `indentSequences` `false`, `quoteStyle` `"single"`, `finalNewline` `true`
39
- * and `forceDefaultStyles` `false`.
38
+ * `indentSequences` `false`, `quoteStyle` `"single"`, `quoteCompat` absent
39
+ * (no dialect-compat quoting), `finalNewline` `true` and `forceDefaultStyles`
40
+ * `false`.
40
41
  *
41
42
  * `lineWidth` controls column-based scalar folding. The default `0` (and any
42
43
  * value `<= 0`) never wraps, emitting byte-identical output to the historic
@@ -114,6 +115,33 @@ var YamlStringifyOptions = class extends Schema.Class("YamlStringifyOptions")({
114
115
  * `"double-quoted"` is unaffected.
115
116
  */
116
117
  quoteStyle: Schema.optionalKey(QuoteStyle),
118
+ /**
119
+ * Additionally quote plain scalars a foreign resolution dialect would
120
+ * coerce to a non-string. Absent (the default) adds no quoting beyond the
121
+ * YAML 1.2 Core Schema rules — byte-identical to the released output.
122
+ *
123
+ * `"yaml-1.1"` quotes every plain scalar a YAML 1.1 parser (js-yaml,
124
+ * PyYAML, libyaml, and the `yaml` npm package's YAML 1.1 schema, whose
125
+ * lenient resolvers set the outer bound) would implicitly resolve to a
126
+ * non-string: the extended
127
+ * boolean spellings (`y`/`yes`/`on`/`off` and case variants — the "Norway
128
+ * problem"), timestamps (`2024-01-15`, `2001-12-15T02:59:43.1Z`, the
129
+ * space-separated 1.1 forms), sexagesimal numbers (`1:30`,
130
+ * `190:20:30.15`), underscore-separated numbers (`1_000`) and the
131
+ * base-2/8/16 integer forms (`0b1010_0111`, `0777`, `0x_FF`). Use it when
132
+ * emitted output is parsed downstream by a YAML 1.1 consumer and blanket
133
+ * `defaultScalarStyle` quoting is too noisy.
134
+ *
135
+ * Strictly additive: it never un-quotes anything the 1.2 rules require
136
+ * quoted, strings no 1.1 parser coerces stay plain, and the quote
137
+ * character stays governed by `quoteStyle`. Scalars carrying an explicit
138
+ * tag are exempt, exactly like the 1.2 type-conflict check. Applies
139
+ * wherever the plain fallback renders — values, mapping keys, flow items —
140
+ * on both the value path ({@link Yaml.stringify},
141
+ * {@link Yaml.stringifyResult}) and the node path (`YamlDocument#stringify`
142
+ * and the `YamlFormat` helpers).
143
+ */
144
+ quoteCompat: Schema.optionalKey(QuoteCompat),
117
145
  finalNewline: Schema.optionalKey(Schema.Boolean),
118
146
  forceDefaultStyles: Schema.optionalKey(Schema.Boolean)
119
147
  }) {};
@@ -167,6 +195,7 @@ const toStringifyInput = (options) => options === void 0 ? {} : {
167
195
  sortKeys: options.sortKeys,
168
196
  indentSequences: options.indentSequences,
169
197
  quoteStyle: options.quoteStyle,
198
+ quoteCompat: options.quoteCompat,
170
199
  finalNewline: options.finalNewline,
171
200
  forceDefaultStyles: options.forceDefaultStyles
172
201
  };
package/YamlDocument.js CHANGED
@@ -163,6 +163,8 @@ const toStringifyInput = (options) => options === void 0 ? {} : {
163
163
  defaultCollectionStyle: options.defaultCollectionStyle,
164
164
  sortKeys: options.sortKeys,
165
165
  indentSequences: options.indentSequences,
166
+ quoteStyle: options.quoteStyle,
167
+ quoteCompat: options.quoteCompat,
166
168
  finalNewline: options.finalNewline,
167
169
  forceDefaultStyles: options.forceDefaultStyles
168
170
  };
package/YamlFormat.js CHANGED
@@ -12,8 +12,8 @@ import { Effect, Schema } from "effect";
12
12
  //#region src/YamlFormat.ts
13
13
  /**
14
14
  * Options controlling formatting behavior: every {@link YamlStringifyOptions}
15
- * field (derived, not hand-duplicated — including `indentSequences` and
16
- * `quoteStyle`) plus
15
+ * field (derived, not hand-duplicated — including `indentSequences`,
16
+ * `quoteStyle` and `quoteCompat`) plus
17
17
  * `preserveComments` (default `true`), `range` (restrict edits to a
18
18
  * region; see the module-level remarks on the `range` parameter vs. this
19
19
  * field) and `requoteScalars` (default `false`).
@@ -105,6 +105,7 @@ const toStringifyInput = (options) => options === void 0 ? {} : {
105
105
  sortKeys: options.sortKeys,
106
106
  indentSequences: options.indentSequences,
107
107
  quoteStyle: options.quoteStyle,
108
+ quoteCompat: options.quoteCompat,
108
109
  finalNewline: options.finalNewline,
109
110
  forceDefaultStyles: options.forceDefaultStyles
110
111
  };
package/YamlNode.js CHANGED
@@ -30,6 +30,21 @@ const CollectionStyle = Schema.Literals(["block", "flow"]);
30
30
  */
31
31
  const QuoteStyle = Schema.Literals(["single", "double"]);
32
32
  /**
33
+ * Foreign resolution dialects the stringifier's plain-scalar fallback can
34
+ * defend against: setting the `quoteCompat` field of `YamlStringifyOptions`
35
+ * to `"yaml-1.1"` additionally quotes every plain scalar a YAML 1.1 parser
36
+ * (js-yaml, PyYAML, libyaml, and the `yaml` npm package's YAML 1.1 schema,
37
+ * whose lenient resolvers set the outer bound) would implicitly resolve to a
38
+ * non-string —
39
+ * `yes`/`no`/`on`/`off` booleans, ISO 8601 and space-separated timestamps,
40
+ * sexagesimal `1:30`, underscored `1_000` and base-2/8/16 numbers. Like
41
+ * `QuoteStyle` it is a stringify-option vocabulary, never a property of a
42
+ * composed node.
43
+ *
44
+ * @public
45
+ */
46
+ const QuoteCompat = Schema.Literals(["yaml-1.1"]);
47
+ /**
33
48
  * Block-scalar chomping indicators (`-` strip, default clip, `+` keep).
34
49
  * Referenced by the {@link YamlScalar} `chomp` field schema.
35
50
  *
@@ -442,4 +457,4 @@ function nodeToValue(node, anchors, budget, counting = false) {
442
457
  }
443
458
 
444
459
  //#endregion
445
- export { AliasExpansionBudgetExceeded, CollectionStyle, QuoteStyle, ScalarChomp, ScalarStyle, YamlAlias, YamlMap, YamlNode, YamlPair, YamlScalar, YamlSeq, aliasExpansionLimit, nodeToJsValue };
460
+ export { AliasExpansionBudgetExceeded, CollectionStyle, QuoteCompat, QuoteStyle, ScalarChomp, ScalarStyle, YamlAlias, YamlMap, YamlNode, YamlPair, YamlScalar, YamlSeq, aliasExpansionLimit, nodeToJsValue };
package/index.d.ts CHANGED
@@ -175,6 +175,33 @@ declare const YamlStringifyOptions_base: Schema.Class<YamlStringifyOptions, Sche
175
175
  * `"double-quoted"` is unaffected.
176
176
  */
177
177
  readonly quoteStyle: Schema.optionalKey<Schema.Literals<readonly ["single", "double"]>>;
178
+ /**
179
+ * Additionally quote plain scalars a foreign resolution dialect would
180
+ * coerce to a non-string. Absent (the default) adds no quoting beyond the
181
+ * YAML 1.2 Core Schema rules — byte-identical to the released output.
182
+ *
183
+ * `"yaml-1.1"` quotes every plain scalar a YAML 1.1 parser (js-yaml,
184
+ * PyYAML, libyaml, and the `yaml` npm package's YAML 1.1 schema, whose
185
+ * lenient resolvers set the outer bound) would implicitly resolve to a
186
+ * non-string: the extended
187
+ * boolean spellings (`y`/`yes`/`on`/`off` and case variants — the "Norway
188
+ * problem"), timestamps (`2024-01-15`, `2001-12-15T02:59:43.1Z`, the
189
+ * space-separated 1.1 forms), sexagesimal numbers (`1:30`,
190
+ * `190:20:30.15`), underscore-separated numbers (`1_000`) and the
191
+ * base-2/8/16 integer forms (`0b1010_0111`, `0777`, `0x_FF`). Use it when
192
+ * emitted output is parsed downstream by a YAML 1.1 consumer and blanket
193
+ * `defaultScalarStyle` quoting is too noisy.
194
+ *
195
+ * Strictly additive: it never un-quotes anything the 1.2 rules require
196
+ * quoted, strings no 1.1 parser coerces stay plain, and the quote
197
+ * character stays governed by `quoteStyle`. Scalars carrying an explicit
198
+ * tag are exempt, exactly like the 1.2 type-conflict check. Applies
199
+ * wherever the plain fallback renders — values, mapping keys, flow items —
200
+ * on both the value path ({@link Yaml.stringify},
201
+ * {@link Yaml.stringifyResult}) and the node path (`YamlDocument#stringify`
202
+ * and the `YamlFormat` helpers).
203
+ */
204
+ readonly quoteCompat: Schema.optionalKey<Schema.Literals<readonly ["yaml-1.1"]>>;
178
205
  readonly finalNewline: Schema.optionalKey<Schema.Boolean>;
179
206
  readonly forceDefaultStyles: Schema.optionalKey<Schema.Boolean>;
180
207
  }>, {}>;
@@ -182,8 +209,9 @@ declare const YamlStringifyOptions_base: Schema.Class<YamlStringifyOptions, Sche
182
209
  * Options controlling stringify behavior. All fields are omissible; absent
183
210
  * fields resolve to `indent` `2`, `lineWidth` `0`, `defaultScalarStyle`
184
211
  * `"plain"`, `defaultCollectionStyle` `"block"`, `sortKeys` `false`,
185
- * `indentSequences` `false`, `quoteStyle` `"single"`, `finalNewline` `true`
186
- * and `forceDefaultStyles` `false`.
212
+ * `indentSequences` `false`, `quoteStyle` `"single"`, `quoteCompat` absent
213
+ * (no dialect-compat quoting), `finalNewline` `true` and `forceDefaultStyles`
214
+ * `false`.
187
215
  *
188
216
  * `lineWidth` controls column-based scalar folding. The default `0` (and any
189
217
  * value `<= 0`) never wraps, emitting byte-identical output to the historic
@@ -641,6 +669,27 @@ declare const QuoteStyle: Schema.Literals<readonly ["single", "double"]>;
641
669
  * @public
642
670
  */
643
671
  type QuoteStyle = typeof QuoteStyle.Type;
672
+ /**
673
+ * Foreign resolution dialects the stringifier's plain-scalar fallback can
674
+ * defend against: setting the `quoteCompat` field of `YamlStringifyOptions`
675
+ * to `"yaml-1.1"` additionally quotes every plain scalar a YAML 1.1 parser
676
+ * (js-yaml, PyYAML, libyaml, and the `yaml` npm package's YAML 1.1 schema,
677
+ * whose lenient resolvers set the outer bound) would implicitly resolve to a
678
+ * non-string —
679
+ * `yes`/`no`/`on`/`off` booleans, ISO 8601 and space-separated timestamps,
680
+ * sexagesimal `1:30`, underscored `1_000` and base-2/8/16 numbers. Like
681
+ * `QuoteStyle` it is a stringify-option vocabulary, never a property of a
682
+ * composed node.
683
+ *
684
+ * @public
685
+ */
686
+ declare const QuoteCompat: Schema.Literals<readonly ["yaml-1.1"]>;
687
+ /**
688
+ * The union of all quote-compat dialect string literals.
689
+ *
690
+ * @public
691
+ */
692
+ type QuoteCompat = typeof QuoteCompat.Type;
644
693
  /**
645
694
  * Block-scalar chomping indicators (`-` strip, default clip, `+` keep).
646
695
  * Referenced by the {@link YamlScalar} `chomp` field schema.
@@ -1005,6 +1054,7 @@ declare const YamlFormattingOptions_base: Schema.Class<YamlFormattingOptions, Sc
1005
1054
  readonly sortKeys: Schema.optionalKey<Schema.Boolean>;
1006
1055
  readonly indentSequences: Schema.optionalKey<Schema.Boolean>;
1007
1056
  readonly quoteStyle: Schema.optionalKey<Schema.Literals<readonly ["single", "double"]>>;
1057
+ readonly quoteCompat: Schema.optionalKey<Schema.Literals<readonly ["yaml-1.1"]>>;
1008
1058
  readonly finalNewline: Schema.optionalKey<Schema.Boolean>;
1009
1059
  readonly forceDefaultStyles: Schema.optionalKey<Schema.Boolean>;
1010
1060
  readonly preserveComments: Schema.optionalKey<Schema.Boolean>;
@@ -1013,8 +1063,8 @@ declare const YamlFormattingOptions_base: Schema.Class<YamlFormattingOptions, Sc
1013
1063
  }>, {}>;
1014
1064
  /**
1015
1065
  * Options controlling formatting behavior: every {@link YamlStringifyOptions}
1016
- * field (derived, not hand-duplicated — including `indentSequences` and
1017
- * `quoteStyle`) plus
1066
+ * field (derived, not hand-duplicated — including `indentSequences`,
1067
+ * `quoteStyle` and `quoteCompat`) plus
1018
1068
  * `preserveComments` (default `true`), `range` (restrict edits to a
1019
1069
  * region; see the module-level remarks on the `range` parameter vs. this
1020
1070
  * field) and `requoteScalars` (default `false`).
@@ -2294,5 +2344,5 @@ declare class YamlVisitor {
2294
2344
  static visit(text: string, options?: YamlParseOptions): Stream.Stream<YamlVisitorEvent>;
2295
2345
  }
2296
2346
  //#endregion
2297
- export { CollectionStyle, type LintContext, type LintLine, QuoteStyle, ScalarChomp, ScalarStyle, StyleConflict, StyleEvidence, StyleFloor, StyleFloorTally, type StyleObservation, StyleVote, StyleVoteTally, Yaml, YamlAlias, type YamlAliasEncoded, type YamlBoundCodec, YamlComposerErrorCode, YamlDiagnostic, YamlDirective, YamlDocument, YamlEdit, YamlErrorCode, YamlFormat, YamlFormattingOptions, YamlLexErrorCode, YamlLint, YamlLintConfig, YamlLintDiagnostic, type YamlLintInference, YamlLintRuleSetting, YamlLintSeverity, YamlMap, type YamlMapEncoded, YamlModificationError, YamlModifyErrorCode, YamlNode, YamlPair, YamlParseError, YamlParseErrorCode, YamlParseOptions, type YamlPath, YamlRange, type YamlRangeLike, type YamlRule, YamlScalar, type YamlScalarEncoded, type YamlSegment, YamlSeq, type YamlSeqEncoded, YamlStringifyError, YamlStringifyErrorCode, YamlStringifyOptions, YamlStyleConflictError, YamlToken, YamlTokenKind, YamlTokens, YamlVisitor, YamlVisitorEvent };
2347
+ export { CollectionStyle, type LintContext, type LintLine, QuoteCompat, QuoteStyle, ScalarChomp, ScalarStyle, StyleConflict, StyleEvidence, StyleFloor, StyleFloorTally, type StyleObservation, StyleVote, StyleVoteTally, Yaml, YamlAlias, type YamlAliasEncoded, type YamlBoundCodec, YamlComposerErrorCode, YamlDiagnostic, YamlDirective, YamlDocument, YamlEdit, YamlErrorCode, YamlFormat, YamlFormattingOptions, YamlLexErrorCode, YamlLint, YamlLintConfig, YamlLintDiagnostic, type YamlLintInference, YamlLintRuleSetting, YamlLintSeverity, YamlMap, type YamlMapEncoded, YamlModificationError, YamlModifyErrorCode, YamlNode, YamlPair, YamlParseError, YamlParseErrorCode, YamlParseOptions, type YamlPath, YamlRange, type YamlRangeLike, type YamlRule, YamlScalar, type YamlScalarEncoded, type YamlSegment, YamlSeq, type YamlSeqEncoded, YamlStringifyError, YamlStringifyErrorCode, YamlStringifyOptions, YamlStyleConflictError, YamlToken, YamlTokenKind, YamlTokens, YamlVisitor, YamlVisitorEvent };
2298
2348
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { CollectionStyle, QuoteStyle, ScalarChomp, ScalarStyle, YamlAlias, YamlMap, YamlNode, YamlPair, YamlScalar, YamlSeq } from "./YamlNode.js";
1
+ import { CollectionStyle, QuoteCompat, QuoteStyle, ScalarChomp, ScalarStyle, YamlAlias, YamlMap, YamlNode, YamlPair, YamlScalar, YamlSeq } from "./YamlNode.js";
2
2
  import { YamlComposerErrorCode, YamlDiagnostic, YamlErrorCode, YamlLexErrorCode, YamlModifyErrorCode, YamlParseErrorCode, YamlStringifyErrorCode } from "./YamlDiagnostic.js";
3
3
  import { Yaml, YamlParseError, YamlParseOptions, YamlStringifyError, YamlStringifyOptions } from "./Yaml.js";
4
4
  import { YamlDirective, YamlDocument } from "./YamlDocument.js";
@@ -9,4 +9,4 @@ import { YamlToken, YamlTokenKind, YamlTokens } from "./YamlToken.js";
9
9
  import { StyleConflict, StyleEvidence, StyleFloorTally, StyleVoteTally, YamlLint, YamlLintConfig, YamlLintRuleSetting, YamlStyleConflictError } from "./YamlLint.js";
10
10
  import { YamlVisitor, YamlVisitorEvent } from "./YamlVisitor.js";
11
11
 
12
- export { CollectionStyle, QuoteStyle, ScalarChomp, ScalarStyle, StyleConflict, StyleEvidence, StyleFloor, StyleFloorTally, StyleVote, StyleVoteTally, Yaml, YamlAlias, YamlComposerErrorCode, YamlDiagnostic, YamlDirective, YamlDocument, YamlEdit, YamlErrorCode, YamlFormat, YamlFormattingOptions, YamlLexErrorCode, YamlLint, YamlLintConfig, YamlLintDiagnostic, YamlLintRuleSetting, YamlLintSeverity, YamlMap, YamlModificationError, YamlModifyErrorCode, YamlNode, YamlPair, YamlParseError, YamlParseErrorCode, YamlParseOptions, YamlRange, YamlScalar, YamlSeq, YamlStringifyError, YamlStringifyErrorCode, YamlStringifyOptions, YamlStyleConflictError, YamlToken, YamlTokenKind, YamlTokens, YamlVisitor, YamlVisitorEvent };
12
+ export { CollectionStyle, QuoteCompat, QuoteStyle, ScalarChomp, ScalarStyle, StyleConflict, StyleEvidence, StyleFloor, StyleFloorTally, StyleVote, StyleVoteTally, Yaml, YamlAlias, YamlComposerErrorCode, YamlDiagnostic, YamlDirective, YamlDocument, YamlEdit, YamlErrorCode, YamlFormat, YamlFormattingOptions, YamlLexErrorCode, YamlLint, YamlLintConfig, YamlLintDiagnostic, YamlLintRuleSetting, YamlLintSeverity, YamlMap, YamlModificationError, YamlModifyErrorCode, YamlNode, YamlPair, YamlParseError, YamlParseErrorCode, YamlParseOptions, YamlRange, YamlScalar, YamlSeq, YamlStringifyError, YamlStringifyErrorCode, YamlStringifyOptions, YamlStyleConflictError, YamlToken, YamlTokenKind, YamlTokens, YamlVisitor, YamlVisitorEvent };
@@ -105,6 +105,23 @@ function wouldBeResolved(s) {
105
105
  if (FLOAT_RE.test(s)) return true;
106
106
  return false;
107
107
  }
108
+ const BOOL_11_RE = /^(?:y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF)$/;
109
+ const INT_11_RE = /^[-+]?(?:0b[0-1_]+|0o?[0-7_]+|[0-9][0-9_]*|0x[0-9a-fA-F_]+|[1-9][0-9_]*(?::[0-5]?[0-9])+)$/;
110
+ const FLOAT_11_RE = /^[-+]?(?:[0-9][0-9_]*(?:\.[0-9_]*(?:[eE][-+]?[0-9]+)?|[eE][-+]?[0-9]+)|\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*)$/;
111
+ const TIMESTAMP_11_RE = /^[0-9][0-9][0-9][0-9]-[0-9][0-9]?-[0-9][0-9]?(?:(?:[Tt]|[ \t]+)[0-9][0-9]?:[0-9][0-9]:[0-9][0-9](?:\.[0-9]*)?(?:[ \t]*(?:Z|[-+][0-9][0-9]?(?::?[0-9][0-9])?))?)?$/;
112
+ /**
113
+ * Returns true if a string value would be resolved as a non-string type by a
114
+ * YAML 1.1 parser. The delta over {@link wouldBeResolved}: null spellings are
115
+ * identical in both editions (and already covered), so only the boolean,
116
+ * integer, float and timestamp families are tested here.
117
+ */
118
+ function wouldBeResolved11(s) {
119
+ if (BOOL_11_RE.test(s)) return true;
120
+ if (INT_11_RE.test(s)) return true;
121
+ if (FLOAT_11_RE.test(s)) return true;
122
+ if (TIMESTAMP_11_RE.test(s)) return true;
123
+ return false;
124
+ }
108
125
  /**
109
126
  * Returns true if a string requires quoting to be safely represented as a plain scalar.
110
127
  *
@@ -112,11 +129,16 @@ function wouldBeResolved(s) {
112
129
  * embedded newlines, leading indicator characters or whitespace, and inline
113
130
  * comment/mapping-value patterns (`: `, ` #`). This is the single gate that
114
131
  * decides whether a plain scalar is safe or must be wrapped in quotes.
132
+ *
133
+ * `quoteCompat` is strictly additive: `"yaml-1.1"` additionally quotes
134
+ * strings a YAML 1.1 parser would coerce ({@link wouldBeResolved11}) and can
135
+ * never un-quote anything the 1.2 rules require quoted.
115
136
  */
116
- function requiresQuoting(s, ignoreType = false) {
137
+ function requiresQuoting(s, ignoreType = false, quoteCompat) {
117
138
  if (s === "") return true;
118
139
  if (s.includes("\n")) return true;
119
140
  if (!ignoreType && wouldBeResolved(s)) return true;
141
+ if (!ignoreType && quoteCompat === "yaml-1.1" && wouldBeResolved11(s)) return true;
120
142
  const first = s[0];
121
143
  if (first === " " || first === " ") return true;
122
144
  if (first !== void 0 && INDICATOR_CHARS.has(first)) {
@@ -197,7 +219,7 @@ function renderSingleQuoted(s) {
197
219
  * Block literal and block folded styles are always accepted for single-line
198
220
  * strings even though the output is unusual.
199
221
  */
200
- function renderString(s, style, indent, ignoreType = false, canonical = false, explicitChomp, parentPosition, quoteStyle = "single", explicitIndent) {
222
+ function renderString(s, style, indent, ignoreType = false, canonical = false, explicitChomp, parentPosition, quoteStyle = "single", explicitIndent, quoteCompat) {
201
223
  const fidelity = !canonical;
202
224
  const fidelityIndent = fidelity ? explicitIndent : void 0;
203
225
  if (s.includes("\n")) {
@@ -230,7 +252,7 @@ function renderString(s, style, indent, ignoreType = false, canonical = false, e
230
252
  if (s === "" && (style === "block-literal" || style === "block-folded")) return renderDoubleQuoted(s, canonical);
231
253
  switch (style) {
232
254
  case "plain":
233
- if (requiresQuoting(s, ignoreType)) {
255
+ if (requiresQuoting(s, ignoreType, quoteCompat)) {
234
256
  if (s.includes(" ") || s.includes("\r")) return renderDoubleQuoted(s, canonical);
235
257
  for (let i = 0; i < s.length; i++) if (isControlChar(s.charCodeAt(i))) return renderDoubleQuoted(s, canonical);
236
258
  return quoteStyle === "double" ? renderDoubleQuoted(s, canonical) : renderSingleQuoted(s);
@@ -289,6 +311,7 @@ function createContext(options) {
289
311
  sortKeys: options?.sortKeys ?? false,
290
312
  indentSequences: options?.indentSequences ?? false,
291
313
  quoteStyle: options?.quoteStyle ?? "single",
314
+ quoteCompat: options?.quoteCompat,
292
315
  forceDefaultStyles: options?.forceDefaultStyles ?? false,
293
316
  seen: /* @__PURE__ */ new Set()
294
317
  };
@@ -308,7 +331,7 @@ function stringifyLines(value, ctx, depth, allowFold = true) {
308
331
  if (typeof value === "bigint") return [value.toString()];
309
332
  if (typeof value === "string") {
310
333
  const indentStr = " ".repeat(ctx.indent);
311
- const rendered = renderString(value, ctx.defaultScalarStyle, indentStr, false, ctx.forceDefaultStyles, void 0, void 0, ctx.quoteStyle);
334
+ const rendered = renderString(value, ctx.defaultScalarStyle, indentStr, false, ctx.forceDefaultStyles, void 0, void 0, ctx.quoteStyle, void 0, ctx.quoteCompat);
312
335
  return (allowFold && ctx.lineWidth > 0 ? foldRenderedScalar(rendered, indentStr, ctx.lineWidth) : rendered).split("\n");
313
336
  }
314
337
  if (Array.isArray(value)) {
@@ -373,7 +396,7 @@ function stringifyObjectLines(obj, ctx, depth) {
373
396
  const keys = Object.keys(obj);
374
397
  if (keys.length === 0) return ["{}"];
375
398
  if (ctx.sortKeys) keys.sort();
376
- const renderPlainKey = (k) => renderString(k, "plain", "", false, false, void 0, void 0, ctx.quoteStyle);
399
+ const renderPlainKey = (k) => renderString(k, "plain", "", false, false, void 0, void 0, ctx.quoteStyle, void 0, ctx.quoteCompat);
377
400
  if (ctx.defaultCollectionStyle === "flow") return [`{${keys.map((k) => {
378
401
  return `${renderPlainKey(k)}: ${stringifyLines(obj[k], ctx, depth + 1, false).join(" ")}`;
379
402
  }).join(", ")}}`];
@@ -584,7 +607,7 @@ function stringifyScalarNodeLines(node, ctx) {
584
607
  else lines = ["null"];
585
608
  } else if (typeof val === "boolean") lines = [val ? "true" : "false"];
586
609
  else if (typeof val === "number") lines = [node.raw !== void 0 ? node.raw : renderNumber(val)];
587
- else if (typeof val === "string") lines = renderString(val, style, " ".repeat(ctx.indent), !!node.tag, ctx.forceDefaultStyles, node.chomp, ctx.parentPosition, ctx.quoteStyle, node.blockIndent).split("\n");
610
+ 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).split("\n");
588
611
  else lines = [renderDoubleQuoted(String(val))];
589
612
  if (node.tag) lines[0] = `${node.tag} ${lines[0]}`;
590
613
  if (node.anchor) lines[0] = `&${node.anchor} ${lines[0]}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effected/yaml",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "private": false,
5
5
  "description": "Zero-dependency YAML parsing, editing, formatting and linting as Effect schemas.",
6
6
  "keywords": [