yaml 2.8.2 → 3.0.0-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.
Files changed (238) hide show
  1. package/README.md +65 -85
  2. package/{bin.mjs → bin.js} +1 -1
  3. package/dist/chunk-BYypO7fO.js +18 -0
  4. package/dist/cli.d.ts +10 -7
  5. package/dist/cli.js +181 -0
  6. package/dist/directives-CG6n4xSM.js +2856 -0
  7. package/dist/index.d.ts +335 -25
  8. package/dist/index.js +4 -49
  9. package/dist/line-counter-TFl552k_.js +3098 -0
  10. package/dist/public-api-BE74JyVm.js +79 -0
  11. package/dist/stringifyString-S_ITVLTO.d.ts +1306 -0
  12. package/dist/test-events.d.ts +6 -3
  13. package/dist/test-events.js +98 -124
  14. package/dist/util.d.ts +2 -16
  15. package/dist/util.js +2 -27
  16. package/package.json +20 -44
  17. package/browser/dist/compose/compose-collection.js +0 -88
  18. package/browser/dist/compose/compose-doc.js +0 -43
  19. package/browser/dist/compose/compose-node.js +0 -102
  20. package/browser/dist/compose/compose-scalar.js +0 -86
  21. package/browser/dist/compose/composer.js +0 -217
  22. package/browser/dist/compose/resolve-block-map.js +0 -115
  23. package/browser/dist/compose/resolve-block-scalar.js +0 -198
  24. package/browser/dist/compose/resolve-block-seq.js +0 -49
  25. package/browser/dist/compose/resolve-end.js +0 -37
  26. package/browser/dist/compose/resolve-flow-collection.js +0 -207
  27. package/browser/dist/compose/resolve-flow-scalar.js +0 -223
  28. package/browser/dist/compose/resolve-props.js +0 -146
  29. package/browser/dist/compose/util-contains-newline.js +0 -34
  30. package/browser/dist/compose/util-empty-scalar-position.js +0 -26
  31. package/browser/dist/compose/util-flow-indent-check.js +0 -15
  32. package/browser/dist/compose/util-map-includes.js +0 -13
  33. package/browser/dist/doc/Document.js +0 -335
  34. package/browser/dist/doc/anchors.js +0 -71
  35. package/browser/dist/doc/applyReviver.js +0 -55
  36. package/browser/dist/doc/createNode.js +0 -88
  37. package/browser/dist/doc/directives.js +0 -176
  38. package/browser/dist/errors.js +0 -57
  39. package/browser/dist/index.js +0 -17
  40. package/browser/dist/log.js +0 -11
  41. package/browser/dist/nodes/Alias.js +0 -114
  42. package/browser/dist/nodes/Collection.js +0 -147
  43. package/browser/dist/nodes/Node.js +0 -38
  44. package/browser/dist/nodes/Pair.js +0 -36
  45. package/browser/dist/nodes/Scalar.js +0 -24
  46. package/browser/dist/nodes/YAMLMap.js +0 -144
  47. package/browser/dist/nodes/YAMLSeq.js +0 -113
  48. package/browser/dist/nodes/addPairToJSMap.js +0 -63
  49. package/browser/dist/nodes/identity.js +0 -36
  50. package/browser/dist/nodes/toJS.js +0 -37
  51. package/browser/dist/parse/cst-scalar.js +0 -214
  52. package/browser/dist/parse/cst-stringify.js +0 -61
  53. package/browser/dist/parse/cst-visit.js +0 -97
  54. package/browser/dist/parse/cst.js +0 -98
  55. package/browser/dist/parse/lexer.js +0 -717
  56. package/browser/dist/parse/line-counter.js +0 -39
  57. package/browser/dist/parse/parser.js +0 -967
  58. package/browser/dist/public-api.js +0 -102
  59. package/browser/dist/schema/Schema.js +0 -37
  60. package/browser/dist/schema/common/map.js +0 -17
  61. package/browser/dist/schema/common/null.js +0 -15
  62. package/browser/dist/schema/common/seq.js +0 -17
  63. package/browser/dist/schema/common/string.js +0 -14
  64. package/browser/dist/schema/core/bool.js +0 -19
  65. package/browser/dist/schema/core/float.js +0 -43
  66. package/browser/dist/schema/core/int.js +0 -38
  67. package/browser/dist/schema/core/schema.js +0 -23
  68. package/browser/dist/schema/json/schema.js +0 -62
  69. package/browser/dist/schema/tags.js +0 -96
  70. package/browser/dist/schema/yaml-1.1/binary.js +0 -58
  71. package/browser/dist/schema/yaml-1.1/bool.js +0 -26
  72. package/browser/dist/schema/yaml-1.1/float.js +0 -46
  73. package/browser/dist/schema/yaml-1.1/int.js +0 -71
  74. package/browser/dist/schema/yaml-1.1/merge.js +0 -64
  75. package/browser/dist/schema/yaml-1.1/omap.js +0 -74
  76. package/browser/dist/schema/yaml-1.1/pairs.js +0 -78
  77. package/browser/dist/schema/yaml-1.1/schema.js +0 -39
  78. package/browser/dist/schema/yaml-1.1/set.js +0 -93
  79. package/browser/dist/schema/yaml-1.1/timestamp.js +0 -101
  80. package/browser/dist/stringify/foldFlowLines.js +0 -146
  81. package/browser/dist/stringify/stringify.js +0 -128
  82. package/browser/dist/stringify/stringifyCollection.js +0 -143
  83. package/browser/dist/stringify/stringifyComment.js +0 -20
  84. package/browser/dist/stringify/stringifyDocument.js +0 -85
  85. package/browser/dist/stringify/stringifyNumber.js +0 -24
  86. package/browser/dist/stringify/stringifyPair.js +0 -150
  87. package/browser/dist/stringify/stringifyString.js +0 -336
  88. package/browser/dist/util.js +0 -11
  89. package/browser/dist/visit.js +0 -233
  90. package/browser/index.js +0 -5
  91. package/browser/package.json +0 -3
  92. package/dist/cli.mjs +0 -201
  93. package/dist/compose/compose-collection.d.ts +0 -11
  94. package/dist/compose/compose-collection.js +0 -90
  95. package/dist/compose/compose-doc.d.ts +0 -7
  96. package/dist/compose/compose-doc.js +0 -45
  97. package/dist/compose/compose-node.d.ts +0 -29
  98. package/dist/compose/compose-node.js +0 -105
  99. package/dist/compose/compose-scalar.d.ts +0 -5
  100. package/dist/compose/compose-scalar.js +0 -88
  101. package/dist/compose/composer.d.ts +0 -63
  102. package/dist/compose/composer.js +0 -222
  103. package/dist/compose/resolve-block-map.d.ts +0 -6
  104. package/dist/compose/resolve-block-map.js +0 -117
  105. package/dist/compose/resolve-block-scalar.d.ts +0 -11
  106. package/dist/compose/resolve-block-scalar.js +0 -200
  107. package/dist/compose/resolve-block-seq.d.ts +0 -6
  108. package/dist/compose/resolve-block-seq.js +0 -51
  109. package/dist/compose/resolve-end.d.ts +0 -6
  110. package/dist/compose/resolve-end.js +0 -39
  111. package/dist/compose/resolve-flow-collection.d.ts +0 -7
  112. package/dist/compose/resolve-flow-collection.js +0 -209
  113. package/dist/compose/resolve-flow-scalar.d.ts +0 -10
  114. package/dist/compose/resolve-flow-scalar.js +0 -225
  115. package/dist/compose/resolve-props.d.ts +0 -23
  116. package/dist/compose/resolve-props.js +0 -148
  117. package/dist/compose/util-contains-newline.d.ts +0 -2
  118. package/dist/compose/util-contains-newline.js +0 -36
  119. package/dist/compose/util-empty-scalar-position.d.ts +0 -2
  120. package/dist/compose/util-empty-scalar-position.js +0 -28
  121. package/dist/compose/util-flow-indent-check.d.ts +0 -3
  122. package/dist/compose/util-flow-indent-check.js +0 -17
  123. package/dist/compose/util-map-includes.d.ts +0 -4
  124. package/dist/compose/util-map-includes.js +0 -15
  125. package/dist/doc/Document.d.ts +0 -141
  126. package/dist/doc/Document.js +0 -337
  127. package/dist/doc/anchors.d.ts +0 -24
  128. package/dist/doc/anchors.js +0 -76
  129. package/dist/doc/applyReviver.d.ts +0 -9
  130. package/dist/doc/applyReviver.js +0 -57
  131. package/dist/doc/createNode.d.ts +0 -17
  132. package/dist/doc/createNode.js +0 -90
  133. package/dist/doc/directives.d.ts +0 -49
  134. package/dist/doc/directives.js +0 -178
  135. package/dist/errors.d.ts +0 -21
  136. package/dist/errors.js +0 -62
  137. package/dist/log.d.ts +0 -3
  138. package/dist/log.js +0 -19
  139. package/dist/nodes/Alias.d.ts +0 -29
  140. package/dist/nodes/Alias.js +0 -116
  141. package/dist/nodes/Collection.d.ts +0 -73
  142. package/dist/nodes/Collection.js +0 -151
  143. package/dist/nodes/Node.d.ts +0 -53
  144. package/dist/nodes/Node.js +0 -40
  145. package/dist/nodes/Pair.d.ts +0 -22
  146. package/dist/nodes/Pair.js +0 -39
  147. package/dist/nodes/Scalar.d.ts +0 -43
  148. package/dist/nodes/Scalar.js +0 -27
  149. package/dist/nodes/YAMLMap.d.ts +0 -53
  150. package/dist/nodes/YAMLMap.js +0 -147
  151. package/dist/nodes/YAMLSeq.d.ts +0 -60
  152. package/dist/nodes/YAMLSeq.js +0 -115
  153. package/dist/nodes/addPairToJSMap.d.ts +0 -4
  154. package/dist/nodes/addPairToJSMap.js +0 -65
  155. package/dist/nodes/identity.d.ts +0 -23
  156. package/dist/nodes/identity.js +0 -53
  157. package/dist/nodes/toJS.d.ts +0 -29
  158. package/dist/nodes/toJS.js +0 -39
  159. package/dist/options.d.ts +0 -344
  160. package/dist/parse/cst-scalar.d.ts +0 -64
  161. package/dist/parse/cst-scalar.js +0 -218
  162. package/dist/parse/cst-stringify.d.ts +0 -8
  163. package/dist/parse/cst-stringify.js +0 -63
  164. package/dist/parse/cst-visit.d.ts +0 -39
  165. package/dist/parse/cst-visit.js +0 -99
  166. package/dist/parse/cst.d.ts +0 -109
  167. package/dist/parse/cst.js +0 -112
  168. package/dist/parse/lexer.d.ts +0 -87
  169. package/dist/parse/lexer.js +0 -719
  170. package/dist/parse/line-counter.d.ts +0 -22
  171. package/dist/parse/line-counter.js +0 -41
  172. package/dist/parse/parser.d.ts +0 -84
  173. package/dist/parse/parser.js +0 -972
  174. package/dist/public-api.d.ts +0 -44
  175. package/dist/public-api.js +0 -107
  176. package/dist/schema/Schema.d.ts +0 -17
  177. package/dist/schema/Schema.js +0 -39
  178. package/dist/schema/common/map.d.ts +0 -2
  179. package/dist/schema/common/map.js +0 -19
  180. package/dist/schema/common/null.d.ts +0 -4
  181. package/dist/schema/common/null.js +0 -17
  182. package/dist/schema/common/seq.d.ts +0 -2
  183. package/dist/schema/common/seq.js +0 -19
  184. package/dist/schema/common/string.d.ts +0 -2
  185. package/dist/schema/common/string.js +0 -16
  186. package/dist/schema/core/bool.d.ts +0 -4
  187. package/dist/schema/core/bool.js +0 -21
  188. package/dist/schema/core/float.d.ts +0 -4
  189. package/dist/schema/core/float.js +0 -47
  190. package/dist/schema/core/int.d.ts +0 -4
  191. package/dist/schema/core/int.js +0 -42
  192. package/dist/schema/core/schema.d.ts +0 -1
  193. package/dist/schema/core/schema.js +0 -25
  194. package/dist/schema/json/schema.d.ts +0 -2
  195. package/dist/schema/json/schema.js +0 -64
  196. package/dist/schema/json-schema.d.ts +0 -69
  197. package/dist/schema/tags.d.ts +0 -48
  198. package/dist/schema/tags.js +0 -99
  199. package/dist/schema/types.d.ts +0 -92
  200. package/dist/schema/yaml-1.1/binary.d.ts +0 -2
  201. package/dist/schema/yaml-1.1/binary.js +0 -70
  202. package/dist/schema/yaml-1.1/bool.d.ts +0 -7
  203. package/dist/schema/yaml-1.1/bool.js +0 -29
  204. package/dist/schema/yaml-1.1/float.d.ts +0 -4
  205. package/dist/schema/yaml-1.1/float.js +0 -50
  206. package/dist/schema/yaml-1.1/int.d.ts +0 -5
  207. package/dist/schema/yaml-1.1/int.js +0 -76
  208. package/dist/schema/yaml-1.1/merge.d.ts +0 -9
  209. package/dist/schema/yaml-1.1/merge.js +0 -68
  210. package/dist/schema/yaml-1.1/omap.d.ts +0 -22
  211. package/dist/schema/yaml-1.1/omap.js +0 -77
  212. package/dist/schema/yaml-1.1/pairs.d.ts +0 -10
  213. package/dist/schema/yaml-1.1/pairs.js +0 -82
  214. package/dist/schema/yaml-1.1/schema.d.ts +0 -1
  215. package/dist/schema/yaml-1.1/schema.js +0 -41
  216. package/dist/schema/yaml-1.1/set.d.ts +0 -28
  217. package/dist/schema/yaml-1.1/set.js +0 -96
  218. package/dist/schema/yaml-1.1/timestamp.d.ts +0 -6
  219. package/dist/schema/yaml-1.1/timestamp.js +0 -105
  220. package/dist/stringify/foldFlowLines.d.ts +0 -34
  221. package/dist/stringify/foldFlowLines.js +0 -151
  222. package/dist/stringify/stringify.d.ts +0 -21
  223. package/dist/stringify/stringify.js +0 -131
  224. package/dist/stringify/stringifyCollection.d.ts +0 -17
  225. package/dist/stringify/stringifyCollection.js +0 -145
  226. package/dist/stringify/stringifyComment.d.ts +0 -10
  227. package/dist/stringify/stringifyComment.js +0 -24
  228. package/dist/stringify/stringifyDocument.d.ts +0 -4
  229. package/dist/stringify/stringifyDocument.js +0 -87
  230. package/dist/stringify/stringifyNumber.d.ts +0 -2
  231. package/dist/stringify/stringifyNumber.js +0 -26
  232. package/dist/stringify/stringifyPair.d.ts +0 -3
  233. package/dist/stringify/stringifyPair.js +0 -152
  234. package/dist/stringify/stringifyString.d.ts +0 -9
  235. package/dist/stringify/stringifyString.js +0 -338
  236. package/dist/visit.d.ts +0 -102
  237. package/dist/visit.js +0 -236
  238. package/util.js +0 -2
@@ -0,0 +1,2856 @@
1
+ //#region src/doc/applyReviver.ts
2
+ /**
3
+ * Applies the JSON.parse reviver algorithm as defined in the ECMA-262 spec,
4
+ * in section 24.5.1.1 "Runtime Semantics: InternalizeJSONProperty" of the
5
+ * 2021 edition: https://tc39.es/ecma262/#sec-json.parse
6
+ *
7
+ * Includes extensions for handling Map and Set objects.
8
+ */
9
+ function applyReviver(reviver, obj, key, val) {
10
+ if (val && typeof val === "object") if (Array.isArray(val)) for (let i = 0, len = val.length; i < len; ++i) {
11
+ const v0 = val[i];
12
+ const v1 = applyReviver(reviver, val, String(i), v0);
13
+ if (v1 === void 0) delete val[i];
14
+ else if (v1 !== v0) val[i] = v1;
15
+ }
16
+ else if (val instanceof Map) for (const k of Array.from(val.keys())) {
17
+ const v0 = val.get(k);
18
+ const v1 = applyReviver(reviver, val, k, v0);
19
+ if (v1 === void 0) val.delete(k);
20
+ else if (v1 !== v0) val.set(k, v1);
21
+ }
22
+ else if (val instanceof Set) for (const v0 of Array.from(val)) {
23
+ const v1 = applyReviver(reviver, val, v0, v0);
24
+ if (v1 === void 0) val.delete(v0);
25
+ else if (v1 !== v0) {
26
+ val.delete(v0);
27
+ val.add(v1);
28
+ }
29
+ }
30
+ else for (const [k, v0] of Object.entries(val)) {
31
+ const v1 = applyReviver(reviver, val, k, v0);
32
+ if (v1 === void 0) delete val[k];
33
+ else if (v1 !== v0) val[k] = v1;
34
+ }
35
+ return reviver.call(obj, key, val);
36
+ }
37
+
38
+ //#endregion
39
+ //#region src/nodes/toJS.ts
40
+ /**
41
+ * Recursively convert any node or its contents to native JavaScript
42
+ *
43
+ * @param value - The input value
44
+ * @param arg - If `value` defines a `toJSON()` method, use this
45
+ * as its first argument
46
+ * @param ctx - Conversion context, originally set in Document#toJS(). If
47
+ * `{ keep: true }` is not set, output should be suitable for JSON
48
+ * stringification.
49
+ */
50
+ function toJS(value, arg, ctx) {
51
+ if (Array.isArray(value)) return value.map((v, i) => toJS(v, String(i), ctx));
52
+ if (value && typeof value.toJSON === "function") {
53
+ const node = value;
54
+ if (!ctx || !(node instanceof NodeBase) || !node.anchor) return value.toJSON(arg, ctx);
55
+ const data = {
56
+ aliasCount: 0,
57
+ count: 1,
58
+ res: void 0
59
+ };
60
+ ctx.anchors.set(node, data);
61
+ ctx.onCreate = (res) => {
62
+ data.res = res;
63
+ delete ctx.onCreate;
64
+ };
65
+ const res = node.toJSON(arg, ctx);
66
+ if (ctx.onCreate) ctx.onCreate(res);
67
+ return res;
68
+ }
69
+ if (typeof value === "bigint" && !ctx?.keep) return Number(value);
70
+ return value;
71
+ }
72
+
73
+ //#endregion
74
+ //#region src/nodes/Node.ts
75
+ var NodeBase = class {
76
+ /** Create a copy of this node. */
77
+ clone(_schema) {
78
+ const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));
79
+ if (this.range) copy.range = this.range.slice();
80
+ return copy;
81
+ }
82
+ /** A plain JavaScript representation of this node. */
83
+ toJS(doc, { mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {
84
+ if (!doc?.schema) throw new TypeError("A document argument is required");
85
+ const ctx = {
86
+ anchors: /* @__PURE__ */ new Map(),
87
+ doc,
88
+ keep: true,
89
+ mapAsMap: mapAsMap === true,
90
+ mapKeyWarned: false,
91
+ maxAliasCount: typeof maxAliasCount === "number" ? maxAliasCount : 100
92
+ };
93
+ const res = toJS(this, "", ctx);
94
+ if (typeof onAnchor === "function") for (const { count, res } of ctx.anchors.values()) onAnchor(res, count);
95
+ return typeof reviver === "function" ? applyReviver(reviver, { "": res }, "", res) : res;
96
+ }
97
+ };
98
+
99
+ //#endregion
100
+ //#region src/nodes/Scalar.ts
101
+ var Scalar = class extends NodeBase {
102
+ static BLOCK_FOLDED = "BLOCK_FOLDED";
103
+ static BLOCK_LITERAL = "BLOCK_LITERAL";
104
+ static PLAIN = "PLAIN";
105
+ static QUOTE_DOUBLE = "QUOTE_DOUBLE";
106
+ static QUOTE_SINGLE = "QUOTE_SINGLE";
107
+ value;
108
+ constructor(value) {
109
+ super();
110
+ this.value = value;
111
+ }
112
+ toJSON(arg, ctx) {
113
+ return ctx?.keep ? this.value : toJS(this.value, arg, ctx);
114
+ }
115
+ toString() {
116
+ return String(this.value);
117
+ }
118
+ };
119
+
120
+ //#endregion
121
+ //#region src/stringify/foldFlowLines.ts
122
+ const FOLD_FLOW = "flow";
123
+ const FOLD_BLOCK = "block";
124
+ const FOLD_QUOTED = "quoted";
125
+ /**
126
+ * Tries to keep input at up to `lineWidth` characters, splitting only on spaces
127
+ * not followed by newlines or spaces unless `mode` is `'quoted'`. Lines are
128
+ * terminated with `\n` and started with `indent`.
129
+ */
130
+ function foldFlowLines(text, indent, mode = "flow", { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) {
131
+ if (!lineWidth || lineWidth < 0) return text;
132
+ if (lineWidth < minContentWidth) minContentWidth = 0;
133
+ const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent.length);
134
+ if (text.length <= endStep) return text;
135
+ const folds = [];
136
+ const escapedFolds = {};
137
+ let end = lineWidth - indent.length;
138
+ if (typeof indentAtStart === "number") if (indentAtStart > lineWidth - Math.max(2, minContentWidth)) folds.push(0);
139
+ else end = lineWidth - indentAtStart;
140
+ let split = void 0;
141
+ let prev = void 0;
142
+ let overflow = false;
143
+ let i = -1;
144
+ let escStart = -1;
145
+ let escEnd = -1;
146
+ if (mode === FOLD_BLOCK) {
147
+ i = consumeMoreIndentedLines(text, i, indent.length);
148
+ if (i !== -1) end = i + endStep;
149
+ }
150
+ for (let ch; ch = text[i += 1];) {
151
+ if (mode === FOLD_QUOTED && ch === "\\") {
152
+ escStart = i;
153
+ switch (text[i + 1]) {
154
+ case "x":
155
+ i += 3;
156
+ break;
157
+ case "u":
158
+ i += 5;
159
+ break;
160
+ case "U":
161
+ i += 9;
162
+ break;
163
+ default: i += 1;
164
+ }
165
+ escEnd = i;
166
+ }
167
+ if (ch === "\n") {
168
+ if (mode === FOLD_BLOCK) i = consumeMoreIndentedLines(text, i, indent.length);
169
+ end = i + indent.length + endStep;
170
+ split = void 0;
171
+ } else {
172
+ if (ch === " " && prev && prev !== " " && prev !== "\n" && prev !== " ") {
173
+ const next = text[i + 1];
174
+ if (next && next !== " " && next !== "\n" && next !== " ") split = i;
175
+ }
176
+ if (i >= end) if (split) {
177
+ folds.push(split);
178
+ end = split + endStep;
179
+ split = void 0;
180
+ } else if (mode === FOLD_QUOTED) {
181
+ while (prev === " " || prev === " ") {
182
+ prev = ch;
183
+ ch = text[i += 1];
184
+ overflow = true;
185
+ }
186
+ const j = i > escEnd + 1 ? i - 2 : escStart - 1;
187
+ if (escapedFolds[j]) return text;
188
+ folds.push(j);
189
+ escapedFolds[j] = true;
190
+ end = j + endStep;
191
+ split = void 0;
192
+ } else overflow = true;
193
+ }
194
+ prev = ch;
195
+ }
196
+ if (overflow && onOverflow) onOverflow();
197
+ if (folds.length === 0) return text;
198
+ if (onFold) onFold();
199
+ let res = text.slice(0, folds[0]);
200
+ for (let i = 0; i < folds.length; ++i) {
201
+ const fold = folds[i];
202
+ const end = folds[i + 1] || text.length;
203
+ if (fold === 0) res = `\n${indent}${text.slice(0, end)}`;
204
+ else {
205
+ if (mode === FOLD_QUOTED && escapedFolds[fold]) res += `${text[fold]}\\`;
206
+ res += `\n${indent}${text.slice(fold + 1, end)}`;
207
+ }
208
+ }
209
+ return res;
210
+ }
211
+ /**
212
+ * Presumes `i + 1` is at the start of a line
213
+ * @returns index of last newline in more-indented block
214
+ */
215
+ function consumeMoreIndentedLines(text, i, indent) {
216
+ let end = i;
217
+ let start = i + 1;
218
+ let ch = text[start];
219
+ while (ch === " " || ch === " ") if (i < start + indent) ch = text[++i];
220
+ else {
221
+ do
222
+ ch = text[++i];
223
+ while (ch && ch !== "\n");
224
+ end = i;
225
+ start = i + 1;
226
+ ch = text[start];
227
+ }
228
+ return end;
229
+ }
230
+
231
+ //#endregion
232
+ //#region src/stringify/stringifyString.ts
233
+ const getFoldOptions = (ctx, isBlock) => ({
234
+ indentAtStart: isBlock ? ctx.indent.length : ctx.indentAtStart,
235
+ lineWidth: ctx.options.lineWidth,
236
+ minContentWidth: ctx.options.minContentWidth
237
+ });
238
+ const containsDocumentMarker = (str) => /^(%|---|\.\.\.)/m.test(str);
239
+ function lineLengthOverLimit(str, lineWidth, indentLength) {
240
+ if (!lineWidth || lineWidth < 0) return false;
241
+ const limit = lineWidth - indentLength;
242
+ const strLen = str.length;
243
+ if (strLen <= limit) return false;
244
+ for (let i = 0, start = 0; i < strLen; ++i) if (str[i] === "\n") {
245
+ if (i - start > limit) return true;
246
+ start = i + 1;
247
+ if (strLen - start <= limit) return false;
248
+ }
249
+ return true;
250
+ }
251
+ function doubleQuotedString(value, ctx) {
252
+ const json = JSON.stringify(value);
253
+ if (ctx.options.doubleQuotedAsJSON) return json;
254
+ const { implicitKey } = ctx;
255
+ const minMultiLineLength = ctx.options.doubleQuotedMinMultiLineLength;
256
+ const indent = ctx.indent || (containsDocumentMarker(value) ? " " : "");
257
+ let str = "";
258
+ let start = 0;
259
+ for (let i = 0, ch = json[i]; ch; ch = json[++i]) {
260
+ if (ch === " " && json[i + 1] === "\\" && json[i + 2] === "n") {
261
+ str += json.slice(start, i) + "\\ ";
262
+ i += 1;
263
+ start = i;
264
+ ch = "\\";
265
+ }
266
+ if (ch === "\\") switch (json[i + 1]) {
267
+ case "u":
268
+ {
269
+ str += json.slice(start, i);
270
+ const code = json.substr(i + 2, 4);
271
+ switch (code) {
272
+ case "0000":
273
+ str += "\\0";
274
+ break;
275
+ case "0007":
276
+ str += "\\a";
277
+ break;
278
+ case "000b":
279
+ str += "\\v";
280
+ break;
281
+ case "001b":
282
+ str += "\\e";
283
+ break;
284
+ case "0085":
285
+ str += "\\N";
286
+ break;
287
+ case "00a0":
288
+ str += "\\_";
289
+ break;
290
+ case "2028":
291
+ str += "\\L";
292
+ break;
293
+ case "2029":
294
+ str += "\\P";
295
+ break;
296
+ default: if (code.substr(0, 2) === "00") str += "\\x" + code.substr(2);
297
+ else str += json.substr(i, 6);
298
+ }
299
+ i += 5;
300
+ start = i + 1;
301
+ }
302
+ break;
303
+ case "n":
304
+ if (implicitKey || json[i + 2] === "\"" || json.length < minMultiLineLength) i += 1;
305
+ else {
306
+ str += json.slice(start, i) + "\n\n";
307
+ while (json[i + 2] === "\\" && json[i + 3] === "n" && json[i + 4] !== "\"") {
308
+ str += "\n";
309
+ i += 2;
310
+ }
311
+ str += indent;
312
+ if (json[i + 2] === " ") str += "\\";
313
+ i += 1;
314
+ start = i + 1;
315
+ }
316
+ break;
317
+ default: i += 1;
318
+ }
319
+ }
320
+ str = start ? str + json.slice(start) : json;
321
+ return implicitKey ? str : foldFlowLines(str, indent, FOLD_QUOTED, getFoldOptions(ctx, false));
322
+ }
323
+ function singleQuotedString(value, ctx) {
324
+ if (ctx.options.singleQuote === false || ctx.implicitKey && value.includes("\n") || /[ \t]\n|\n[ \t]/.test(value)) return doubleQuotedString(value, ctx);
325
+ const indent = ctx.indent || (containsDocumentMarker(value) ? " " : "");
326
+ const res = "'" + value.replace(/'/g, "''").replace(/\n+/g, `$&\n${indent}`) + "'";
327
+ return ctx.implicitKey ? res : foldFlowLines(res, indent, FOLD_FLOW, getFoldOptions(ctx, false));
328
+ }
329
+ function quotedString(value, ctx) {
330
+ const { singleQuote } = ctx.options;
331
+ let qs;
332
+ if (singleQuote === false) qs = doubleQuotedString;
333
+ else {
334
+ const hasDouble = value.includes("\"");
335
+ const hasSingle = value.includes("'");
336
+ if (hasDouble && !hasSingle) qs = singleQuotedString;
337
+ else if (hasSingle && !hasDouble) qs = doubleQuotedString;
338
+ else qs = singleQuote ? singleQuotedString : doubleQuotedString;
339
+ }
340
+ return qs(value, ctx);
341
+ }
342
+ let blockEndNewlines;
343
+ try {
344
+ blockEndNewlines = /* @__PURE__ */ new RegExp("(^|(?<!\n))\n+(?!\n|$)", "g");
345
+ } catch {
346
+ blockEndNewlines = /\n+(?!\n|$)/g;
347
+ }
348
+ function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
349
+ const { blockQuote, commentString, lineWidth } = ctx.options;
350
+ if (!blockQuote || /\n[\t ]+$/.test(value)) return quotedString(value, ctx);
351
+ const indent = ctx.indent || (ctx.forceBlockIndent || containsDocumentMarker(value) ? " " : "");
352
+ const literal = blockQuote === "literal" ? true : blockQuote === "folded" || type === Scalar.BLOCK_FOLDED ? false : type === Scalar.BLOCK_LITERAL ? true : !lineLengthOverLimit(value, lineWidth, indent.length);
353
+ if (!value) return literal ? "|\n" : ">\n";
354
+ let chomp;
355
+ let endStart;
356
+ for (endStart = value.length; endStart > 0; --endStart) {
357
+ const ch = value[endStart - 1];
358
+ if (ch !== "\n" && ch !== " " && ch !== " ") break;
359
+ }
360
+ let end = value.substring(endStart);
361
+ const endNlPos = end.indexOf("\n");
362
+ if (endNlPos === -1) chomp = "-";
363
+ else if (value === end || endNlPos !== end.length - 1) {
364
+ chomp = "+";
365
+ if (onChompKeep) onChompKeep();
366
+ } else chomp = "";
367
+ if (end) {
368
+ value = value.slice(0, -end.length);
369
+ if (end[end.length - 1] === "\n") end = end.slice(0, -1);
370
+ end = end.replace(blockEndNewlines, `$&${indent}`);
371
+ }
372
+ let startWithSpace = false;
373
+ let startEnd;
374
+ let startNlPos = -1;
375
+ for (startEnd = 0; startEnd < value.length; ++startEnd) {
376
+ const ch = value[startEnd];
377
+ if (ch === " ") startWithSpace = true;
378
+ else if (ch === "\n") startNlPos = startEnd;
379
+ else break;
380
+ }
381
+ let start = value.substring(0, startNlPos < startEnd ? startNlPos + 1 : startEnd);
382
+ if (start) {
383
+ value = value.substring(start.length);
384
+ start = start.replace(/\n+/g, `$&${indent}`);
385
+ }
386
+ let header = (startWithSpace ? indent ? "2" : "1" : "") + chomp;
387
+ if (comment) {
388
+ header += " " + commentString(comment.replace(/ ?[\r\n]+/g, " "));
389
+ if (onComment) onComment();
390
+ }
391
+ if (!literal) {
392
+ const foldedValue = value.replace(/\n+/g, "\n$&").replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, "$1$2").replace(/\n+/g, `$&${indent}`);
393
+ let literalFallback = false;
394
+ const foldOptions = getFoldOptions(ctx, true);
395
+ if (blockQuote !== "folded" && type !== Scalar.BLOCK_FOLDED) foldOptions.onOverflow = () => {
396
+ literalFallback = true;
397
+ };
398
+ const body = foldFlowLines(`${start}${foldedValue}${end}`, indent, FOLD_BLOCK, foldOptions);
399
+ if (!literalFallback) return `>${header}\n${indent}${body}`;
400
+ }
401
+ value = value.replace(/\n+/g, `$&${indent}`);
402
+ return `|${header}\n${indent}${start}${value}${end}`;
403
+ }
404
+ function plainString(item, ctx, onComment, onChompKeep) {
405
+ const { type, value } = item;
406
+ const { actualString, implicitKey, indent, indentStep, inFlow } = ctx;
407
+ if (implicitKey && value.includes("\n") || inFlow && /[[\]{},]/.test(value)) return quotedString(value, ctx);
408
+ if (/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) return implicitKey || inFlow || !value.includes("\n") ? quotedString(value, ctx) : blockString(item, ctx, onComment, onChompKeep);
409
+ if (!implicitKey && !inFlow && type !== Scalar.PLAIN && value.includes("\n")) return blockString(item, ctx, onComment, onChompKeep);
410
+ if (containsDocumentMarker(value)) {
411
+ if (indent === "") {
412
+ ctx.forceBlockIndent = true;
413
+ return blockString(item, ctx, onComment, onChompKeep);
414
+ } else if (implicitKey && indent === indentStep) return quotedString(value, ctx);
415
+ }
416
+ const str = value.replace(/\n+/g, `$&\n${indent}`);
417
+ if (actualString) {
418
+ const test = (tag) => tag.default && tag.tag !== "tag:yaml.org,2002:str" && tag.test?.test(str);
419
+ const { compat, tags } = ctx.doc.schema;
420
+ if (tags.some(test) || compat?.some(test)) return quotedString(value, ctx);
421
+ }
422
+ return implicitKey ? str : foldFlowLines(str, indent, FOLD_FLOW, getFoldOptions(ctx, false));
423
+ }
424
+ function stringifyString(item, ctx, onComment, onChompKeep) {
425
+ const { implicitKey, inFlow } = ctx;
426
+ const ss = typeof item.value === "string" ? item : Object.assign({}, item, { value: String(item.value) });
427
+ let { type } = item;
428
+ if (type !== Scalar.QUOTE_DOUBLE) {
429
+ if (/[\x00-\x08\x0b-\x1f\x7f-\x9f\u{D800}-\u{DFFF}]/u.test(ss.value)) type = Scalar.QUOTE_DOUBLE;
430
+ }
431
+ const _stringify = (_type) => {
432
+ switch (_type) {
433
+ case Scalar.BLOCK_FOLDED:
434
+ case Scalar.BLOCK_LITERAL: return implicitKey || inFlow ? quotedString(ss.value, ctx) : blockString(ss, ctx, onComment, onChompKeep);
435
+ case Scalar.QUOTE_DOUBLE: return doubleQuotedString(ss.value, ctx);
436
+ case Scalar.QUOTE_SINGLE: return singleQuotedString(ss.value, ctx);
437
+ case Scalar.PLAIN: return plainString(ss, ctx, onComment, onChompKeep);
438
+ default: return null;
439
+ }
440
+ };
441
+ let res = _stringify(type);
442
+ if (res === null) {
443
+ const { defaultKeyType, defaultStringType } = ctx.options;
444
+ const t = implicitKey && defaultKeyType || defaultStringType;
445
+ res = _stringify(t);
446
+ if (res === null) throw new Error(`Unsupported default string type ${t}`);
447
+ }
448
+ return res;
449
+ }
450
+
451
+ //#endregion
452
+ //#region src/doc/anchors.ts
453
+ /**
454
+ * Verify that the input string is a valid anchor.
455
+ *
456
+ * Will throw on errors.
457
+ */
458
+ function anchorIsValid(anchor) {
459
+ if (/[\x00-\x19\s,[\]{}]/.test(anchor)) {
460
+ const msg = `Anchor must not contain whitespace or control characters: ${JSON.stringify(anchor)}`;
461
+ throw new Error(msg);
462
+ }
463
+ return true;
464
+ }
465
+ function anchorNames(root) {
466
+ const anchors = /* @__PURE__ */ new Set();
467
+ visit(root, { Value(_key, node) {
468
+ if (node.anchor) anchors.add(node.anchor);
469
+ } });
470
+ return anchors;
471
+ }
472
+ /** Find a new anchor name with the given `prefix` and a one-indexed suffix. */
473
+ function findNewAnchor(prefix, exclude) {
474
+ for (let i = 1;; ++i) {
475
+ const name = `${prefix}${i}`;
476
+ if (!exclude.has(name)) return name;
477
+ }
478
+ }
479
+
480
+ //#endregion
481
+ //#region src/doc/NodeCreator.ts
482
+ const defaultTagPrefix = "tag:yaml.org,2002:";
483
+ var NodeCreator = class {
484
+ keepUndefined;
485
+ replacer;
486
+ schema;
487
+ #aliasDuplicateObjects;
488
+ #anchorPrefix;
489
+ #aliasObjects = [];
490
+ #doc;
491
+ #flow;
492
+ #onTagObj;
493
+ #prevAnchors = null;
494
+ #sourceObjects = /* @__PURE__ */ new Map();
495
+ constructor(docOrSchema, options = {}, replacer) {
496
+ this.keepUndefined = options.keepUndefined ?? false;
497
+ this.replacer = replacer;
498
+ this.#flow = options.flow ?? false;
499
+ this.#onTagObj = options.onTagObj;
500
+ this.#aliasDuplicateObjects = options.aliasDuplicateObjects ?? true;
501
+ this.#anchorPrefix = options.anchorPrefix || "a";
502
+ if (docOrSchema instanceof Document) {
503
+ this.#doc = docOrSchema;
504
+ this.schema = docOrSchema.schema;
505
+ } else this.schema = docOrSchema;
506
+ }
507
+ create(value, tagName) {
508
+ if (value instanceof Document) value = value.value;
509
+ if (value instanceof NodeBase) return value;
510
+ if (value instanceof Pair) {
511
+ const map = this.schema.map.nodeClass.from(this, null);
512
+ map.items.push(value);
513
+ return map;
514
+ }
515
+ if (value instanceof String || value instanceof Number || value instanceof Boolean || typeof BigInt !== "undefined" && value instanceof BigInt) value = value.valueOf();
516
+ let ref = void 0;
517
+ if (this.#aliasDuplicateObjects && value && typeof value === "object") {
518
+ ref = this.#sourceObjects.get(value);
519
+ if (ref) {
520
+ if (!ref.anchor) {
521
+ this.#aliasObjects.push(value);
522
+ this.#prevAnchors ??= anchorNames(this.#doc);
523
+ ref.anchor = findNewAnchor(this.#anchorPrefix, this.#prevAnchors);
524
+ this.#prevAnchors.add(ref.anchor);
525
+ }
526
+ return new Alias(ref.anchor);
527
+ } else {
528
+ ref = {
529
+ anchor: null,
530
+ node: null
531
+ };
532
+ this.#sourceObjects.set(value, ref);
533
+ }
534
+ }
535
+ let tagObj;
536
+ if (tagName) {
537
+ if (tagName.startsWith("!!")) tagName = defaultTagPrefix + tagName.slice(2);
538
+ const match = this.schema.tags.filter((t) => t.tag === tagName);
539
+ tagObj = match.find((t) => !t.format) ?? match[0];
540
+ if (!tagObj) throw new Error(`Tag ${tagName} not found`);
541
+ } else tagObj = this.schema.tags.find((t) => t.identify?.(value) && !t.format);
542
+ if (!tagObj) {
543
+ if (value && typeof value.toJSON === "function") value = value.toJSON();
544
+ if (!value || typeof value !== "object") {
545
+ const node = new Scalar(value);
546
+ if (ref) ref.node = node;
547
+ return node;
548
+ }
549
+ tagObj = value instanceof Map ? this.schema.map : Symbol.iterator in Object(value) ? this.schema.seq : this.schema.map;
550
+ }
551
+ if (this.#onTagObj) {
552
+ this.#onTagObj(tagObj);
553
+ this.#onTagObj = void 0;
554
+ }
555
+ const node = tagObj?.createNode?.(this, value) ?? tagObj?.nodeClass?.from?.(this, value) ?? new Scalar(value);
556
+ if (tagName) node.tag = tagName;
557
+ else if (!tagObj.default) node.tag = tagObj.tag;
558
+ if (ref) ref.node = node;
559
+ if (this.#flow && node instanceof Collection) node.flow = true;
560
+ return node;
561
+ }
562
+ createPair(key, value) {
563
+ return new Pair(this.create(key), value == null ? null : this.create(value));
564
+ }
565
+ /**
566
+ * With circular references, the source node is only resolved after all
567
+ * of its child nodes are. This is why anchors are set only after all of
568
+ * the nodes have been created.
569
+ */
570
+ setAnchors() {
571
+ for (const source of this.#aliasObjects) {
572
+ const ref = this.#sourceObjects.get(source);
573
+ if (typeof ref === "object" && ref.anchor && (ref.node instanceof Scalar || ref.node instanceof Collection)) ref.node.anchor = ref.anchor;
574
+ else throw Object.assign(new Error("Failed to resolve repeated object (this should not happen)"), { source });
575
+ }
576
+ }
577
+ };
578
+
579
+ //#endregion
580
+ //#region src/nodes/Collection.ts
581
+ function collectionFromPath(schema, path, value) {
582
+ let v = value;
583
+ for (let i = path.length - 1; i >= 0; --i) {
584
+ const k = path[i];
585
+ if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
586
+ const a = [];
587
+ a[k] = v;
588
+ v = a;
589
+ } else v = new Map([[k, v]]);
590
+ }
591
+ return new NodeCreator(schema, { aliasDuplicateObjects: false }).create(v);
592
+ }
593
+ var Collection = class Collection extends NodeBase {
594
+ schema;
595
+ constructor(schema) {
596
+ super();
597
+ Object.defineProperty(this, "schema", {
598
+ value: schema,
599
+ configurable: true,
600
+ enumerable: false,
601
+ writable: true
602
+ });
603
+ }
604
+ /**
605
+ * Create a copy of this collection.
606
+ *
607
+ * @param schema - If defined, overwrites the original's schema
608
+ */
609
+ clone(schema) {
610
+ const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));
611
+ if (schema) copy.schema = schema;
612
+ copy.items = copy.items.map((it) => it.clone(schema));
613
+ if (this.range) copy.range = this.range.slice();
614
+ return copy;
615
+ }
616
+ /**
617
+ * Adds a value to the collection.
618
+ *
619
+ * For `!!map` and `!!omap` the value must be a Pair instance.
620
+ */
621
+ addIn(path, value) {
622
+ if (!path.length) this.add(value);
623
+ else {
624
+ const [key, ...rest] = path;
625
+ const node = this.get(key);
626
+ if (node instanceof Collection) node.addIn(rest, value);
627
+ else if (node === void 0 && this.schema) this.set(key, collectionFromPath(this.schema, rest, value));
628
+ else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
629
+ }
630
+ }
631
+ /**
632
+ * Removes a value from the collection.
633
+ *
634
+ * @returns `true` if the item was found and removed.
635
+ */
636
+ deleteIn(path) {
637
+ const [key, ...rest] = path;
638
+ if (rest.length === 0) return this.delete(key);
639
+ const node = this.get(key);
640
+ if (node instanceof Collection) return node.deleteIn(rest);
641
+ else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
642
+ }
643
+ /**
644
+ * Returns item at `key`, or `undefined` if not found.
645
+ */
646
+ getIn(path) {
647
+ const [key, ...rest] = path;
648
+ const node = this.get(key);
649
+ if (rest.length === 0) return node;
650
+ else return node instanceof Collection ? node.getIn(rest) : void 0;
651
+ }
652
+ /**
653
+ * Checks if the collection includes a value with the key `key`.
654
+ */
655
+ hasIn(path) {
656
+ const [key, ...rest] = path;
657
+ if (rest.length === 0) return this.has(key);
658
+ const node = this.get(key);
659
+ return node instanceof Collection ? node.hasIn(rest) : false;
660
+ }
661
+ /**
662
+ * Sets a value in this collection.
663
+ */
664
+ setIn(path, value) {
665
+ const [key, ...rest] = path;
666
+ if (rest.length === 0) this.set(key, value);
667
+ else {
668
+ const node = this.get(key);
669
+ if (node instanceof Collection) node.setIn(rest, value);
670
+ else if (node === void 0 && this.schema) this.set(key, collectionFromPath(this.schema, rest, value));
671
+ else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
672
+ }
673
+ }
674
+ };
675
+
676
+ //#endregion
677
+ //#region src/stringify/stringifyComment.ts
678
+ /**
679
+ * Stringifies a comment.
680
+ *
681
+ * Empty comment lines are left empty,
682
+ * lines consisting of a single space are replaced by `#`,
683
+ * and all other lines are prefixed with a `#`.
684
+ */
685
+ const stringifyComment = (str) => str.replace(/^(?!$)(?: $)?/gm, "#");
686
+ function indentComment(comment, indent) {
687
+ if (/^\n+$/.test(comment)) return comment.substring(1);
688
+ return indent ? comment.replace(/^(?! *$)/gm, indent) : comment;
689
+ }
690
+ const lineComment = (str, indent, comment) => str.endsWith("\n") ? indentComment(comment, indent) : comment.includes("\n") ? "\n" + indentComment(comment, indent) : (str.endsWith(" ") ? "" : " ") + comment;
691
+
692
+ //#endregion
693
+ //#region src/stringify/stringify.ts
694
+ function createStringifyContext(doc, options) {
695
+ const opt = Object.assign({
696
+ blockQuote: true,
697
+ commentString: stringifyComment,
698
+ defaultKeyType: null,
699
+ defaultStringType: "PLAIN",
700
+ directives: null,
701
+ doubleQuotedAsJSON: false,
702
+ doubleQuotedMinMultiLineLength: 40,
703
+ falseStr: "false",
704
+ flowCollectionPadding: true,
705
+ indentSeq: true,
706
+ lineWidth: 80,
707
+ minContentWidth: 20,
708
+ nullStr: "null",
709
+ simpleKeys: false,
710
+ singleQuote: null,
711
+ trueStr: "true",
712
+ verifyAliasOrder: true
713
+ }, doc.schema.toStringOptions, options);
714
+ let inFlow;
715
+ switch (opt.collectionStyle) {
716
+ case "block":
717
+ inFlow = false;
718
+ break;
719
+ case "flow":
720
+ inFlow = true;
721
+ break;
722
+ default: inFlow = null;
723
+ }
724
+ return {
725
+ anchors: /* @__PURE__ */ new Set(),
726
+ doc,
727
+ flowCollectionPadding: opt.flowCollectionPadding ? " " : "",
728
+ indent: "",
729
+ indentStep: typeof opt.indent === "number" ? " ".repeat(opt.indent) : " ",
730
+ inFlow,
731
+ options: opt
732
+ };
733
+ }
734
+ function getTagObject(tags, item) {
735
+ if (item.tag) {
736
+ const match = tags.filter((t) => t.tag === item.tag);
737
+ if (match.length > 0) return match.find((t) => t.format === item.format) ?? match[0];
738
+ }
739
+ let tagObj = void 0;
740
+ let obj;
741
+ if (item instanceof Scalar) {
742
+ obj = item.value;
743
+ let match = tags.filter((t) => t.identify?.(obj));
744
+ if (match.length > 1) {
745
+ const testMatch = match.filter((t) => t.test);
746
+ if (testMatch.length > 0) match = testMatch;
747
+ }
748
+ tagObj = match.find((t) => t.format === item.format) ?? match.find((t) => !t.format);
749
+ } else {
750
+ obj = item;
751
+ tagObj = tags.find((t) => t.nodeClass && obj instanceof t.nodeClass);
752
+ }
753
+ if (!tagObj) {
754
+ const name = obj?.constructor?.name ?? (obj === null ? "null" : typeof obj);
755
+ throw new Error(`Tag not resolved for ${name} value`);
756
+ }
757
+ return tagObj;
758
+ }
759
+ function stringifyProps(node, tagObj, { anchors, doc }) {
760
+ if (!doc.directives) return "";
761
+ const props = [];
762
+ const anchor = (node instanceof Scalar || node instanceof Collection) && node.anchor;
763
+ if (anchor && anchorIsValid(anchor)) {
764
+ anchors.add(anchor);
765
+ props.push(`&${anchor}`);
766
+ }
767
+ const tag = node.tag ?? (tagObj.default ? null : tagObj.tag);
768
+ if (tag) props.push(doc.directives.tagString(tag));
769
+ return props.join(" ");
770
+ }
771
+ function stringify(item, ctx, onComment, onChompKeep) {
772
+ if (item instanceof Pair) return item.toString(ctx, onComment, onChompKeep);
773
+ if (item instanceof Alias) {
774
+ if (ctx.doc.directives) return item.toString(ctx);
775
+ if (ctx.resolvedAliases?.has(item)) throw new TypeError(`Cannot stringify circular structure without alias nodes`);
776
+ else {
777
+ if (ctx.resolvedAliases) ctx.resolvedAliases.add(item);
778
+ else ctx.resolvedAliases = new Set([item]);
779
+ item = item.resolve(ctx.doc);
780
+ }
781
+ }
782
+ let tagObj = void 0;
783
+ const node = item instanceof NodeBase ? item : ctx.doc.createNode(item, { onTagObj: (o) => tagObj = o });
784
+ tagObj ??= getTagObject(ctx.doc.schema.tags, node);
785
+ const props = stringifyProps(node, tagObj, ctx);
786
+ if (props.length > 0) ctx.indentAtStart = (ctx.indentAtStart ?? 0) + props.length + 1;
787
+ const str = typeof tagObj.stringify === "function" ? tagObj.stringify(node, ctx, onComment, onChompKeep) : node instanceof Scalar ? stringifyString(node, ctx, onComment, onChompKeep) : node.toString(ctx, onComment, onChompKeep);
788
+ if (!props) return str;
789
+ return node instanceof Scalar || str[0] === "{" || str[0] === "[" ? `${props} ${str}` : `${props}\n${ctx.indent}${str}`;
790
+ }
791
+
792
+ //#endregion
793
+ //#region src/stringify/stringifyCollection.ts
794
+ function stringifyCollection(collection, ctx, options) {
795
+ return (ctx.inFlow ?? collection.flow ? stringifyFlowCollection : stringifyBlockCollection)(collection, ctx, options);
796
+ }
797
+ function stringifyBlockCollection({ comment, items }, ctx, { blockItemPrefix, flowChars, itemIndent, onChompKeep, onComment }) {
798
+ const { indent, options: { commentString } } = ctx;
799
+ const itemCtx = Object.assign({}, ctx, {
800
+ indent: itemIndent,
801
+ type: null
802
+ });
803
+ let chompKeep = false;
804
+ const lines = [];
805
+ for (let i = 0; i < items.length; ++i) {
806
+ const item = items[i];
807
+ let comment = null;
808
+ if (item instanceof NodeBase) {
809
+ if (!chompKeep && item.spaceBefore) lines.push("");
810
+ addCommentBefore(ctx, lines, item.commentBefore, chompKeep);
811
+ if (item.comment) comment = item.comment;
812
+ } else if (item instanceof Pair) {
813
+ const ik = item.key instanceof NodeBase ? item.key : null;
814
+ if (ik) {
815
+ if (!chompKeep && ik.spaceBefore) lines.push("");
816
+ addCommentBefore(ctx, lines, ik.commentBefore, chompKeep);
817
+ }
818
+ }
819
+ chompKeep = false;
820
+ let str = stringify(item, itemCtx, () => comment = null, () => chompKeep = true);
821
+ if (comment) str += lineComment(str, itemIndent, commentString(comment));
822
+ if (chompKeep && comment) chompKeep = false;
823
+ lines.push(blockItemPrefix + str);
824
+ }
825
+ let str;
826
+ if (lines.length === 0) str = flowChars.start + flowChars.end;
827
+ else {
828
+ str = lines[0];
829
+ for (let i = 1; i < lines.length; ++i) {
830
+ const line = lines[i];
831
+ str += line ? `\n${indent}${line}` : "\n";
832
+ }
833
+ }
834
+ if (comment) {
835
+ str += "\n" + indentComment(commentString(comment), indent);
836
+ if (onComment) onComment();
837
+ } else if (chompKeep && onChompKeep) onChompKeep();
838
+ return str;
839
+ }
840
+ function stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) {
841
+ const { indent, indentStep, flowCollectionPadding: fcPadding, options: { commentString } } = ctx;
842
+ itemIndent += indentStep;
843
+ const itemCtx = Object.assign({}, ctx, {
844
+ indent: itemIndent,
845
+ inFlow: true,
846
+ type: null
847
+ });
848
+ let reqNewline = false;
849
+ let linesAtValue = 0;
850
+ const lines = [];
851
+ for (let i = 0; i < items.length; ++i) {
852
+ const item = items[i];
853
+ let comment = null;
854
+ if (item instanceof NodeBase) {
855
+ if (item.spaceBefore) lines.push("");
856
+ addCommentBefore(ctx, lines, item.commentBefore, false);
857
+ if (item.comment) comment = item.comment;
858
+ } else if (item instanceof Pair) {
859
+ const ik = item.key instanceof NodeBase ? item.key : null;
860
+ if (ik) {
861
+ if (ik.spaceBefore) lines.push("");
862
+ addCommentBefore(ctx, lines, ik.commentBefore, false);
863
+ if (ik.comment) reqNewline = true;
864
+ }
865
+ const iv = item.value instanceof NodeBase ? item.value : null;
866
+ if (iv) {
867
+ if (iv.comment) comment = iv.comment;
868
+ if (iv.commentBefore) reqNewline = true;
869
+ } else if (item.value == null && ik?.comment) comment = ik.comment;
870
+ }
871
+ if (comment) reqNewline = true;
872
+ let str = stringify(item, itemCtx, () => comment = null);
873
+ if (i < items.length - 1) str += ",";
874
+ if (comment) str += lineComment(str, itemIndent, commentString(comment));
875
+ if (!reqNewline && (lines.length > linesAtValue || str.includes("\n"))) reqNewline = true;
876
+ lines.push(str);
877
+ linesAtValue = lines.length;
878
+ }
879
+ const { start, end } = flowChars;
880
+ if (lines.length === 0) return start + end;
881
+ else {
882
+ if (!reqNewline) {
883
+ const len = lines.reduce((sum, line) => sum + line.length + 2, 2);
884
+ reqNewline = ctx.options.lineWidth > 0 && len > ctx.options.lineWidth;
885
+ }
886
+ if (reqNewline) {
887
+ let str = start;
888
+ for (const line of lines) str += line ? `\n${indentStep}${indent}${line}` : "\n";
889
+ return `${str}\n${indent}${end}`;
890
+ } else return `${start}${fcPadding}${lines.join(" ")}${fcPadding}${end}`;
891
+ }
892
+ }
893
+ function addCommentBefore({ indent, options: { commentString } }, lines, comment, chompKeep) {
894
+ if (comment && chompKeep) comment = comment.replace(/^\n+/, "");
895
+ if (comment) {
896
+ const ic = indentComment(commentString(comment), indent);
897
+ lines.push(ic.trimStart());
898
+ }
899
+ }
900
+
901
+ //#endregion
902
+ //#region src/nodes/YAMLSeq.ts
903
+ const isScalarValue = (value) => !value || typeof value !== "function" && typeof value !== "object";
904
+ var YAMLSeq = class extends Collection {
905
+ static get tagName() {
906
+ return "tag:yaml.org,2002:seq";
907
+ }
908
+ items = [];
909
+ add(value, options) {
910
+ if (value instanceof NodeBase) this.items.push(value);
911
+ else if (!this.schema) throw new Error("Schema is required");
912
+ else {
913
+ const nc = new NodeCreator(this.schema, {
914
+ ...options,
915
+ aliasDuplicateObjects: false
916
+ });
917
+ this.items.push(nc.create(value));
918
+ nc.setAnchors();
919
+ }
920
+ }
921
+ /**
922
+ * Removes a value from the collection.
923
+ *
924
+ * Throws if `idx` is not a non-negative integer.
925
+ *
926
+ * @returns `true` if the item was found and removed.
927
+ */
928
+ delete(idx) {
929
+ if (!Number.isInteger(idx)) throw new TypeError(`Expected an integer, not ${idx}.`);
930
+ if (idx < 0) throw new RangeError(`Invalid negative index ${idx}`);
931
+ return this.items.splice(idx, 1).length > 0;
932
+ }
933
+ /**
934
+ * Returns item at `key`, or `undefined` if not found.
935
+ *
936
+ * Throws if `idx` is not a non-negative integer.
937
+ */
938
+ get(idx) {
939
+ if (!Number.isInteger(idx)) throw new TypeError(`Expected an integer, not ${JSON.stringify(idx)}.`);
940
+ if (idx < 0) throw new RangeError(`Invalid negative index ${idx}`);
941
+ return this.items[idx];
942
+ }
943
+ /**
944
+ * Checks if the collection includes a value with the key `key`.
945
+ *
946
+ * Throws if `idx` is not a non-negative integer.
947
+ */
948
+ has(idx) {
949
+ if (!Number.isInteger(idx)) throw new TypeError(`Expected an integer, not ${JSON.stringify(idx)}.`);
950
+ if (idx < 0) throw new RangeError(`Invalid negative index ${idx}`);
951
+ return idx < this.items.length;
952
+ }
953
+ /**
954
+ * Sets a value in this collection. For `!!set`, `value` needs to be a
955
+ * boolean to add/remove the item from the set.
956
+ *
957
+ * Throws if `idx` is not a non-negative integer.
958
+ */
959
+ set(idx, value, options) {
960
+ if (!Number.isInteger(idx)) throw new TypeError(`Expected an integer, not ${JSON.stringify(idx)}.`);
961
+ if (idx < 0) throw new RangeError(`Invalid negative index ${idx}`);
962
+ const prev = this.items[idx];
963
+ if (prev instanceof Scalar && isScalarValue(value)) prev.value = value;
964
+ else if (value instanceof NodeBase) this.items[idx] = value;
965
+ else if (!this.schema) throw new Error("Schema is required");
966
+ else {
967
+ const nc = new NodeCreator(this.schema, {
968
+ ...options,
969
+ aliasDuplicateObjects: false
970
+ });
971
+ this.items[idx] = nc.create(value);
972
+ nc.setAnchors();
973
+ }
974
+ }
975
+ toJSON(_, ctx) {
976
+ const seq = [];
977
+ if (ctx?.onCreate) ctx.onCreate(seq);
978
+ let i = 0;
979
+ for (const item of this.items) seq.push(toJS(item, String(i++), ctx));
980
+ return seq;
981
+ }
982
+ toString(ctx, onComment, onChompKeep) {
983
+ if (!ctx) return JSON.stringify(this);
984
+ return stringifyCollection(this, ctx, {
985
+ blockItemPrefix: "- ",
986
+ flowChars: {
987
+ start: "[",
988
+ end: "]"
989
+ },
990
+ itemIndent: (ctx.indent || "") + " ",
991
+ onChompKeep,
992
+ onComment
993
+ });
994
+ }
995
+ static from(nc, obj) {
996
+ const seq = new this(nc.schema);
997
+ if (obj && Symbol.iterator in Object(obj)) {
998
+ let i = 0;
999
+ for (let it of obj) {
1000
+ if (typeof nc.replacer === "function") {
1001
+ const key = obj instanceof Set ? it : String(i++);
1002
+ it = nc.replacer.call(obj, key, it);
1003
+ }
1004
+ seq.items.push(nc.create(it));
1005
+ }
1006
+ }
1007
+ return seq;
1008
+ }
1009
+ };
1010
+
1011
+ //#endregion
1012
+ //#region src/stringify/stringifyPair.ts
1013
+ function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
1014
+ const { doc, indent, indentStep, noValues, options: { commentString, indentSeq, simpleKeys } } = ctx;
1015
+ let keyComment = key instanceof NodeBase && key.comment || null;
1016
+ if (simpleKeys) {
1017
+ if (keyComment) throw new Error("With simple keys, key nodes cannot have comments");
1018
+ if (key instanceof Collection || !(key instanceof NodeBase) && typeof key === "object") throw new Error("With simple keys, collection cannot be used as a key value");
1019
+ }
1020
+ let explicitKey = !simpleKeys && (!key || !(key instanceof Scalar) || key.type === Scalar.BLOCK_FOLDED || key.type === Scalar.BLOCK_LITERAL);
1021
+ ctx = {
1022
+ ...ctx,
1023
+ implicitKey: !explicitKey && (simpleKeys || !noValues),
1024
+ indent: indent + indentStep,
1025
+ noValues: false
1026
+ };
1027
+ let keyCommentDone = false;
1028
+ let chompKeep = false;
1029
+ let str = stringify(key, ctx, () => keyCommentDone = true, () => chompKeep = true);
1030
+ if (!explicitKey && !ctx.inFlow && str.length > 1024) {
1031
+ if (simpleKeys) throw new Error("With simple keys, single line scalar must not span more than 1024 characters");
1032
+ explicitKey = true;
1033
+ }
1034
+ if (ctx.inFlow) {
1035
+ if (noValues || value == null) {
1036
+ if (keyCommentDone && onComment) onComment();
1037
+ return str === "" ? "?" : explicitKey ? `? ${str}` : noValues ? str : `${str}:`;
1038
+ }
1039
+ } else if (noValues && !simpleKeys || value == null && explicitKey) {
1040
+ str = `? ${str}`;
1041
+ if (keyComment && !keyCommentDone) str += lineComment(str, ctx.indent, commentString(keyComment));
1042
+ else if (chompKeep && onChompKeep) onChompKeep();
1043
+ return str;
1044
+ }
1045
+ if (keyCommentDone) keyComment = null;
1046
+ if (explicitKey) {
1047
+ if (keyComment) str += lineComment(str, ctx.indent, commentString(keyComment));
1048
+ str = `? ${str}\n${indent}:`;
1049
+ } else {
1050
+ str = `${str}:`;
1051
+ if (keyComment) str += lineComment(str, ctx.indent, commentString(keyComment));
1052
+ }
1053
+ let vsb, vcb, valueComment;
1054
+ if (value instanceof NodeBase) {
1055
+ vsb = !!value.spaceBefore;
1056
+ vcb = value.commentBefore;
1057
+ valueComment = value.comment;
1058
+ } else {
1059
+ vsb = false;
1060
+ vcb = null;
1061
+ valueComment = null;
1062
+ if (value && typeof value === "object") value = doc.createNode(value);
1063
+ }
1064
+ ctx.implicitKey = false;
1065
+ if (!explicitKey && !keyComment && value instanceof Scalar) ctx.indentAtStart = str.length + 1;
1066
+ chompKeep = false;
1067
+ if (!indentSeq && indentStep.length >= 2 && !ctx.inFlow && !explicitKey && value instanceof YAMLSeq && !value.flow && !value.tag && !value.anchor) ctx.indent = ctx.indent.substring(2);
1068
+ let valueCommentDone = false;
1069
+ const valueStr = stringify(value, ctx, () => valueCommentDone = true, () => chompKeep = true);
1070
+ let ws = " ";
1071
+ if (keyComment || vsb || vcb) {
1072
+ ws = vsb ? "\n" : "";
1073
+ if (vcb) {
1074
+ const cs = commentString(vcb);
1075
+ ws += `\n${indentComment(cs, ctx.indent)}`;
1076
+ }
1077
+ if (valueStr === "" && !ctx.inFlow) {
1078
+ if (ws === "\n" && valueComment) ws = "\n\n";
1079
+ } else ws += `\n${ctx.indent}`;
1080
+ } else if (!explicitKey && value instanceof Collection) {
1081
+ const vs0 = valueStr[0];
1082
+ const nl0 = valueStr.indexOf("\n");
1083
+ const hasNewline = nl0 !== -1;
1084
+ const flow = ctx.inFlow ?? value.flow ?? value.items.length === 0;
1085
+ if (hasNewline || !flow) {
1086
+ let hasPropsLine = false;
1087
+ if (hasNewline && (vs0 === "&" || vs0 === "!")) {
1088
+ let sp0 = valueStr.indexOf(" ");
1089
+ if (vs0 === "&" && sp0 !== -1 && sp0 < nl0 && valueStr[sp0 + 1] === "!") sp0 = valueStr.indexOf(" ", sp0 + 1);
1090
+ if (sp0 === -1 || nl0 < sp0) hasPropsLine = true;
1091
+ }
1092
+ if (!hasPropsLine) ws = `\n${ctx.indent}`;
1093
+ }
1094
+ } else if (valueStr === "" || valueStr[0] === "\n") ws = "";
1095
+ str += ws + valueStr;
1096
+ if (ctx.inFlow) {
1097
+ if (valueCommentDone && onComment) onComment();
1098
+ } else if (valueComment && !valueCommentDone) str += lineComment(str, ctx.indent, commentString(valueComment));
1099
+ else if (chompKeep && onChompKeep) onChompKeep();
1100
+ return str;
1101
+ }
1102
+
1103
+ //#endregion
1104
+ //#region src/log.ts
1105
+ function debug(logLevel, ...messages) {
1106
+ if (logLevel === "debug") console.log(...messages);
1107
+ }
1108
+ function warn(logLevel, warning) {
1109
+ if (logLevel === "debug" || logLevel === "warn") if (typeof process !== "undefined" && typeof process.emitWarning === "function") process.emitWarning(warning);
1110
+ else console.warn(warning);
1111
+ }
1112
+
1113
+ //#endregion
1114
+ //#region src/schema/yaml-1.1/merge.ts
1115
+ const MERGE_KEY = "<<";
1116
+ const merge = {
1117
+ identify: (value) => value === MERGE_KEY || typeof value === "symbol" && value.description === MERGE_KEY,
1118
+ default: "key",
1119
+ tag: "tag:yaml.org,2002:merge",
1120
+ test: /^<<$/,
1121
+ resolve: () => Object.assign(new Scalar(Symbol(MERGE_KEY)), { addToJSMap: addMergeToJSMap }),
1122
+ stringify: () => MERGE_KEY
1123
+ };
1124
+ const isMergeKey = (ctx, key) => (merge.identify(key) || key instanceof Scalar && (!key.type || key.type === Scalar.PLAIN) && merge.identify(key.value)) && Boolean(ctx?.doc.schema.tags.some((tag) => tag.tag === merge.tag && tag.default));
1125
+ function addMergeToJSMap(ctx, map, value) {
1126
+ value = ctx && value instanceof Alias ? value.resolve(ctx.doc) : value;
1127
+ if (value instanceof YAMLSeq) for (const it of value.items) mergeValue(ctx, map, it);
1128
+ else if (Array.isArray(value)) for (const it of value) mergeValue(ctx, map, it);
1129
+ else mergeValue(ctx, map, value);
1130
+ }
1131
+ function mergeValue(ctx, map, value) {
1132
+ const srcMap = (ctx && value instanceof Alias ? value.resolve(ctx.doc) : value).toJSON(null, ctx, Map);
1133
+ if (!(srcMap instanceof Map)) throw new Error("Merge sources must be maps or map aliases");
1134
+ for (const [key, value] of srcMap) if (map instanceof Map) {
1135
+ if (!map.has(key)) map.set(key, value);
1136
+ } else if (map instanceof Set) map.add(key);
1137
+ else if (!Object.prototype.hasOwnProperty.call(map, key)) Object.defineProperty(map, key, {
1138
+ value,
1139
+ writable: true,
1140
+ enumerable: true,
1141
+ configurable: true
1142
+ });
1143
+ return map;
1144
+ }
1145
+
1146
+ //#endregion
1147
+ //#region src/nodes/addPairToJSMap.ts
1148
+ function addPairToJSMap(ctx, map, { key, value }) {
1149
+ if (key instanceof NodeBase && key.addToJSMap) key.addToJSMap(ctx, map, value);
1150
+ else if (isMergeKey(ctx, key)) addMergeToJSMap(ctx, map, value);
1151
+ else {
1152
+ const jsKey = toJS(key, "", ctx);
1153
+ if (map instanceof Map) map.set(jsKey, toJS(value, jsKey, ctx));
1154
+ else if (map instanceof Set) map.add(jsKey);
1155
+ else {
1156
+ const stringKey = stringifyKey(key, jsKey, ctx);
1157
+ const jsValue = toJS(value, stringKey, ctx);
1158
+ if (stringKey in map) Object.defineProperty(map, stringKey, {
1159
+ value: jsValue,
1160
+ writable: true,
1161
+ enumerable: true,
1162
+ configurable: true
1163
+ });
1164
+ else map[stringKey] = jsValue;
1165
+ }
1166
+ }
1167
+ return map;
1168
+ }
1169
+ function stringifyKey(key, jsKey, ctx) {
1170
+ if (jsKey === null) return "";
1171
+ if (typeof jsKey !== "object") return String(jsKey);
1172
+ if (key instanceof NodeBase && ctx?.doc) {
1173
+ const strCtx = createStringifyContext(ctx.doc, {});
1174
+ strCtx.anchors = /* @__PURE__ */ new Set();
1175
+ for (const node of ctx.anchors.keys()) strCtx.anchors.add(node.anchor);
1176
+ strCtx.inFlow = true;
1177
+ strCtx.inStringifyKey = true;
1178
+ const strKey = key.toString(strCtx);
1179
+ if (!ctx.mapKeyWarned) {
1180
+ let jsonStr = JSON.stringify(strKey);
1181
+ if (jsonStr.length > 40) jsonStr = jsonStr.substring(0, 36) + "...\"";
1182
+ warn(ctx.doc.options.logLevel, `Keys with collection values will be stringified due to JS Object restrictions: ${jsonStr}. Set mapAsMap: true to use object keys.`);
1183
+ ctx.mapKeyWarned = true;
1184
+ }
1185
+ return strKey;
1186
+ }
1187
+ return JSON.stringify(jsKey);
1188
+ }
1189
+
1190
+ //#endregion
1191
+ //#region src/nodes/Pair.ts
1192
+ var Pair = class Pair {
1193
+ key;
1194
+ value;
1195
+ constructor(key, value = null) {
1196
+ this.key = key;
1197
+ this.value = value;
1198
+ }
1199
+ clone(schema) {
1200
+ return new Pair(this.key.clone(schema), this.value?.clone(schema) ?? null);
1201
+ }
1202
+ toJSON(_, ctx) {
1203
+ return addPairToJSMap(ctx, ctx?.mapAsMap ? /* @__PURE__ */ new Map() : {}, this);
1204
+ }
1205
+ toString(ctx, onComment, onChompKeep) {
1206
+ return ctx?.doc ? stringifyPair(this, ctx, onComment, onChompKeep) : JSON.stringify(this);
1207
+ }
1208
+ };
1209
+
1210
+ //#endregion
1211
+ //#region src/nodes/Alias.ts
1212
+ var Alias = class Alias extends NodeBase {
1213
+ source;
1214
+ constructor(source) {
1215
+ super();
1216
+ this.source = source;
1217
+ Object.defineProperty(this, "tag", { set() {
1218
+ throw new Error("Alias nodes cannot have tags");
1219
+ } });
1220
+ }
1221
+ /**
1222
+ * Resolve the value of this alias within `doc`, finding the last
1223
+ * instance of the `source` anchor before this node.
1224
+ */
1225
+ resolve(doc, ctx) {
1226
+ let nodes;
1227
+ if (ctx?.aliasResolveCache) nodes = ctx.aliasResolveCache;
1228
+ else {
1229
+ nodes = [];
1230
+ visit(doc, { Node: (_key, node) => {
1231
+ if (node instanceof Alias || node.anchor) nodes.push(node);
1232
+ } });
1233
+ if (ctx) ctx.aliasResolveCache = nodes;
1234
+ }
1235
+ let found = void 0;
1236
+ for (const node of nodes) {
1237
+ if (node === this) break;
1238
+ if (node.anchor === this.source) found = node;
1239
+ }
1240
+ return found;
1241
+ }
1242
+ toJSON(_arg, ctx) {
1243
+ if (!ctx) return { source: this.source };
1244
+ const { anchors, doc, maxAliasCount } = ctx;
1245
+ const source = this.resolve(doc, ctx);
1246
+ if (!source) {
1247
+ const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
1248
+ throw new ReferenceError(msg);
1249
+ }
1250
+ let data = anchors.get(source);
1251
+ if (!data) {
1252
+ toJS(source, null, ctx);
1253
+ data = anchors.get(source);
1254
+ }
1255
+ /* istanbul ignore if */
1256
+ if (data?.res === void 0) throw new ReferenceError("This should not happen: Alias anchor was not resolved?");
1257
+ if (maxAliasCount >= 0) {
1258
+ data.count += 1;
1259
+ if (data.aliasCount === 0) data.aliasCount = getAliasCount(doc, source, anchors);
1260
+ if (data.count * data.aliasCount > maxAliasCount) throw new ReferenceError("Excessive alias count indicates a resource exhaustion attack");
1261
+ }
1262
+ return data.res;
1263
+ }
1264
+ toString(ctx, _onComment, _onChompKeep) {
1265
+ const src = `*${this.source}`;
1266
+ if (ctx) {
1267
+ anchorIsValid(this.source);
1268
+ if (ctx.options.verifyAliasOrder && !ctx.anchors.has(this.source)) {
1269
+ const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
1270
+ throw new Error(msg);
1271
+ }
1272
+ if (ctx.implicitKey) return `${src} `;
1273
+ }
1274
+ return src;
1275
+ }
1276
+ };
1277
+ function getAliasCount(doc, node, anchors) {
1278
+ if (node instanceof Alias) {
1279
+ const source = node.resolve(doc);
1280
+ const anchor = anchors && source && anchors.get(source);
1281
+ return anchor ? anchor.count * anchor.aliasCount : 0;
1282
+ } else if (node instanceof NodeBase && "items" in node) {
1283
+ const coll = node;
1284
+ let count = 0;
1285
+ for (const item of coll.items) {
1286
+ const c = getAliasCount(doc, item, anchors);
1287
+ if (c > count) count = c;
1288
+ }
1289
+ return count;
1290
+ } else if (node instanceof Pair) {
1291
+ const kc = getAliasCount(doc, node.key, anchors);
1292
+ const vc = getAliasCount(doc, node.value, anchors);
1293
+ return Math.max(kc, vc);
1294
+ }
1295
+ return 1;
1296
+ }
1297
+
1298
+ //#endregion
1299
+ //#region src/nodes/YAMLMap.ts
1300
+ function findPair(items, key) {
1301
+ const k = key instanceof Scalar ? key.value : key;
1302
+ for (const it of items) {
1303
+ if (it.key === key || it.key === k) return it;
1304
+ if (it.key instanceof Scalar && it.key.value === k) return it;
1305
+ }
1306
+ }
1307
+ var YAMLMap = class extends Collection {
1308
+ static get tagName() {
1309
+ return "tag:yaml.org,2002:map";
1310
+ }
1311
+ items = [];
1312
+ /**
1313
+ * A generic collection parsing method that can be extended
1314
+ * to other node classes that inherit from YAMLMap
1315
+ */
1316
+ static from(nc, obj) {
1317
+ const { replacer } = nc;
1318
+ const map = new this(nc.schema);
1319
+ const add = (key, value) => {
1320
+ if (typeof replacer === "function") value = replacer.call(obj, key, value);
1321
+ else if (Array.isArray(replacer) && !replacer.includes(key)) return;
1322
+ if (value !== void 0 || nc.keepUndefined) map.items.push(nc.createPair(key, value));
1323
+ };
1324
+ if (obj instanceof Map) for (const [key, value] of obj) add(key, value);
1325
+ else if (obj && typeof obj === "object") for (const key of Object.keys(obj)) add(key, obj[key]);
1326
+ if (typeof nc.schema.sortMapEntries === "function") map.items.sort(nc.schema.sortMapEntries);
1327
+ return map;
1328
+ }
1329
+ /**
1330
+ * Adds a key-value pair to the map.
1331
+ *
1332
+ * Using a key that is already in the collection overwrites the previous value.
1333
+ */
1334
+ add(pair) {
1335
+ if (!(pair instanceof Pair)) throw new TypeError("Expected a Pair");
1336
+ const prev = findPair(this.items, pair.key);
1337
+ const sortEntries = this.schema?.sortMapEntries;
1338
+ if (prev) if (prev.value instanceof Scalar && pair.value instanceof Scalar) prev.value.value = pair.value.value;
1339
+ else prev.value = pair.value;
1340
+ else if (sortEntries) {
1341
+ const i = this.items.findIndex((item) => sortEntries(pair, item) < 0);
1342
+ if (i === -1) this.items.push(pair);
1343
+ else this.items.splice(i, 0, pair);
1344
+ } else this.items.push(pair);
1345
+ }
1346
+ delete(key) {
1347
+ const it = findPair(this.items, key);
1348
+ if (!it) return false;
1349
+ return this.items.splice(this.items.indexOf(it), 1).length > 0;
1350
+ }
1351
+ get(key) {
1352
+ return findPair(this.items, key)?.value ?? void 0;
1353
+ }
1354
+ has(key) {
1355
+ return !!findPair(this.items, key);
1356
+ }
1357
+ set(key, value, options) {
1358
+ let pair;
1359
+ if (key instanceof NodeBase && (value instanceof NodeBase || value === null)) pair = new Pair(key, value);
1360
+ else if (!this.schema) throw new Error("Schema is required");
1361
+ else {
1362
+ const nc = new NodeCreator(this.schema, {
1363
+ ...options,
1364
+ aliasDuplicateObjects: false
1365
+ });
1366
+ pair = nc.createPair(key, value);
1367
+ nc.setAnchors();
1368
+ }
1369
+ this.add(pair);
1370
+ }
1371
+ toJSON(_, ctx, Type) {
1372
+ const map = Type ? new Type() : ctx?.mapAsMap ? /* @__PURE__ */ new Map() : {};
1373
+ if (ctx?.onCreate) ctx.onCreate(map);
1374
+ for (const item of this.items) addPairToJSMap(ctx, map, item);
1375
+ return map;
1376
+ }
1377
+ toString(ctx, onComment, onChompKeep) {
1378
+ if (!ctx) return JSON.stringify(this);
1379
+ for (const item of this.items) if (!(item instanceof Pair)) throw new Error(`Map items must all be pairs; found ${JSON.stringify(item)} instead`);
1380
+ return stringifyCollection(this, ctx, {
1381
+ blockItemPrefix: "",
1382
+ flowChars: {
1383
+ start: "{",
1384
+ end: "}"
1385
+ },
1386
+ itemIndent: ctx.indent || "",
1387
+ onChompKeep,
1388
+ onComment
1389
+ });
1390
+ }
1391
+ };
1392
+
1393
+ //#endregion
1394
+ //#region src/schema/common/map.ts
1395
+ const map = {
1396
+ collection: "map",
1397
+ default: true,
1398
+ nodeClass: YAMLMap,
1399
+ tag: "tag:yaml.org,2002:map",
1400
+ resolve(map, onError) {
1401
+ if (!(map instanceof YAMLMap)) onError("Expected a mapping for this tag");
1402
+ return map;
1403
+ }
1404
+ };
1405
+
1406
+ //#endregion
1407
+ //#region src/schema/common/seq.ts
1408
+ const seq = {
1409
+ collection: "seq",
1410
+ default: true,
1411
+ nodeClass: YAMLSeq,
1412
+ tag: "tag:yaml.org,2002:seq",
1413
+ resolve(seq, onError) {
1414
+ if (!(seq instanceof YAMLSeq)) onError("Expected a sequence for this tag");
1415
+ return seq;
1416
+ }
1417
+ };
1418
+
1419
+ //#endregion
1420
+ //#region src/schema/common/string.ts
1421
+ const string = {
1422
+ identify: (value) => typeof value === "string",
1423
+ default: true,
1424
+ tag: "tag:yaml.org,2002:str",
1425
+ resolve: (str) => str,
1426
+ stringify(item, ctx, onComment, onChompKeep) {
1427
+ ctx = Object.assign({ actualString: true }, ctx);
1428
+ return stringifyString(item, ctx, onComment, onChompKeep);
1429
+ }
1430
+ };
1431
+
1432
+ //#endregion
1433
+ //#region src/schema/common/null.ts
1434
+ const nullTag = {
1435
+ identify: (value) => value == null,
1436
+ createNode: () => new Scalar(null),
1437
+ default: true,
1438
+ tag: "tag:yaml.org,2002:null",
1439
+ test: /^(?:~|[Nn]ull|NULL)?$/,
1440
+ resolve: () => new Scalar(null),
1441
+ stringify: ({ source }, ctx) => typeof source === "string" && nullTag.test.test(source) ? source : ctx.options.nullStr
1442
+ };
1443
+
1444
+ //#endregion
1445
+ //#region src/schema/core/bool.ts
1446
+ const boolTag = {
1447
+ identify: (value) => typeof value === "boolean",
1448
+ default: true,
1449
+ tag: "tag:yaml.org,2002:bool",
1450
+ test: /^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/,
1451
+ resolve: (str) => new Scalar(str[0] === "t" || str[0] === "T"),
1452
+ stringify({ source, value }, ctx) {
1453
+ if (source && boolTag.test.test(source)) {
1454
+ if (value === (source[0] === "t" || source[0] === "T")) return source;
1455
+ }
1456
+ return value ? ctx.options.trueStr : ctx.options.falseStr;
1457
+ }
1458
+ };
1459
+
1460
+ //#endregion
1461
+ //#region src/stringify/stringifyNumber.ts
1462
+ function stringifyNumber({ format, minFractionDigits, tag, value }) {
1463
+ if (typeof value === "bigint") return String(value);
1464
+ const num = typeof value === "number" ? value : Number(value);
1465
+ if (!isFinite(num)) return isNaN(num) ? ".nan" : num < 0 ? "-.inf" : ".inf";
1466
+ let n = Object.is(value, -0) ? "-0" : JSON.stringify(value);
1467
+ if (!format && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^\d/.test(n)) {
1468
+ let i = n.indexOf(".");
1469
+ if (i < 0) {
1470
+ i = n.length;
1471
+ n += ".";
1472
+ }
1473
+ let d = minFractionDigits - (n.length - i - 1);
1474
+ while (d-- > 0) n += "0";
1475
+ }
1476
+ return n;
1477
+ }
1478
+
1479
+ //#endregion
1480
+ //#region src/schema/core/float.ts
1481
+ const floatNaN$1 = {
1482
+ identify: (value) => typeof value === "number",
1483
+ default: true,
1484
+ tag: "tag:yaml.org,2002:float",
1485
+ test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
1486
+ resolve: (str) => str.slice(-3).toLowerCase() === "nan" ? NaN : str[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,
1487
+ stringify: stringifyNumber
1488
+ };
1489
+ const floatExp$1 = {
1490
+ identify: (value) => typeof value === "number",
1491
+ default: true,
1492
+ tag: "tag:yaml.org,2002:float",
1493
+ format: "EXP",
1494
+ test: /^[-+]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)[eE][-+]?[0-9]+$/,
1495
+ resolve: (str) => parseFloat(str),
1496
+ stringify(node) {
1497
+ const num = Number(node.value);
1498
+ return isFinite(num) ? num.toExponential() : stringifyNumber(node);
1499
+ }
1500
+ };
1501
+ const float$1 = {
1502
+ identify: (value) => typeof value === "number",
1503
+ default: true,
1504
+ tag: "tag:yaml.org,2002:float",
1505
+ test: /^[-+]?(?:\.[0-9]+|[0-9]+\.[0-9]*)$/,
1506
+ resolve(str) {
1507
+ const node = new Scalar(parseFloat(str));
1508
+ const dot = str.indexOf(".");
1509
+ if (dot !== -1 && str[str.length - 1] === "0") node.minFractionDigits = str.length - dot - 1;
1510
+ return node;
1511
+ },
1512
+ stringify: stringifyNumber
1513
+ };
1514
+
1515
+ //#endregion
1516
+ //#region src/schema/core/int.ts
1517
+ const intIdentify$2 = (value) => typeof value === "bigint" || Number.isInteger(value);
1518
+ const intResolve$1 = (str, offset, radix, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str.substring(offset), radix);
1519
+ function intStringify$1(node, radix, prefix) {
1520
+ const { value } = node;
1521
+ if (intIdentify$2(value) && value >= 0) return prefix + value.toString(radix);
1522
+ return stringifyNumber(node);
1523
+ }
1524
+ const intOct$1 = {
1525
+ identify: (value) => intIdentify$2(value) && value >= 0,
1526
+ default: true,
1527
+ tag: "tag:yaml.org,2002:int",
1528
+ format: "OCT",
1529
+ test: /^0o[0-7]+$/,
1530
+ resolve: (str, _onError, opt) => intResolve$1(str, 2, 8, opt),
1531
+ stringify: (node) => intStringify$1(node, 8, "0o")
1532
+ };
1533
+ const int$1 = {
1534
+ identify: intIdentify$2,
1535
+ default: true,
1536
+ tag: "tag:yaml.org,2002:int",
1537
+ test: /^[-+]?[0-9]+$/,
1538
+ resolve: (str, _onError, opt) => intResolve$1(str, 0, 10, opt),
1539
+ stringify: stringifyNumber
1540
+ };
1541
+ const intHex$1 = {
1542
+ identify: (value) => intIdentify$2(value) && value >= 0,
1543
+ default: true,
1544
+ tag: "tag:yaml.org,2002:int",
1545
+ format: "HEX",
1546
+ test: /^0x[0-9a-fA-F]+$/,
1547
+ resolve: (str, _onError, opt) => intResolve$1(str, 2, 16, opt),
1548
+ stringify: (node) => intStringify$1(node, 16, "0x")
1549
+ };
1550
+
1551
+ //#endregion
1552
+ //#region src/schema/core/schema.ts
1553
+ const schema$2 = [
1554
+ map,
1555
+ seq,
1556
+ string,
1557
+ nullTag,
1558
+ boolTag,
1559
+ intOct$1,
1560
+ int$1,
1561
+ intHex$1,
1562
+ floatNaN$1,
1563
+ floatExp$1,
1564
+ float$1
1565
+ ];
1566
+
1567
+ //#endregion
1568
+ //#region src/schema/json/schema.ts
1569
+ function intIdentify$1(value) {
1570
+ return typeof value === "bigint" || Number.isInteger(value);
1571
+ }
1572
+ const stringifyJSON = ({ value }) => JSON.stringify(value);
1573
+ const jsonScalars = [
1574
+ {
1575
+ identify: (value) => typeof value === "string",
1576
+ default: true,
1577
+ tag: "tag:yaml.org,2002:str",
1578
+ resolve: (str) => str,
1579
+ stringify: stringifyJSON
1580
+ },
1581
+ {
1582
+ identify: (value) => value == null,
1583
+ createNode: () => new Scalar(null),
1584
+ default: true,
1585
+ tag: "tag:yaml.org,2002:null",
1586
+ test: /^null$/,
1587
+ resolve: () => null,
1588
+ stringify: stringifyJSON
1589
+ },
1590
+ {
1591
+ identify: (value) => typeof value === "boolean",
1592
+ default: true,
1593
+ tag: "tag:yaml.org,2002:bool",
1594
+ test: /^true$|^false$/,
1595
+ resolve: (str) => str === "true",
1596
+ stringify: stringifyJSON
1597
+ },
1598
+ {
1599
+ identify: intIdentify$1,
1600
+ default: true,
1601
+ tag: "tag:yaml.org,2002:int",
1602
+ test: /^-?(?:0|[1-9][0-9]*)$/,
1603
+ resolve: (str, _onError, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str, 10),
1604
+ stringify: ({ value }) => intIdentify$1(value) ? value.toString() : JSON.stringify(value)
1605
+ },
1606
+ {
1607
+ identify: (value) => typeof value === "number",
1608
+ default: true,
1609
+ tag: "tag:yaml.org,2002:float",
1610
+ test: /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$/,
1611
+ resolve: (str) => parseFloat(str),
1612
+ stringify: stringifyJSON
1613
+ }
1614
+ ];
1615
+ const jsonError = {
1616
+ default: true,
1617
+ tag: "",
1618
+ test: /^/,
1619
+ resolve(str, onError) {
1620
+ onError(`Unresolved plain scalar ${JSON.stringify(str)}`);
1621
+ return str;
1622
+ }
1623
+ };
1624
+ const schema$1 = [
1625
+ map,
1626
+ seq,
1627
+ ...jsonScalars,
1628
+ jsonError
1629
+ ];
1630
+
1631
+ //#endregion
1632
+ //#region src/schema/yaml-1.1/binary.ts
1633
+ const binary = {
1634
+ identify: (value) => value instanceof Uint8Array,
1635
+ default: false,
1636
+ tag: "tag:yaml.org,2002:binary",
1637
+ resolve(src, onError) {
1638
+ if (typeof Buffer === "function") return Buffer.from(src, "base64");
1639
+ else if (typeof Uint8Array.fromBase64 === "function") return Uint8Array.fromBase64(src);
1640
+ else if (typeof atob === "function") {
1641
+ const str = atob(src.replace(/[\n\r]/g, ""));
1642
+ const buffer = new Uint8Array(str.length);
1643
+ for (let i = 0; i < str.length; ++i) buffer[i] = str.charCodeAt(i);
1644
+ return buffer;
1645
+ } else {
1646
+ onError("This environment does not support reading binary tags; either Buffer or atob is required");
1647
+ return src;
1648
+ }
1649
+ },
1650
+ stringify({ comment, type, value }, ctx, onComment, onChompKeep) {
1651
+ if (!value) return "";
1652
+ const buf = value;
1653
+ let str;
1654
+ if (typeof buf.toBase64 === "function") str = buf.toBase64();
1655
+ else if (typeof Buffer === "function") str = buf instanceof Buffer ? buf.toString("base64") : Buffer.from(buf.buffer).toString("base64");
1656
+ else if (typeof btoa === "function") {
1657
+ let s = "";
1658
+ for (let i = 0; i < buf.length; ++i) s += String.fromCharCode(buf[i]);
1659
+ str = btoa(s);
1660
+ } else throw new Error("This environment does not support writing binary tags; either Buffer or btoa is required");
1661
+ type ??= Scalar.BLOCK_LITERAL;
1662
+ if (type !== Scalar.QUOTE_DOUBLE) {
1663
+ const lineWidth = Math.max(ctx.options.lineWidth - ctx.indent.length, ctx.options.minContentWidth);
1664
+ const n = Math.ceil(str.length / lineWidth);
1665
+ const lines = new Array(n);
1666
+ for (let i = 0, o = 0; i < n; ++i, o += lineWidth) lines[i] = str.substr(o, lineWidth);
1667
+ str = lines.join(type === Scalar.BLOCK_LITERAL ? "\n" : " ");
1668
+ }
1669
+ return stringifyString({
1670
+ comment,
1671
+ type,
1672
+ value: str
1673
+ }, ctx, onComment, onChompKeep);
1674
+ }
1675
+ };
1676
+
1677
+ //#endregion
1678
+ //#region src/schema/yaml-1.1/pairs.ts
1679
+ function resolvePairs(seq, onError) {
1680
+ if (seq instanceof YAMLSeq) for (let i = 0; i < seq.items.length; ++i) {
1681
+ const item = seq.items[i];
1682
+ if (item instanceof Pair) continue;
1683
+ else if (item instanceof YAMLMap) {
1684
+ if (item.items.length > 1) onError("Each pair must have its own sequence indicator");
1685
+ const pair = item.items[0] || new Pair(new Scalar(null));
1686
+ if (item.commentBefore) pair.key.commentBefore = pair.key.commentBefore ? `${item.commentBefore}\n${pair.key.commentBefore}` : item.commentBefore;
1687
+ if (item.comment) {
1688
+ const cn = pair.value ?? pair.key;
1689
+ cn.comment = cn.comment ? `${item.comment}\n${cn.comment}` : item.comment;
1690
+ }
1691
+ seq.items[i] = pair;
1692
+ } else seq.items[i] = new Pair(item, null);
1693
+ }
1694
+ else onError("Expected a sequence for this tag");
1695
+ return seq;
1696
+ }
1697
+ function createPairs(nc, iterable) {
1698
+ const pairs = new YAMLSeq(nc.schema);
1699
+ pairs.tag = "tag:yaml.org,2002:pairs";
1700
+ let i = 0;
1701
+ if (iterable && Symbol.iterator in Object(iterable)) for (let it of iterable) {
1702
+ if (typeof nc.replacer === "function") it = nc.replacer.call(iterable, String(i++), it);
1703
+ let key, value;
1704
+ if (Array.isArray(it)) if (it.length === 2) {
1705
+ key = it[0];
1706
+ value = it[1];
1707
+ } else throw new TypeError(`Expected [key, value] tuple: ${it}`);
1708
+ else if (it && it instanceof Object) {
1709
+ const keys = Object.keys(it);
1710
+ if (keys.length === 1) {
1711
+ key = keys[0];
1712
+ value = it[key];
1713
+ } else throw new TypeError(`Expected tuple with one key, not ${keys.length} keys`);
1714
+ } else key = it;
1715
+ pairs.items.push(nc.createPair(key, value));
1716
+ }
1717
+ return pairs;
1718
+ }
1719
+ const pairs = {
1720
+ collection: "seq",
1721
+ default: false,
1722
+ tag: "tag:yaml.org,2002:pairs",
1723
+ resolve: resolvePairs,
1724
+ createNode: createPairs
1725
+ };
1726
+
1727
+ //#endregion
1728
+ //#region src/schema/yaml-1.1/omap.ts
1729
+ var YAMLOMap = class YAMLOMap extends YAMLSeq {
1730
+ static tag = "tag:yaml.org,2002:omap";
1731
+ constructor(schema) {
1732
+ super(schema);
1733
+ this.tag = YAMLOMap.tag;
1734
+ }
1735
+ add = YAMLMap.prototype.add.bind(this);
1736
+ delete = YAMLMap.prototype.delete.bind(this);
1737
+ get = YAMLMap.prototype.get.bind(this);
1738
+ has = YAMLMap.prototype.has.bind(this);
1739
+ set = YAMLMap.prototype.set.bind(this);
1740
+ /**
1741
+ * If `ctx` is given, the return type is actually `Map<unknown, unknown>`,
1742
+ * but TypeScript won't allow widening the signature of a child method.
1743
+ */
1744
+ toJSON(_, ctx) {
1745
+ if (!ctx) return super.toJSON(_);
1746
+ const map = /* @__PURE__ */ new Map();
1747
+ if (ctx?.onCreate) ctx.onCreate(map);
1748
+ for (const pair of this.items) {
1749
+ let key, value;
1750
+ if (pair instanceof Pair) {
1751
+ key = toJS(pair.key, "", ctx);
1752
+ value = toJS(pair.value, key, ctx);
1753
+ } else key = toJS(pair, "", ctx);
1754
+ if (map.has(key)) throw new Error("Ordered maps must not include duplicate keys");
1755
+ map.set(key, value);
1756
+ }
1757
+ return map;
1758
+ }
1759
+ static from(nc, iterable) {
1760
+ const pairs = createPairs(nc, iterable);
1761
+ const omap = new this(nc.schema);
1762
+ omap.items = pairs.items;
1763
+ return omap;
1764
+ }
1765
+ };
1766
+ const omap = {
1767
+ collection: "seq",
1768
+ identify: (value) => value instanceof Map,
1769
+ nodeClass: YAMLOMap,
1770
+ default: false,
1771
+ tag: "tag:yaml.org,2002:omap",
1772
+ resolve(seq, onError) {
1773
+ const pairs = resolvePairs(seq, onError);
1774
+ const seenKeys = [];
1775
+ for (const { key } of pairs.items) if (key instanceof Scalar) if (seenKeys.includes(key.value)) onError(`Ordered maps must not include duplicate keys: ${key.value}`);
1776
+ else seenKeys.push(key.value);
1777
+ return Object.assign(new YAMLOMap(), pairs);
1778
+ }
1779
+ };
1780
+
1781
+ //#endregion
1782
+ //#region src/schema/yaml-1.1/bool.ts
1783
+ function boolStringify({ value, source }, ctx) {
1784
+ if (source && (value ? trueTag : falseTag).test.test(source)) return source;
1785
+ return value ? ctx.options.trueStr : ctx.options.falseStr;
1786
+ }
1787
+ const trueTag = {
1788
+ identify: (value) => value === true,
1789
+ default: true,
1790
+ tag: "tag:yaml.org,2002:bool",
1791
+ test: /^(?:Y|y|[Yy]es|YES|[Tt]rue|TRUE|[Oo]n|ON)$/,
1792
+ resolve: () => new Scalar(true),
1793
+ stringify: boolStringify
1794
+ };
1795
+ const falseTag = {
1796
+ identify: (value) => value === false,
1797
+ default: true,
1798
+ tag: "tag:yaml.org,2002:bool",
1799
+ test: /^(?:N|n|[Nn]o|NO|[Ff]alse|FALSE|[Oo]ff|OFF)$/,
1800
+ resolve: () => new Scalar(false),
1801
+ stringify: boolStringify
1802
+ };
1803
+
1804
+ //#endregion
1805
+ //#region src/schema/yaml-1.1/float.ts
1806
+ const floatNaN = {
1807
+ identify: (value) => typeof value === "number",
1808
+ default: true,
1809
+ tag: "tag:yaml.org,2002:float",
1810
+ test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
1811
+ resolve: (str) => str.slice(-3).toLowerCase() === "nan" ? NaN : str[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,
1812
+ stringify: stringifyNumber
1813
+ };
1814
+ const floatExp = {
1815
+ identify: (value) => typeof value === "number",
1816
+ default: true,
1817
+ tag: "tag:yaml.org,2002:float",
1818
+ format: "EXP",
1819
+ test: /^[-+]?(?:[0-9][0-9_]*)?(?:\.[0-9_]*)?[eE][-+]?[0-9]+$/,
1820
+ resolve: (str) => parseFloat(str.replace(/_/g, "")),
1821
+ stringify(node) {
1822
+ const num = Number(node.value);
1823
+ return isFinite(num) ? num.toExponential() : stringifyNumber(node);
1824
+ }
1825
+ };
1826
+ const float = {
1827
+ identify: (value) => typeof value === "number",
1828
+ default: true,
1829
+ tag: "tag:yaml.org,2002:float",
1830
+ test: /^[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*$/,
1831
+ resolve(str) {
1832
+ const node = new Scalar(parseFloat(str.replace(/_/g, "")));
1833
+ const dot = str.indexOf(".");
1834
+ if (dot !== -1) {
1835
+ const f = str.substring(dot + 1).replace(/_/g, "");
1836
+ if (f[f.length - 1] === "0") node.minFractionDigits = f.length;
1837
+ }
1838
+ return node;
1839
+ },
1840
+ stringify: stringifyNumber
1841
+ };
1842
+
1843
+ //#endregion
1844
+ //#region src/schema/yaml-1.1/int.ts
1845
+ const intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
1846
+ function intResolve(str, offset, radix, { intAsBigInt }) {
1847
+ const sign = str[0];
1848
+ if (sign === "-" || sign === "+") offset += 1;
1849
+ str = str.substring(offset).replace(/_/g, "");
1850
+ if (intAsBigInt) {
1851
+ switch (radix) {
1852
+ case 2:
1853
+ str = `0b${str}`;
1854
+ break;
1855
+ case 8:
1856
+ str = `0o${str}`;
1857
+ break;
1858
+ case 16:
1859
+ str = `0x${str}`;
1860
+ break;
1861
+ }
1862
+ const n = BigInt(str);
1863
+ return sign === "-" ? BigInt(-1) * n : n;
1864
+ }
1865
+ const n = parseInt(str, radix);
1866
+ return sign === "-" ? -1 * n : n;
1867
+ }
1868
+ function intStringify(node, radix, prefix) {
1869
+ const { value } = node;
1870
+ if (intIdentify(value)) {
1871
+ const str = value.toString(radix);
1872
+ return value < 0 ? "-" + prefix + str.substr(1) : prefix + str;
1873
+ }
1874
+ return stringifyNumber(node);
1875
+ }
1876
+ const intBin = {
1877
+ identify: intIdentify,
1878
+ default: true,
1879
+ tag: "tag:yaml.org,2002:int",
1880
+ format: "BIN",
1881
+ test: /^[-+]?0b[0-1_]+$/,
1882
+ resolve: (str, _onError, opt) => intResolve(str, 2, 2, opt),
1883
+ stringify: (node) => intStringify(node, 2, "0b")
1884
+ };
1885
+ const intOct = {
1886
+ identify: intIdentify,
1887
+ default: true,
1888
+ tag: "tag:yaml.org,2002:int",
1889
+ format: "OCT",
1890
+ test: /^[-+]?0[0-7_]+$/,
1891
+ resolve: (str, _onError, opt) => intResolve(str, 1, 8, opt),
1892
+ stringify: (node) => intStringify(node, 8, "0")
1893
+ };
1894
+ const int = {
1895
+ identify: intIdentify,
1896
+ default: true,
1897
+ tag: "tag:yaml.org,2002:int",
1898
+ test: /^[-+]?[0-9][0-9_]*$/,
1899
+ resolve: (str, _onError, opt) => intResolve(str, 0, 10, opt),
1900
+ stringify: stringifyNumber
1901
+ };
1902
+ const intHex = {
1903
+ identify: intIdentify,
1904
+ default: true,
1905
+ tag: "tag:yaml.org,2002:int",
1906
+ format: "HEX",
1907
+ test: /^[-+]?0x[0-9a-fA-F_]+$/,
1908
+ resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),
1909
+ stringify: (node) => intStringify(node, 16, "0x")
1910
+ };
1911
+
1912
+ //#endregion
1913
+ //#region src/schema/yaml-1.1/set.ts
1914
+ var YAMLSet = class YAMLSet extends YAMLMap {
1915
+ static tag = "tag:yaml.org,2002:set";
1916
+ constructor(schema) {
1917
+ super(schema);
1918
+ this.tag = YAMLSet.tag;
1919
+ }
1920
+ /**
1921
+ * Add a value to the set.
1922
+ *
1923
+ * If `value` is a Pair, its `.value` must be null and `options` is ignored.
1924
+ *
1925
+ * If the set already includes a matching value, no value is added.
1926
+ */
1927
+ add(value, options) {
1928
+ if (!(value instanceof Pair)) this.set(value, true, options);
1929
+ else if (value.value !== null) throw new TypeError("set pair values must be null");
1930
+ else if (!findPair(this.items, value.key)) this.items.push(value);
1931
+ }
1932
+ /**
1933
+ * Returns the value matching `key`.
1934
+ */
1935
+ get(key) {
1936
+ return findPair(this.items, key)?.key;
1937
+ }
1938
+ /**
1939
+ * `value` needs to be true/false to add/remove the item from the set.
1940
+ */
1941
+ set(key, value, options) {
1942
+ if (typeof value !== "boolean") throw new Error(`Expected a boolean value, not ${typeof value}`);
1943
+ const prev = findPair(this.items, key);
1944
+ if (prev && !value) this.items.splice(this.items.indexOf(prev), 1);
1945
+ else if (!prev && value) {
1946
+ let node;
1947
+ if (key instanceof NodeBase) node = key;
1948
+ else if (!this.schema) throw new Error("Schema is required");
1949
+ else {
1950
+ const nc = new NodeCreator(this.schema, {
1951
+ ...options,
1952
+ aliasDuplicateObjects: false
1953
+ });
1954
+ node = nc.create(key);
1955
+ nc.setAnchors();
1956
+ }
1957
+ this.items.push(new Pair(node));
1958
+ }
1959
+ }
1960
+ toJSON(_, ctx) {
1961
+ return super.toJSON(_, ctx, Set);
1962
+ }
1963
+ toString(ctx, onComment, onChompKeep) {
1964
+ if (!ctx) return JSON.stringify(this);
1965
+ return super.toString({
1966
+ ...ctx,
1967
+ noValues: true
1968
+ }, onComment, onChompKeep);
1969
+ }
1970
+ static from(nc, iterable) {
1971
+ const set = new this(nc.schema);
1972
+ if (iterable && Symbol.iterator in Object(iterable)) for (let value of iterable) {
1973
+ if (typeof nc.replacer === "function") value = nc.replacer.call(iterable, value, value);
1974
+ set.items.push(nc.createPair(value, null));
1975
+ }
1976
+ return set;
1977
+ }
1978
+ };
1979
+ const hasAllNullValues = (map) => map.items.every(({ value }) => value == null || value instanceof Scalar && value.value == null && !value.commentBefore && !value.comment && !value.tag);
1980
+ const set = {
1981
+ collection: "map",
1982
+ identify: (value) => value instanceof Set,
1983
+ nodeClass: YAMLSet,
1984
+ default: false,
1985
+ tag: "tag:yaml.org,2002:set",
1986
+ resolve(map, onError) {
1987
+ if (!(map instanceof YAMLMap)) {
1988
+ onError("Expected a mapping for this tag");
1989
+ return map;
1990
+ } else if (!hasAllNullValues(map)) {
1991
+ onError("Set items must all have null values");
1992
+ return map;
1993
+ } else {
1994
+ const set = Object.assign(new YAMLSet(), map);
1995
+ for (const pair of map.items) pair.value &&= null;
1996
+ return set;
1997
+ }
1998
+ }
1999
+ };
2000
+
2001
+ //#endregion
2002
+ //#region src/schema/yaml-1.1/timestamp.ts
2003
+ /** Internal types handle bigint as number, because TS can't figure it out. */
2004
+ function parseSexagesimal(str, asBigInt) {
2005
+ const sign = str[0];
2006
+ const parts = sign === "-" || sign === "+" ? str.substring(1) : str;
2007
+ const num = (n) => asBigInt ? BigInt(n) : Number(n);
2008
+ const res = parts.replace(/_/g, "").split(":").reduce((res, p) => res * num(60) + num(p), num(0));
2009
+ return sign === "-" ? num(-1) * res : res;
2010
+ }
2011
+ /**
2012
+ * hhhh:mm:ss.sss
2013
+ *
2014
+ * Internal types handle bigint as number, because TS can't figure it out.
2015
+ */
2016
+ function stringifySexagesimal(node) {
2017
+ let { value } = node;
2018
+ let num = (n) => n;
2019
+ if (typeof value === "bigint") num = (n) => BigInt(n);
2020
+ else if (isNaN(value) || !isFinite(value)) return stringifyNumber(node);
2021
+ let sign = "";
2022
+ if (value < 0) {
2023
+ sign = "-";
2024
+ value *= num(-1);
2025
+ }
2026
+ const _60 = num(60);
2027
+ const parts = [value % _60];
2028
+ if (value < 60) parts.unshift(0);
2029
+ else {
2030
+ value = (value - parts[0]) / _60;
2031
+ parts.unshift(value % _60);
2032
+ if (value >= 60) {
2033
+ value = (value - parts[0]) / _60;
2034
+ parts.unshift(value);
2035
+ }
2036
+ }
2037
+ return sign + parts.map((n) => String(n).padStart(2, "0")).join(":").replace(/000000\d*$/, "");
2038
+ }
2039
+ const intTime = {
2040
+ identify: (value) => typeof value === "bigint" || Number.isInteger(value),
2041
+ default: true,
2042
+ tag: "tag:yaml.org,2002:int",
2043
+ format: "TIME",
2044
+ test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+$/,
2045
+ resolve: (str, _onError, { intAsBigInt }) => parseSexagesimal(str, intAsBigInt),
2046
+ stringify: stringifySexagesimal
2047
+ };
2048
+ const floatTime = {
2049
+ identify: (value) => typeof value === "number",
2050
+ default: true,
2051
+ tag: "tag:yaml.org,2002:float",
2052
+ format: "TIME",
2053
+ test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*$/,
2054
+ resolve: (str) => parseSexagesimal(str, false),
2055
+ stringify: stringifySexagesimal
2056
+ };
2057
+ const timestamp = {
2058
+ identify: (value) => value instanceof Date,
2059
+ default: true,
2060
+ tag: "tag:yaml.org,2002:timestamp",
2061
+ test: RegExp("^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})(?:(?:t|T|[ \\t]+)([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}(\\.[0-9]+)?)(?:[ \\t]*(Z|[-+][012]?[0-9](?::[0-9]{2})?))?)?$"),
2062
+ resolve(str) {
2063
+ const match = str.match(timestamp.test);
2064
+ if (!match) throw new Error("!!timestamp expects a date, starting with yyyy-mm-dd");
2065
+ const [, year, month, day, hour, minute, second] = match.map(Number);
2066
+ const millisec = match[7] ? Number((match[7] + "00").substr(1, 3)) : 0;
2067
+ let date = Date.UTC(year, month - 1, day, hour || 0, minute || 0, second || 0, millisec);
2068
+ const tz = match[8];
2069
+ if (tz && tz !== "Z") {
2070
+ let d = parseSexagesimal(tz, false);
2071
+ if (Math.abs(d) < 30) d *= 60;
2072
+ date -= 6e4 * d;
2073
+ }
2074
+ return new Date(date);
2075
+ },
2076
+ stringify: ({ value }) => value?.toISOString().replace(/(T00:00:00)?\.000Z$/, "") ?? ""
2077
+ };
2078
+
2079
+ //#endregion
2080
+ //#region src/schema/yaml-1.1/schema.ts
2081
+ const schema = [
2082
+ map,
2083
+ seq,
2084
+ string,
2085
+ nullTag,
2086
+ trueTag,
2087
+ falseTag,
2088
+ intBin,
2089
+ intOct,
2090
+ int,
2091
+ intHex,
2092
+ floatNaN,
2093
+ floatExp,
2094
+ float,
2095
+ binary,
2096
+ merge,
2097
+ omap,
2098
+ pairs,
2099
+ set,
2100
+ intTime,
2101
+ floatTime,
2102
+ timestamp
2103
+ ];
2104
+
2105
+ //#endregion
2106
+ //#region src/schema/tags.ts
2107
+ const schemas = new Map([
2108
+ ["core", schema$2],
2109
+ ["failsafe", [
2110
+ map,
2111
+ seq,
2112
+ string
2113
+ ]],
2114
+ ["json", schema$1],
2115
+ ["yaml11", schema],
2116
+ ["yaml-1.1", schema]
2117
+ ]);
2118
+ const tagsByName = {
2119
+ binary,
2120
+ bool: boolTag,
2121
+ float: float$1,
2122
+ floatExp: floatExp$1,
2123
+ floatNaN: floatNaN$1,
2124
+ floatTime,
2125
+ int: int$1,
2126
+ intHex: intHex$1,
2127
+ intOct: intOct$1,
2128
+ intTime,
2129
+ map,
2130
+ merge,
2131
+ null: nullTag,
2132
+ omap,
2133
+ pairs,
2134
+ seq,
2135
+ set,
2136
+ timestamp
2137
+ };
2138
+ const coreKnownTags = {
2139
+ "tag:yaml.org,2002:binary": binary,
2140
+ "tag:yaml.org,2002:merge": merge,
2141
+ "tag:yaml.org,2002:omap": omap,
2142
+ "tag:yaml.org,2002:pairs": pairs,
2143
+ "tag:yaml.org,2002:set": set,
2144
+ "tag:yaml.org,2002:timestamp": timestamp
2145
+ };
2146
+ function getTags(customTags, schemaName, addMergeTag) {
2147
+ const schemaTags = schemas.get(schemaName);
2148
+ if (schemaTags && !customTags) return addMergeTag && !schemaTags.includes(merge) ? schemaTags.concat(merge) : schemaTags.slice();
2149
+ let tags = schemaTags;
2150
+ if (!tags) if (Array.isArray(customTags)) tags = [];
2151
+ else {
2152
+ const keys = Array.from(schemas.keys()).filter((key) => key !== "yaml11").map((key) => JSON.stringify(key)).join(", ");
2153
+ throw new Error(`Unknown schema "${schemaName}"; use one of ${keys} or define customTags array`);
2154
+ }
2155
+ if (Array.isArray(customTags)) for (const tag of customTags) tags = tags.concat(tag);
2156
+ else if (typeof customTags === "function") tags = customTags(tags.slice());
2157
+ if (addMergeTag) tags = tags.concat(merge);
2158
+ return tags.reduce((tags, tag) => {
2159
+ const tagObj = typeof tag === "string" ? tagsByName[tag] : tag;
2160
+ if (!tagObj) {
2161
+ const tagName = JSON.stringify(tag);
2162
+ const keys = Object.keys(tagsByName).map((key) => JSON.stringify(key)).join(", ");
2163
+ throw new Error(`Unknown custom tag ${tagName}; use one of ${keys}`);
2164
+ }
2165
+ if (!tags.includes(tagObj)) tags.push(tagObj);
2166
+ return tags;
2167
+ }, []);
2168
+ }
2169
+
2170
+ //#endregion
2171
+ //#region src/schema/Schema.ts
2172
+ const sortMapEntriesByKey = (a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0;
2173
+ var Schema = class Schema {
2174
+ compat;
2175
+ knownTags;
2176
+ name;
2177
+ sortMapEntries;
2178
+ tags;
2179
+ toStringOptions;
2180
+ constructor({ compat, customTags, merge, resolveKnownTags, schema, sortMapEntries, toStringDefaults }) {
2181
+ this.compat = Array.isArray(compat) ? getTags(compat, "compat") : compat ? getTags(null, compat) : null;
2182
+ this.name = typeof schema === "string" && schema || "core";
2183
+ this.knownTags = resolveKnownTags ? coreKnownTags : {};
2184
+ this.tags = getTags(customTags, this.name, merge);
2185
+ this.toStringOptions = toStringDefaults ?? null;
2186
+ Object.defineProperty(this, "map", { value: map });
2187
+ Object.defineProperty(this, "scalar", { value: string });
2188
+ Object.defineProperty(this, "seq", { value: seq });
2189
+ this.sortMapEntries = typeof sortMapEntries === "function" ? sortMapEntries : sortMapEntries === true ? sortMapEntriesByKey : null;
2190
+ }
2191
+ clone() {
2192
+ const copy = Object.create(Schema.prototype, Object.getOwnPropertyDescriptors(this));
2193
+ copy.tags = this.tags.slice();
2194
+ return copy;
2195
+ }
2196
+ };
2197
+
2198
+ //#endregion
2199
+ //#region src/stringify/stringifyDocument.ts
2200
+ function stringifyDocument(doc, options) {
2201
+ const lines = [];
2202
+ let hasDirectives = options.directives === true;
2203
+ if (options.directives !== false && doc.directives) {
2204
+ const dir = doc.directives.toString(doc);
2205
+ if (dir) {
2206
+ lines.push(dir);
2207
+ hasDirectives = true;
2208
+ } else if (doc.directives.docStart) hasDirectives = true;
2209
+ }
2210
+ if (hasDirectives) lines.push("---");
2211
+ const ctx = createStringifyContext(doc, options);
2212
+ const { commentString } = ctx.options;
2213
+ if (doc.commentBefore) {
2214
+ if (lines.length !== 1) lines.unshift("");
2215
+ const cs = commentString(doc.commentBefore);
2216
+ lines.unshift(indentComment(cs, ""));
2217
+ }
2218
+ let chompKeep = false;
2219
+ let contentComment = null;
2220
+ if (doc.value.spaceBefore && hasDirectives) lines.push("");
2221
+ if (doc.value.commentBefore) {
2222
+ const cs = commentString(doc.value.commentBefore);
2223
+ lines.push(indentComment(cs, ""));
2224
+ }
2225
+ ctx.forceBlockIndent = !!doc.comment;
2226
+ contentComment = doc.value.comment;
2227
+ const onChompKeep = contentComment ? void 0 : () => chompKeep = true;
2228
+ let body = stringify(doc.value, ctx, () => contentComment = null, onChompKeep);
2229
+ if (contentComment) body += lineComment(body, "", commentString(contentComment));
2230
+ if ((body[0] === "|" || body[0] === ">") && lines[lines.length - 1] === "---") lines[lines.length - 1] = `--- ${body}`;
2231
+ else lines.push(body);
2232
+ if (doc.directives?.docEnd) if (doc.comment) {
2233
+ const cs = commentString(doc.comment);
2234
+ if (cs.includes("\n")) {
2235
+ lines.push("...");
2236
+ lines.push(indentComment(cs, ""));
2237
+ } else lines.push(`... ${cs}`);
2238
+ } else lines.push("...");
2239
+ else {
2240
+ let dc = doc.comment;
2241
+ if (dc && chompKeep) dc = dc.replace(/^\n+/, "");
2242
+ if (dc) {
2243
+ if ((!chompKeep || contentComment) && lines[lines.length - 1] !== "") lines.push("");
2244
+ lines.push(indentComment(commentString(dc), ""));
2245
+ }
2246
+ }
2247
+ return lines.join("\n") + "\n";
2248
+ }
2249
+
2250
+ //#endregion
2251
+ //#region src/doc/Document.ts
2252
+ var Document = class Document {
2253
+ /** A comment before this Document */
2254
+ commentBefore = null;
2255
+ /** A comment immediately after this Document */
2256
+ comment = null;
2257
+ /** The document value. */
2258
+ value;
2259
+ directives;
2260
+ /** Errors encountered during parsing. */
2261
+ errors = [];
2262
+ options;
2263
+ /** Warnings encountered during parsing. */
2264
+ warnings = [];
2265
+ constructor(value, replacer, options) {
2266
+ let _replacer = null;
2267
+ if (typeof replacer === "function" || Array.isArray(replacer)) _replacer = replacer;
2268
+ else if (options === void 0 && replacer) {
2269
+ options = replacer;
2270
+ replacer = void 0;
2271
+ }
2272
+ const opt = Object.assign({
2273
+ intAsBigInt: false,
2274
+ keepSourceTokens: false,
2275
+ logLevel: "warn",
2276
+ prettyErrors: true,
2277
+ strict: true,
2278
+ stringKeys: false,
2279
+ uniqueKeys: true,
2280
+ version: "1.2"
2281
+ }, options);
2282
+ this.options = opt;
2283
+ let { version } = opt;
2284
+ if (options?._directives) {
2285
+ this.directives = options._directives.atDocument();
2286
+ if (this.directives.yaml.explicit) version = this.directives.yaml.version;
2287
+ } else this.directives = new Directives({ version });
2288
+ this.setSchema(version, options);
2289
+ this.value = this.createNode(value, _replacer, options);
2290
+ }
2291
+ /**
2292
+ * Create a deep copy of this Document and its value.
2293
+ *
2294
+ * Custom Node values that inherit from `Object` still refer to their original instances.
2295
+ */
2296
+ clone() {
2297
+ const copy = Object.create(Document.prototype);
2298
+ copy.commentBefore = this.commentBefore;
2299
+ copy.comment = this.comment;
2300
+ copy.errors = this.errors.slice();
2301
+ copy.warnings = this.warnings.slice();
2302
+ copy.options = Object.assign({}, this.options);
2303
+ if (this.directives) copy.directives = this.directives.clone();
2304
+ copy.schema = this.schema.clone();
2305
+ copy.value = this.value.clone(copy.schema);
2306
+ if (this.range) copy.range = this.range.slice();
2307
+ return copy;
2308
+ }
2309
+ /** Adds a value to the document. */
2310
+ add(value) {
2311
+ assertCollection(this.value).add(value);
2312
+ }
2313
+ /** Adds a value to the document. */
2314
+ addIn(path, value) {
2315
+ assertCollection(this.value).addIn(path, value);
2316
+ }
2317
+ /**
2318
+ * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
2319
+ *
2320
+ * If `node` already has an anchor, `name` is ignored.
2321
+ * Otherwise, the `node.anchor` value will be set to `name`,
2322
+ * or if an anchor with that name is already present in the document,
2323
+ * `name` will be used as a prefix for a new unique anchor.
2324
+ * If `name` is undefined, the generated anchor will use 'a' as a prefix.
2325
+ */
2326
+ createAlias(node, name) {
2327
+ if (!node.anchor) {
2328
+ const prev = anchorNames(this);
2329
+ node.anchor = !name || prev.has(name) ? findNewAnchor(name || "a", prev) : name;
2330
+ }
2331
+ return new Alias(node.anchor);
2332
+ }
2333
+ createNode(value, replacer, options) {
2334
+ let nc;
2335
+ if (typeof replacer === "function") {
2336
+ value = replacer.call({ "": value }, "", value);
2337
+ nc = new NodeCreator(this, options, replacer);
2338
+ } else if (Array.isArray(replacer)) {
2339
+ const keyToStr = (v) => typeof v === "number" || v instanceof String || v instanceof Number;
2340
+ const asStr = replacer.filter(keyToStr).map(String);
2341
+ if (asStr.length > 0) replacer = replacer.concat(asStr);
2342
+ nc = new NodeCreator(this, options, replacer);
2343
+ } else {
2344
+ options ??= replacer ?? void 0;
2345
+ nc = new NodeCreator(this, options);
2346
+ }
2347
+ const node = nc.create(value, options?.tag);
2348
+ nc.setAnchors();
2349
+ return node;
2350
+ }
2351
+ /**
2352
+ * Convert a key and a value into a `Pair` using the current schema,
2353
+ * recursively wrapping all values as `Scalar` or `Collection` nodes.
2354
+ */
2355
+ createPair(key, value, options = {}) {
2356
+ const nc = new NodeCreator(this, options);
2357
+ const pair = nc.createPair(key, value);
2358
+ nc.setAnchors();
2359
+ return pair;
2360
+ }
2361
+ /**
2362
+ * Removes a value from the document.
2363
+ * @returns `true` if the item was found and removed.
2364
+ */
2365
+ delete(key) {
2366
+ return assertCollection(this.value).delete(key);
2367
+ }
2368
+ /**
2369
+ * Removes a value from the document.
2370
+ * @returns `true` if the item was found and removed.
2371
+ */
2372
+ deleteIn(path) {
2373
+ if (!path.length) {
2374
+ this.value = new Scalar(null);
2375
+ return true;
2376
+ }
2377
+ return assertCollection(this.value).deleteIn(path);
2378
+ }
2379
+ /**
2380
+ * Returns item at `key`, or `undefined` if not found.
2381
+ */
2382
+ get(key) {
2383
+ return this.value instanceof Collection ? this.value.get(key) : void 0;
2384
+ }
2385
+ /**
2386
+ * Returns item at `path`, or `undefined` if not found.
2387
+ */
2388
+ getIn(path) {
2389
+ if (!path.length) return this.value;
2390
+ return this.value instanceof Collection ? this.value.getIn(path) : void 0;
2391
+ }
2392
+ /**
2393
+ * Checks if the document includes a value with the key `key`.
2394
+ */
2395
+ has(key) {
2396
+ return this.value instanceof Collection ? this.value.has(key) : false;
2397
+ }
2398
+ /**
2399
+ * Checks if the document includes a value at `path`.
2400
+ */
2401
+ hasIn(path) {
2402
+ if (!path.length) return true;
2403
+ return this.value instanceof Collection ? this.value.hasIn(path) : false;
2404
+ }
2405
+ /**
2406
+ * Sets a value in this document. For `!!set`, `value` needs to be a
2407
+ * boolean to add/remove the item from the set.
2408
+ */
2409
+ set(key, value) {
2410
+ assertCollection(this.value).set(key, value);
2411
+ }
2412
+ /**
2413
+ * Sets a value in this document. For `!!set`, `value` needs to be a
2414
+ * boolean to add/remove the item from the set.
2415
+ */
2416
+ setIn(path, value) {
2417
+ if (!path.length) this.value = value;
2418
+ else assertCollection(this.value).setIn(path, value);
2419
+ }
2420
+ /**
2421
+ * Change the YAML version and schema used by the document.
2422
+ * A `null` version disables support for directives, explicit tags, anchors, and aliases.
2423
+ * It also requires the `schema` option to be given as a `Schema` instance value.
2424
+ *
2425
+ * Overrides all previously set schema options.
2426
+ */
2427
+ setSchema(version, options = {}) {
2428
+ if (typeof version === "number") version = String(version);
2429
+ let opt;
2430
+ switch (version) {
2431
+ case "1.1":
2432
+ if (this.directives) this.directives.yaml.version = "1.1";
2433
+ else this.directives = new Directives({ version: "1.1" });
2434
+ opt = {
2435
+ resolveKnownTags: false,
2436
+ schema: "yaml-1.1"
2437
+ };
2438
+ break;
2439
+ case "1.2":
2440
+ case "next":
2441
+ if (this.directives) this.directives.yaml.version = version;
2442
+ else this.directives = new Directives({ version });
2443
+ opt = {
2444
+ resolveKnownTags: true,
2445
+ schema: "core"
2446
+ };
2447
+ break;
2448
+ case null:
2449
+ if (this.directives) delete this.directives;
2450
+ opt = null;
2451
+ break;
2452
+ default: {
2453
+ const sv = JSON.stringify(version);
2454
+ throw new Error(`Expected '1.1', '1.2' or null as first argument, but found: ${sv}`);
2455
+ }
2456
+ }
2457
+ if (options.schema instanceof Object) this.schema = options.schema;
2458
+ else if (opt) this.schema = new Schema(Object.assign(opt, options));
2459
+ else throw new Error(`With a null YAML version, the { schema: Schema } option is required`);
2460
+ }
2461
+ toJS({ json, jsonArg, mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {
2462
+ const ctx = {
2463
+ anchors: /* @__PURE__ */ new Map(),
2464
+ doc: this,
2465
+ keep: !json,
2466
+ mapAsMap: mapAsMap === true,
2467
+ mapKeyWarned: false,
2468
+ maxAliasCount: typeof maxAliasCount === "number" ? maxAliasCount : 100
2469
+ };
2470
+ const res = toJS(this.value, jsonArg ?? "", ctx);
2471
+ if (typeof onAnchor === "function") for (const { count, res } of ctx.anchors.values()) onAnchor(res, count);
2472
+ return typeof reviver === "function" ? applyReviver(reviver, { "": res }, "", res) : res;
2473
+ }
2474
+ /**
2475
+ * A JSON representation of the document `value`.
2476
+ *
2477
+ * @param jsonArg Used by `JSON.stringify` to indicate the array index or
2478
+ * property name.
2479
+ */
2480
+ toJSON(jsonArg, onAnchor) {
2481
+ return this.toJS({
2482
+ json: true,
2483
+ jsonArg,
2484
+ mapAsMap: false,
2485
+ onAnchor
2486
+ });
2487
+ }
2488
+ /** A YAML representation of the document. */
2489
+ toString(options = {}) {
2490
+ if (this.errors.length > 0) throw new Error("Document with errors cannot be stringified");
2491
+ if ("indent" in options && (!Number.isInteger(options.indent) || Number(options.indent) <= 0)) {
2492
+ const s = JSON.stringify(options.indent);
2493
+ throw new Error(`"indent" option must be a positive integer, not ${s}`);
2494
+ }
2495
+ return stringifyDocument(this, options);
2496
+ }
2497
+ };
2498
+ function assertCollection(value) {
2499
+ if (value instanceof Collection) return value;
2500
+ throw new Error("Expected a YAML collection as document value");
2501
+ }
2502
+
2503
+ //#endregion
2504
+ //#region src/visit.ts
2505
+ const BREAK = Symbol("break visit");
2506
+ const SKIP = Symbol("skip children");
2507
+ const REMOVE = Symbol("remove node");
2508
+ /**
2509
+ * Apply a visitor to an AST node or document.
2510
+ *
2511
+ * Walks through the tree (depth-first) starting from `node`, calling a
2512
+ * `visitor` function with three arguments:
2513
+ * - `key`: For sequence values and map `Pair`, the node's index in the
2514
+ * collection. Within a `Pair`, `'key'` or `'value'`, correspondingly.
2515
+ * `null` for the root node.
2516
+ * - `node`: The current node.
2517
+ * - `path`: The ancestry of the current node.
2518
+ *
2519
+ * The return value of the visitor may be used to control the traversal:
2520
+ * - `undefined` (default): Do nothing and continue
2521
+ * - `visit.SKIP`: Do not visit the children of this node, continue with next
2522
+ * sibling
2523
+ * - `visit.BREAK`: Terminate traversal completely
2524
+ * - `visit.REMOVE`: Remove the current node, then continue with the next one
2525
+ * - `Node`: Replace the current node, then continue by visiting it
2526
+ * - `number`: While iterating the items of a sequence or map, set the index
2527
+ * of the next step. This is useful especially if the index of the current
2528
+ * node has changed.
2529
+ *
2530
+ * If `visitor` is a single function, it will be called with all values
2531
+ * encountered in the tree, including e.g. `null` values. Alternatively,
2532
+ * separate visitor functions may be defined for each `Map`, `Pair`, `Seq`,
2533
+ * `Alias` and `Scalar` node. To define the same visitor function for more than
2534
+ * one node type, use the `Collection` (map and seq), `Value` (map, seq & scalar)
2535
+ * and `Node` (alias, map, seq & scalar) targets. Of all these, only the most
2536
+ * specific defined one will be used for each node.
2537
+ */
2538
+ const visit = function visit(node, visitor) {
2539
+ const visitor_ = initVisitor(visitor);
2540
+ if (node instanceof Document) {
2541
+ if (visit_(null, node.value, visitor_, Object.freeze([node])) === REMOVE) node.value = new Scalar(null);
2542
+ } else visit_(null, node, visitor_, Object.freeze([]));
2543
+ };
2544
+ visit.BREAK = BREAK;
2545
+ visit.SKIP = SKIP;
2546
+ visit.REMOVE = REMOVE;
2547
+ function visit_(key, node, visitor, path) {
2548
+ const ctrl = callVisitor(key, node, visitor, path);
2549
+ if (ctrl instanceof NodeBase || ctrl instanceof Pair) {
2550
+ replaceNode(key, path, ctrl);
2551
+ return visit_(key, ctrl, visitor, path);
2552
+ }
2553
+ if (typeof ctrl !== "symbol") {
2554
+ if (node instanceof YAMLMap || node instanceof YAMLSeq) {
2555
+ path = Object.freeze(path.concat(node));
2556
+ for (let i = 0; i < node.items.length; ++i) {
2557
+ const ci = visit_(i, node.items[i], visitor, path);
2558
+ if (typeof ci === "number") i = ci - 1;
2559
+ else if (ci === BREAK) return BREAK;
2560
+ else if (ci === REMOVE) {
2561
+ node.items.splice(i, 1);
2562
+ i -= 1;
2563
+ }
2564
+ }
2565
+ } else if (node instanceof Pair) {
2566
+ path = Object.freeze(path.concat(node));
2567
+ const ck = visit_("key", node.key, visitor, path);
2568
+ if (ck === BREAK) return BREAK;
2569
+ else if (ck === REMOVE) node.key = new Scalar(null);
2570
+ const cv = visit_("value", node.value, visitor, path);
2571
+ if (cv === BREAK) return BREAK;
2572
+ else if (cv === REMOVE) node.value = null;
2573
+ }
2574
+ }
2575
+ return ctrl;
2576
+ }
2577
+ /**
2578
+ * Apply an async visitor to an AST node or document.
2579
+ *
2580
+ * Walks through the tree (depth-first) starting from `node`, calling a
2581
+ * `visitor` function with three arguments:
2582
+ * - `key`: For sequence values and map `Pair`, the node's index in the
2583
+ * collection. Within a `Pair`, `'key'` or `'value'`, correspondingly.
2584
+ * `null` for the root node.
2585
+ * - `node`: The current node.
2586
+ * - `path`: The ancestry of the current node.
2587
+ *
2588
+ * The return value of the visitor may be used to control the traversal:
2589
+ * - `Promise`: Must resolve to one of the following values
2590
+ * - `undefined` (default): Do nothing and continue
2591
+ * - `visitAsync.SKIP`: Do not visit the children of this node,
2592
+ * continue with next sibling
2593
+ * - `visitAsync.BREAK`: Terminate traversal completely
2594
+ * - `visitAsync.REMOVE`: Remove the current node,
2595
+ * then continue with the next one
2596
+ * - `Node`: Replace the current node, then continue by visiting it
2597
+ * - `number`: While iterating the items of a sequence or map, set the index
2598
+ * of the next step. This is useful especially if the index of the current
2599
+ * node has changed.
2600
+ *
2601
+ * If `visitor` is a single function, it will be called with all values
2602
+ * encountered in the tree, including e.g. `null` values. Alternatively,
2603
+ * separate visitor functions may be defined for each `Map`, `Pair`, `Seq`,
2604
+ * `Alias` and `Scalar` node. To define the same visitor function for more than
2605
+ * one node type, use the `Collection` (map and seq), `Value` (map, seq & scalar)
2606
+ * and `Node` (alias, map, seq & scalar) targets. Of all these, only the most
2607
+ * specific defined one will be used for each node.
2608
+ */
2609
+ const visitAsync = async function visitAsync(node, visitor) {
2610
+ const visitor_ = initVisitor(visitor);
2611
+ if (node instanceof Document) {
2612
+ if (await visitAsync_(null, node.value, visitor_, Object.freeze([node])) === REMOVE) node.value = new Scalar(null);
2613
+ } else await visitAsync_(null, node, visitor_, Object.freeze([]));
2614
+ };
2615
+ visitAsync.BREAK = BREAK;
2616
+ visitAsync.SKIP = SKIP;
2617
+ visitAsync.REMOVE = REMOVE;
2618
+ async function visitAsync_(key, node, visitor, path) {
2619
+ const ctrl = await callVisitor(key, node, visitor, path);
2620
+ if (ctrl instanceof NodeBase || ctrl instanceof Pair) {
2621
+ replaceNode(key, path, ctrl);
2622
+ return visitAsync_(key, ctrl, visitor, path);
2623
+ }
2624
+ if (typeof ctrl !== "symbol") {
2625
+ if (node instanceof YAMLMap || node instanceof YAMLSeq) {
2626
+ path = Object.freeze(path.concat(node));
2627
+ for (let i = 0; i < node.items.length; ++i) {
2628
+ const ci = await visitAsync_(i, node.items[i], visitor, path);
2629
+ if (typeof ci === "number") i = ci - 1;
2630
+ else if (ci === BREAK) return BREAK;
2631
+ else if (ci === REMOVE) {
2632
+ node.items.splice(i, 1);
2633
+ i -= 1;
2634
+ }
2635
+ }
2636
+ } else if (node instanceof Pair) {
2637
+ path = Object.freeze(path.concat(node));
2638
+ const ck = await visitAsync_("key", node.key, visitor, path);
2639
+ if (ck === BREAK) return BREAK;
2640
+ else if (ck === REMOVE) node.key = new Scalar(null);
2641
+ const cv = await visitAsync_("value", node.value, visitor, path);
2642
+ if (cv === BREAK) return BREAK;
2643
+ else if (cv === REMOVE) node.value = null;
2644
+ }
2645
+ }
2646
+ return ctrl;
2647
+ }
2648
+ function initVisitor(visitor) {
2649
+ if (typeof visitor === "object" && (visitor.Collection || visitor.Node || visitor.Value)) return Object.assign({
2650
+ Alias: visitor.Node,
2651
+ Map: visitor.Node,
2652
+ Scalar: visitor.Node,
2653
+ Seq: visitor.Node
2654
+ }, visitor.Value && {
2655
+ Map: visitor.Value,
2656
+ Scalar: visitor.Value,
2657
+ Seq: visitor.Value
2658
+ }, visitor.Collection && {
2659
+ Map: visitor.Collection,
2660
+ Seq: visitor.Collection
2661
+ }, visitor);
2662
+ return visitor;
2663
+ }
2664
+ function callVisitor(key, node, visitor, path) {
2665
+ if (typeof visitor === "function") return visitor(key, node, path);
2666
+ if (node instanceof YAMLMap) return visitor.Map?.(key, node, path);
2667
+ if (node instanceof YAMLSeq) return visitor.Seq?.(key, node, path);
2668
+ if (node instanceof Pair) return visitor.Pair?.(key, node, path);
2669
+ if (node instanceof Scalar) return visitor.Scalar?.(key, node, path);
2670
+ if (node instanceof Alias) return visitor.Alias?.(key, node, path);
2671
+ }
2672
+ function replaceNode(key, path, node) {
2673
+ const parent = path[path.length - 1];
2674
+ if (parent instanceof YAMLMap || parent instanceof YAMLSeq) parent.items[key] = node;
2675
+ else if (parent instanceof Pair) if (node instanceof NodeBase) if (key === "key") parent.key = node;
2676
+ else parent.value = node;
2677
+ else throw new Error(`Cannot replace pair ${key} with non-node value`);
2678
+ else if (parent instanceof Document) parent.value = node;
2679
+ else {
2680
+ const pt = parent instanceof Alias ? "alias" : "scalar";
2681
+ throw new Error(`Cannot replace node with ${pt} parent`);
2682
+ }
2683
+ }
2684
+
2685
+ //#endregion
2686
+ //#region src/doc/directives.ts
2687
+ const escapeChars = {
2688
+ "!": "%21",
2689
+ ",": "%2C",
2690
+ "[": "%5B",
2691
+ "]": "%5D",
2692
+ "{": "%7B",
2693
+ "}": "%7D"
2694
+ };
2695
+ const escapeTagName = (tn) => tn.replace(/[!,[\]{}]/g, (ch) => escapeChars[ch]);
2696
+ var Directives = class Directives {
2697
+ static defaultYaml = {
2698
+ explicit: false,
2699
+ version: "1.2"
2700
+ };
2701
+ static defaultTags = { "!!": "tag:yaml.org,2002:" };
2702
+ yaml;
2703
+ tags;
2704
+ /**
2705
+ * The directives-end/doc-start marker `---`. If `null`, a marker may still be
2706
+ * included in the document's stringified representation.
2707
+ */
2708
+ docStart = null;
2709
+ /** The doc-end marker `...`. */
2710
+ docEnd = false;
2711
+ /**
2712
+ * Used when parsing YAML 1.1, where:
2713
+ * > If the document specifies no directives, it is parsed using the same
2714
+ * > settings as the previous document. If the document does specify any
2715
+ * > directives, all directives of previous documents, if any, are ignored.
2716
+ */
2717
+ atNextDocument;
2718
+ constructor(yaml, tags) {
2719
+ this.yaml = Object.assign({}, Directives.defaultYaml, yaml);
2720
+ this.tags = Object.assign({}, Directives.defaultTags, tags);
2721
+ }
2722
+ clone() {
2723
+ const copy = new Directives(this.yaml, this.tags);
2724
+ copy.docStart = this.docStart;
2725
+ return copy;
2726
+ }
2727
+ /**
2728
+ * During parsing, get a Directives instance for the current document and
2729
+ * update the stream state according to the current version's spec.
2730
+ */
2731
+ atDocument() {
2732
+ const res = new Directives(this.yaml, this.tags);
2733
+ switch (this.yaml.version) {
2734
+ case "1.1":
2735
+ this.atNextDocument = true;
2736
+ break;
2737
+ case "1.2":
2738
+ this.atNextDocument = false;
2739
+ this.yaml = {
2740
+ explicit: Directives.defaultYaml.explicit,
2741
+ version: "1.2"
2742
+ };
2743
+ this.tags = Object.assign({}, Directives.defaultTags);
2744
+ break;
2745
+ }
2746
+ return res;
2747
+ }
2748
+ /**
2749
+ * @param onError - May be called even if the action was successful
2750
+ * @returns `true` on success
2751
+ */
2752
+ add(line, onError) {
2753
+ if (this.atNextDocument) {
2754
+ this.yaml = {
2755
+ explicit: Directives.defaultYaml.explicit,
2756
+ version: "1.1"
2757
+ };
2758
+ this.tags = Object.assign({}, Directives.defaultTags);
2759
+ this.atNextDocument = false;
2760
+ }
2761
+ const parts = line.trim().split(/[ \t]+/);
2762
+ const name = parts.shift();
2763
+ switch (name) {
2764
+ case "%TAG": {
2765
+ if (parts.length !== 2) {
2766
+ onError(0, "%TAG directive should contain exactly two parts");
2767
+ if (parts.length < 2) return false;
2768
+ }
2769
+ const [handle, prefix] = parts;
2770
+ this.tags[handle] = prefix;
2771
+ return true;
2772
+ }
2773
+ case "%YAML": {
2774
+ this.yaml.explicit = true;
2775
+ if (parts.length !== 1) {
2776
+ onError(0, "%YAML directive should contain exactly one part");
2777
+ return false;
2778
+ }
2779
+ const [version] = parts;
2780
+ if (version === "1.1" || version === "1.2") {
2781
+ this.yaml.version = version;
2782
+ return true;
2783
+ } else {
2784
+ const isValid = /^\d+\.\d+$/.test(version);
2785
+ onError(6, `Unsupported YAML version ${version}`, isValid);
2786
+ return false;
2787
+ }
2788
+ }
2789
+ default:
2790
+ onError(0, `Unknown directive ${name}`, true);
2791
+ return false;
2792
+ }
2793
+ }
2794
+ /**
2795
+ * Resolves a tag, matching handles to those defined in %TAG directives.
2796
+ *
2797
+ * @returns Resolved tag, which may also be the non-specific tag `'!'` or a
2798
+ * `'!local'` tag, or `null` if unresolvable.
2799
+ */
2800
+ tagName(source, onError) {
2801
+ if (source === "!") return "!";
2802
+ if (source[0] !== "!") {
2803
+ onError(`Not a valid tag: ${source}`);
2804
+ return null;
2805
+ }
2806
+ if (source[1] === "<") {
2807
+ const verbatim = source.slice(2, -1);
2808
+ if (verbatim === "!" || verbatim === "!!") {
2809
+ onError(`Verbatim tags aren't resolved, so ${source} is invalid.`);
2810
+ return null;
2811
+ }
2812
+ if (source[source.length - 1] !== ">") onError("Verbatim tags must end with a >");
2813
+ return verbatim;
2814
+ }
2815
+ const [, handle, suffix] = source.match(/^(.*!)([^!]*)$/s);
2816
+ if (!suffix) onError(`The ${source} tag has no suffix`);
2817
+ const prefix = this.tags[handle];
2818
+ if (prefix) try {
2819
+ return prefix + decodeURIComponent(suffix);
2820
+ } catch (error) {
2821
+ onError(String(error));
2822
+ return null;
2823
+ }
2824
+ if (handle === "!") return source;
2825
+ onError(`Could not resolve tag: ${source}`);
2826
+ return null;
2827
+ }
2828
+ /**
2829
+ * Given a fully resolved tag, returns its printable string form,
2830
+ * taking into account current tag prefixes and defaults.
2831
+ */
2832
+ tagString(tag) {
2833
+ for (const [handle, prefix] of Object.entries(this.tags)) if (tag.startsWith(prefix)) return handle + escapeTagName(tag.substring(prefix.length));
2834
+ return tag[0] === "!" ? tag : `!<${tag}>`;
2835
+ }
2836
+ toString(doc) {
2837
+ const lines = this.yaml.explicit ? [`%YAML ${this.yaml.version || "1.2"}`] : [];
2838
+ const tagEntries = Object.entries(this.tags);
2839
+ let tagNames;
2840
+ if (doc && tagEntries.length > 0) {
2841
+ const tags = {};
2842
+ visit(doc.value, (_key, node) => {
2843
+ if (node instanceof NodeBase && node.tag) tags[node.tag] = true;
2844
+ });
2845
+ tagNames = Object.keys(tags);
2846
+ } else tagNames = [];
2847
+ for (const [handle, prefix] of tagEntries) {
2848
+ if (handle === "!!" && prefix === "tag:yaml.org,2002:") continue;
2849
+ if (!doc || tagNames.some((tn) => tn.startsWith(prefix))) lines.push(`%TAG ${handle} ${prefix}`);
2850
+ }
2851
+ return lines.join("\n");
2852
+ }
2853
+ };
2854
+
2855
+ //#endregion
2856
+ export { toJS as S, Collection as _, Schema as a, Scalar as b, seq as c, findPair as d, Alias as f, YAMLSeq as g, warn as h, Document as i, map as l, debug as m, visit as n, stringifyNumber as o, Pair as p, visitAsync as r, string as s, Directives as t, YAMLMap as u, stringifyString as v, NodeBase as x, foldFlowLines as y };