yaml 2.0.0-4 → 2.0.0-8

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 (220) hide show
  1. package/README.md +5 -5
  2. package/browser/dist/compose/compose-collection.js +12 -9
  3. package/browser/dist/compose/compose-doc.js +23 -6
  4. package/browser/dist/compose/compose-node.js +27 -17
  5. package/browser/dist/compose/compose-scalar.js +21 -23
  6. package/browser/dist/compose/composer.js +108 -78
  7. package/browser/dist/compose/resolve-block-map.js +41 -29
  8. package/browser/dist/compose/resolve-block-scalar.js +14 -17
  9. package/browser/dist/compose/resolve-block-seq.js +21 -17
  10. package/browser/dist/compose/resolve-end.js +7 -8
  11. package/browser/dist/compose/resolve-flow-collection.js +158 -199
  12. package/browser/dist/compose/resolve-flow-scalar.js +62 -26
  13. package/browser/dist/compose/resolve-props.js +72 -37
  14. package/browser/dist/compose/util-contains-newline.js +15 -12
  15. package/browser/dist/compose/util-map-includes.js +17 -0
  16. package/browser/dist/doc/Document.js +74 -99
  17. package/browser/dist/doc/anchors.js +72 -0
  18. package/browser/dist/doc/createNode.js +35 -19
  19. package/browser/dist/doc/directives.js +5 -0
  20. package/browser/dist/errors.js +16 -12
  21. package/browser/dist/index.js +3 -3
  22. package/browser/dist/nodes/Alias.js +51 -28
  23. package/browser/dist/nodes/Collection.js +23 -92
  24. package/browser/dist/nodes/Node.js +9 -1
  25. package/browser/dist/nodes/Pair.js +16 -231
  26. package/browser/dist/nodes/YAMLMap.js +8 -4
  27. package/browser/dist/nodes/YAMLSeq.js +7 -4
  28. package/browser/dist/nodes/addPairToJSMap.js +103 -0
  29. package/browser/dist/nodes/toJS.js +12 -10
  30. package/browser/dist/options.js +1 -2
  31. package/browser/dist/parse/cst-scalar.js +219 -0
  32. package/browser/dist/parse/cst-stringify.js +61 -0
  33. package/browser/dist/parse/cst-visit.js +97 -0
  34. package/{dist/parse/tokens.js → browser/dist/parse/cst.js} +12 -7
  35. package/browser/dist/parse/lexer.js +149 -125
  36. package/browser/dist/parse/parser.js +272 -196
  37. package/browser/dist/public-api.js +11 -14
  38. package/browser/dist/schema/Schema.js +28 -0
  39. package/browser/dist/{tags/failsafe → schema/common}/map.js +0 -0
  40. package/browser/dist/schema/common/null.js +13 -0
  41. package/browser/dist/{tags/failsafe → schema/common}/seq.js +1 -1
  42. package/browser/dist/{tags/failsafe → schema/common}/string.js +0 -0
  43. package/browser/dist/schema/core/bool.js +19 -0
  44. package/browser/dist/schema/core/float.js +40 -0
  45. package/browser/dist/schema/core/int.js +38 -0
  46. package/browser/dist/schema/core/schema.js +23 -0
  47. package/browser/dist/{tags/json.js → schema/json/schema.js} +5 -6
  48. package/browser/dist/schema/tags.js +79 -0
  49. package/browser/dist/{tags → schema}/yaml-1.1/binary.js +0 -0
  50. package/browser/dist/schema/yaml-1.1/bool.js +26 -0
  51. package/browser/dist/schema/yaml-1.1/float.js +43 -0
  52. package/browser/dist/schema/yaml-1.1/int.js +71 -0
  53. package/browser/dist/{tags → schema}/yaml-1.1/omap.js +0 -0
  54. package/browser/dist/{tags → schema}/yaml-1.1/pairs.js +9 -6
  55. package/browser/dist/schema/yaml-1.1/schema.js +37 -0
  56. package/browser/dist/{tags → schema}/yaml-1.1/set.js +0 -0
  57. package/browser/dist/{tags → schema}/yaml-1.1/timestamp.js +0 -0
  58. package/browser/dist/stringify/stringify.js +8 -6
  59. package/browser/dist/stringify/stringifyCollection.js +122 -0
  60. package/browser/dist/stringify/stringifyComment.js +14 -0
  61. package/browser/dist/stringify/stringifyDocument.js +64 -0
  62. package/browser/dist/stringify/stringifyPair.js +111 -0
  63. package/browser/dist/stringify/stringifyString.js +53 -52
  64. package/browser/dist/visit.js +20 -1
  65. package/dist/compose/compose-collection.d.ts +4 -4
  66. package/dist/compose/compose-collection.js +12 -9
  67. package/dist/compose/compose-doc.d.ts +4 -3
  68. package/dist/compose/compose-doc.js +23 -6
  69. package/dist/compose/compose-node.d.ts +15 -7
  70. package/dist/compose/compose-node.js +27 -17
  71. package/dist/compose/compose-scalar.d.ts +4 -3
  72. package/dist/compose/compose-scalar.js +20 -22
  73. package/dist/compose/composer.d.ts +28 -23
  74. package/dist/compose/composer.js +109 -79
  75. package/dist/compose/resolve-block-map.d.ts +5 -4
  76. package/dist/compose/resolve-block-map.js +41 -29
  77. package/dist/compose/resolve-block-scalar.d.ts +5 -3
  78. package/dist/compose/resolve-block-scalar.js +14 -17
  79. package/dist/compose/resolve-block-seq.d.ts +4 -4
  80. package/dist/compose/resolve-block-seq.js +21 -17
  81. package/dist/compose/resolve-end.d.ts +3 -2
  82. package/dist/compose/resolve-end.js +7 -8
  83. package/dist/compose/resolve-flow-collection.d.ts +4 -5
  84. package/dist/compose/resolve-flow-collection.js +157 -198
  85. package/dist/compose/resolve-flow-scalar.d.ts +5 -3
  86. package/dist/compose/resolve-flow-scalar.js +62 -26
  87. package/dist/compose/resolve-props.d.ts +16 -10
  88. package/dist/compose/resolve-props.js +72 -37
  89. package/dist/compose/util-contains-newline.d.ts +1 -1
  90. package/dist/compose/util-contains-newline.js +15 -12
  91. package/dist/compose/util-empty-scalar-position.d.ts +1 -1
  92. package/dist/compose/util-map-includes.d.ts +4 -0
  93. package/dist/compose/util-map-includes.js +19 -0
  94. package/dist/doc/Document.d.ts +35 -15
  95. package/dist/doc/Document.js +72 -97
  96. package/dist/doc/anchors.d.ts +24 -0
  97. package/dist/doc/anchors.js +77 -0
  98. package/dist/doc/createNode.d.ts +10 -11
  99. package/dist/doc/createNode.js +34 -18
  100. package/dist/doc/directives.d.ts +1 -0
  101. package/dist/doc/directives.js +5 -0
  102. package/dist/errors.d.ts +11 -8
  103. package/dist/errors.js +16 -12
  104. package/dist/index.d.ts +5 -3
  105. package/dist/index.js +3 -3
  106. package/dist/nodes/Alias.d.ts +19 -9
  107. package/dist/nodes/Alias.js +51 -28
  108. package/dist/nodes/Collection.d.ts +9 -17
  109. package/dist/nodes/Collection.js +22 -91
  110. package/dist/nodes/Node.d.ts +10 -4
  111. package/dist/nodes/Node.js +9 -0
  112. package/dist/nodes/Pair.d.ts +10 -13
  113. package/dist/nodes/Pair.js +15 -230
  114. package/dist/nodes/Scalar.d.ts +6 -3
  115. package/dist/nodes/YAMLMap.d.ts +3 -3
  116. package/dist/nodes/YAMLMap.js +8 -4
  117. package/dist/nodes/YAMLSeq.d.ts +3 -3
  118. package/dist/nodes/YAMLSeq.js +7 -4
  119. package/dist/nodes/addPairToJSMap.d.ts +3 -0
  120. package/dist/nodes/addPairToJSMap.js +105 -0
  121. package/dist/nodes/toJS.d.ts +4 -5
  122. package/dist/nodes/toJS.js +12 -10
  123. package/dist/options.d.ts +41 -25
  124. package/dist/options.js +1 -2
  125. package/dist/parse/cst-scalar.d.ts +58 -0
  126. package/dist/parse/cst-scalar.js +223 -0
  127. package/dist/parse/cst-stringify.d.ts +8 -0
  128. package/dist/parse/cst-stringify.js +63 -0
  129. package/dist/parse/cst-visit.d.ts +39 -0
  130. package/dist/parse/cst-visit.js +99 -0
  131. package/dist/parse/{tokens.d.ts → cst.d.ts} +23 -7
  132. package/{browser/dist/parse/tokens.js → dist/parse/cst.js} +27 -1
  133. package/dist/parse/lexer.d.ts +7 -14
  134. package/dist/parse/lexer.js +150 -126
  135. package/dist/parse/parser.d.ts +31 -24
  136. package/dist/parse/parser.js +274 -198
  137. package/dist/public-api.d.ts +7 -7
  138. package/dist/public-api.js +11 -14
  139. package/dist/{doc → schema}/Schema.d.ts +6 -3
  140. package/dist/schema/Schema.js +30 -0
  141. package/dist/{tags/failsafe → schema/common}/map.d.ts +0 -0
  142. package/dist/{tags/failsafe → schema/common}/map.js +0 -0
  143. package/dist/schema/common/null.d.ts +4 -0
  144. package/dist/schema/common/null.js +15 -0
  145. package/dist/{tags/failsafe → schema/common}/seq.d.ts +0 -0
  146. package/dist/{tags/failsafe → schema/common}/seq.js +1 -1
  147. package/dist/{tags/failsafe → schema/common}/string.d.ts +0 -0
  148. package/dist/{tags/failsafe → schema/common}/string.js +0 -0
  149. package/dist/schema/core/bool.d.ts +4 -0
  150. package/dist/schema/core/bool.js +21 -0
  151. package/dist/schema/core/float.d.ts +4 -0
  152. package/dist/schema/core/float.js +44 -0
  153. package/dist/schema/core/int.d.ts +4 -0
  154. package/dist/schema/core/int.js +42 -0
  155. package/dist/schema/core/schema.d.ts +1 -0
  156. package/dist/schema/core/schema.js +25 -0
  157. package/dist/schema/json/schema.d.ts +2 -0
  158. package/dist/{tags/json.js → schema/json/schema.js} +5 -6
  159. package/dist/schema/tags.d.ts +41 -0
  160. package/dist/schema/tags.js +82 -0
  161. package/dist/{tags → schema}/types.d.ts +3 -7
  162. package/dist/{tags → schema}/yaml-1.1/binary.d.ts +0 -0
  163. package/dist/{tags → schema}/yaml-1.1/binary.js +0 -0
  164. package/dist/schema/yaml-1.1/bool.d.ts +7 -0
  165. package/dist/schema/yaml-1.1/bool.js +29 -0
  166. package/dist/schema/yaml-1.1/float.d.ts +4 -0
  167. package/dist/schema/yaml-1.1/float.js +47 -0
  168. package/dist/schema/yaml-1.1/int.d.ts +5 -0
  169. package/dist/schema/yaml-1.1/int.js +76 -0
  170. package/dist/{tags → schema}/yaml-1.1/omap.d.ts +0 -0
  171. package/dist/{tags → schema}/yaml-1.1/omap.js +0 -0
  172. package/dist/{tags → schema}/yaml-1.1/pairs.d.ts +3 -2
  173. package/dist/{tags → schema}/yaml-1.1/pairs.js +9 -6
  174. package/dist/schema/yaml-1.1/schema.d.ts +1 -0
  175. package/dist/schema/yaml-1.1/schema.js +39 -0
  176. package/dist/{tags → schema}/yaml-1.1/set.d.ts +1 -1
  177. package/dist/{tags → schema}/yaml-1.1/set.js +0 -0
  178. package/dist/{tags → schema}/yaml-1.1/timestamp.d.ts +0 -0
  179. package/dist/{tags → schema}/yaml-1.1/timestamp.js +0 -0
  180. package/dist/stringify/stringify.d.ts +1 -2
  181. package/dist/stringify/stringify.js +8 -6
  182. package/dist/stringify/stringifyCollection.d.ts +21 -0
  183. package/dist/stringify/stringifyCollection.js +124 -0
  184. package/dist/stringify/stringifyComment.d.ts +2 -0
  185. package/dist/stringify/stringifyComment.js +17 -0
  186. package/dist/stringify/stringifyDocument.d.ts +3 -0
  187. package/dist/stringify/stringifyDocument.js +66 -0
  188. package/dist/stringify/stringifyPair.d.ts +3 -0
  189. package/dist/stringify/stringifyPair.js +113 -0
  190. package/dist/stringify/stringifyString.js +53 -52
  191. package/dist/test-events.d.ts +1 -2
  192. package/dist/test-events.js +25 -12
  193. package/dist/util.d.ts +1 -1
  194. package/dist/visit.d.ts +10 -1
  195. package/dist/visit.js +20 -1
  196. package/package.json +9 -8
  197. package/browser/dist/doc/Anchors.js +0 -102
  198. package/browser/dist/doc/Schema.js +0 -27
  199. package/browser/dist/doc/getSchemaTags.js +0 -30
  200. package/browser/dist/stringify/addComment.js +0 -17
  201. package/browser/dist/tags/core.js +0 -109
  202. package/browser/dist/tags/failsafe/index.js +0 -7
  203. package/browser/dist/tags/index.js +0 -34
  204. package/browser/dist/tags/yaml-1.1/index.js +0 -152
  205. package/dist/doc/Anchors.d.ts +0 -36
  206. package/dist/doc/Anchors.js +0 -104
  207. package/dist/doc/Schema.js +0 -29
  208. package/dist/doc/getSchemaTags.d.ts +0 -3
  209. package/dist/doc/getSchemaTags.js +0 -32
  210. package/dist/stringify/addComment.d.ts +0 -2
  211. package/dist/stringify/addComment.js +0 -20
  212. package/dist/tags/core.d.ts +0 -14
  213. package/dist/tags/core.js +0 -119
  214. package/dist/tags/failsafe/index.d.ts +0 -1
  215. package/dist/tags/failsafe/index.js +0 -9
  216. package/dist/tags/index.d.ts +0 -31
  217. package/dist/tags/index.js +0 -37
  218. package/dist/tags/json.d.ts +0 -2
  219. package/dist/tags/yaml-1.1/index.d.ts +0 -2
  220. package/dist/tags/yaml-1.1/index.js +0 -154
@@ -6,10 +6,10 @@ var Node = require('../nodes/Node.js');
6
6
  var Pair = require('../nodes/Pair.js');
7
7
  var toJS = require('../nodes/toJS.js');
8
8
  var options = require('../options.js');
9
- var addComment = require('../stringify/addComment.js');
9
+ var Schema = require('../schema/Schema.js');
10
10
  var stringify = require('../stringify/stringify.js');
11
- var Anchors = require('./Anchors.js');
12
- var Schema = require('./Schema.js');
11
+ var stringifyDocument = require('../stringify/stringifyDocument.js');
12
+ var anchors = require('./anchors.js');
13
13
  var applyReviver = require('./applyReviver.js');
14
14
  var createNode = require('./createNode.js');
15
15
  var directives = require('./directives.js');
@@ -25,7 +25,7 @@ class Document {
25
25
  /** Warnings encountered during parsing. */
26
26
  this.warnings = [];
27
27
  Object.defineProperty(this, Node.NODE_TYPE, { value: Node.DOC });
28
- let _replacer = undefined;
28
+ let _replacer = null;
29
29
  if (typeof replacer === 'function' || Array.isArray(replacer)) {
30
30
  _replacer = replacer;
31
31
  }
@@ -35,7 +35,6 @@ class Document {
35
35
  }
36
36
  const opt = Object.assign({}, options.defaultOptions, options$1);
37
37
  this.options = opt;
38
- this.anchors = new Anchors.Anchors(this.options.anchorPrefix);
39
38
  let { version } = opt;
40
39
  if (options$1 === null || options$1 === void 0 ? void 0 : options$1.directives) {
41
40
  this.directives = options$1.directives.atDocument();
@@ -45,10 +44,34 @@ class Document {
45
44
  else
46
45
  this.directives = new directives.Directives({ version });
47
46
  this.setSchema(version, options$1);
48
- this.contents =
49
- value === undefined
50
- ? null
51
- : this.createNode(value, { replacer: _replacer });
47
+ if (value === undefined)
48
+ this.contents = null;
49
+ else {
50
+ this.contents = this.createNode(value, _replacer, options$1);
51
+ }
52
+ }
53
+ /**
54
+ * Create a deep copy of this Document and its contents.
55
+ *
56
+ * Custom Node values that inherit from `Object` still refer to their original instances.
57
+ */
58
+ clone() {
59
+ const copy = Object.create(Document.prototype, {
60
+ [Node.NODE_TYPE]: { value: Node.DOC }
61
+ });
62
+ copy.commentBefore = this.commentBefore;
63
+ copy.comment = this.comment;
64
+ copy.errors = this.errors.slice();
65
+ copy.warnings = this.warnings.slice();
66
+ copy.options = Object.assign({}, this.options);
67
+ copy.directives = this.directives.clone();
68
+ copy.schema = this.schema.clone();
69
+ copy.contents = Node.isNode(this.contents)
70
+ ? this.contents.clone(copy.schema)
71
+ : this.contents;
72
+ if (this.range)
73
+ copy.range = this.range.slice();
74
+ return copy;
52
75
  }
53
76
  /** Adds a value to the document. */
54
77
  add(value) {
@@ -61,48 +84,54 @@ class Document {
61
84
  this.contents.addIn(path, value);
62
85
  }
63
86
  /**
64
- * Convert any value into a `Node` using the current schema, recursively
65
- * turning objects into collections.
87
+ * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
88
+ *
89
+ * If `node` already has an anchor, `name` is ignored.
90
+ * Otherwise, the `node.anchor` value will be set to `name`,
91
+ * or if an anchor with that name is already present in the document,
92
+ * `name` will be used as a prefix for a new unique anchor.
93
+ * If `name` is undefined, the generated anchor will use 'a' as a prefix.
66
94
  */
67
- createNode(value, { flow, keepUndefined, onTagObj, replacer, tag } = {}) {
68
- if (typeof replacer === 'function')
95
+ createAlias(node, name) {
96
+ if (!node.anchor) {
97
+ const prev = anchors.anchorNames(this);
98
+ node.anchor =
99
+ !name || prev.has(name) ? anchors.findNewAnchor(name || 'a', prev) : name;
100
+ }
101
+ return new Alias.Alias(node.anchor);
102
+ }
103
+ createNode(value, replacer, options) {
104
+ let _replacer = undefined;
105
+ if (typeof replacer === 'function') {
69
106
  value = replacer.call({ '': value }, '', value);
107
+ _replacer = replacer;
108
+ }
70
109
  else if (Array.isArray(replacer)) {
71
110
  const keyToStr = (v) => typeof v === 'number' || v instanceof String || v instanceof Number;
72
111
  const asStr = replacer.filter(keyToStr).map(String);
73
112
  if (asStr.length > 0)
74
113
  replacer = replacer.concat(asStr);
114
+ _replacer = replacer;
115
+ }
116
+ else if (options === undefined && replacer) {
117
+ options = replacer;
118
+ replacer = undefined;
75
119
  }
76
- if (typeof keepUndefined !== 'boolean')
77
- keepUndefined = !!this.options.keepUndefined;
78
- const aliasNodes = [];
120
+ const { aliasDuplicateObjects, anchorPrefix, flow, keepUndefined, onTagObj, tag } = options || {};
121
+ const { onAnchor, setAnchors, sourceObjects } = anchors.createNodeAnchors(this, anchorPrefix || 'a');
79
122
  const ctx = {
80
- keepUndefined,
81
- onAlias(source) {
82
- // These get fixed later in createNode()
83
- const alias = new Alias.Alias(source);
84
- aliasNodes.push(alias);
85
- return alias;
86
- },
123
+ aliasDuplicateObjects: aliasDuplicateObjects !== null && aliasDuplicateObjects !== void 0 ? aliasDuplicateObjects : true,
124
+ keepUndefined: keepUndefined !== null && keepUndefined !== void 0 ? keepUndefined : false,
125
+ onAnchor,
87
126
  onTagObj,
88
- prevObjects: new Map(),
89
- replacer,
90
- schema: this.schema
127
+ replacer: _replacer,
128
+ schema: this.schema,
129
+ sourceObjects
91
130
  };
92
131
  const node = createNode.createNode(value, tag, ctx);
93
- for (const alias of aliasNodes) {
94
- // With circular references, the source node is only resolved after all of
95
- // its child nodes are. This is why anchors are set only after all of the
96
- // nodes have been created.
97
- alias.source = alias.source.node;
98
- let name = this.anchors.getName(alias.source);
99
- if (!name) {
100
- name = this.anchors.newName();
101
- this.anchors.map[name] = alias.source;
102
- }
103
- }
104
132
  if (flow && Node.isCollection(node))
105
133
  node.flow = true;
134
+ setAnchors();
106
135
  return node;
107
136
  }
108
137
  /**
@@ -110,8 +139,8 @@ class Document {
110
139
  * recursively wrapping all values as `Scalar` or `Collection` nodes.
111
140
  */
112
141
  createPair(key, value, options = {}) {
113
- const k = this.createNode(key, options);
114
- const v = this.createNode(value, options);
142
+ const k = this.createNode(key, null, options);
143
+ const v = this.createNode(value, null, options);
115
144
  return new Pair.Pair(k, v);
116
145
  }
117
146
  /**
@@ -225,10 +254,8 @@ class Document {
225
254
  }
226
255
  // json & jsonArg are only used from toJSON()
227
256
  toJS({ json, jsonArg, mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {
228
- const anchorNodes = Object.values(this.anchors.map).map(node => [node, { alias: [], aliasCount: 0, count: 1 }]);
229
- const anchors = anchorNodes.length > 0 ? new Map(anchorNodes) : null;
230
257
  const ctx = {
231
- anchors,
258
+ anchors: new Map(),
232
259
  doc: this,
233
260
  keep: !json,
234
261
  mapAsMap: mapAsMap === true,
@@ -237,8 +264,8 @@ class Document {
237
264
  stringify: stringify.stringify
238
265
  };
239
266
  const res = toJS.toJS(this.contents, jsonArg || '', ctx);
240
- if (typeof onAnchor === 'function' && anchors)
241
- for (const { count, res } of anchors.values())
267
+ if (typeof onAnchor === 'function')
268
+ for (const { count, res } of ctx.anchors.values())
242
269
  onAnchor(res, count);
243
270
  return typeof reviver === 'function'
244
271
  ? applyReviver.applyReviver(reviver, { '': res }, '', res)
@@ -262,59 +289,7 @@ class Document {
262
289
  const s = JSON.stringify(options.indent);
263
290
  throw new Error(`"indent" option must be a positive integer, not ${s}`);
264
291
  }
265
- const lines = [];
266
- let hasDirectives = options.directives === true;
267
- if (options.directives !== false) {
268
- const dir = this.directives.toString(this);
269
- if (dir) {
270
- lines.push(dir);
271
- hasDirectives = true;
272
- }
273
- else if (this.directives.marker)
274
- hasDirectives = true;
275
- }
276
- if (hasDirectives)
277
- lines.push('---');
278
- if (this.commentBefore) {
279
- if (lines.length !== 1)
280
- lines.unshift('');
281
- lines.unshift(this.commentBefore.replace(/^/gm, '#'));
282
- }
283
- const ctx = stringify.createStringifyContext(this, options);
284
- let chompKeep = false;
285
- let contentComment = null;
286
- if (this.contents) {
287
- if (Node.isNode(this.contents)) {
288
- if (this.contents.spaceBefore && hasDirectives)
289
- lines.push('');
290
- if (this.contents.commentBefore)
291
- lines.push(this.contents.commentBefore.replace(/^/gm, '#'));
292
- // top-level block scalars need to be indented if followed by a comment
293
- ctx.forceBlockIndent = !!this.comment;
294
- contentComment = this.contents.comment;
295
- }
296
- const onChompKeep = contentComment ? undefined : () => (chompKeep = true);
297
- let body = stringify.stringify(this.contents, ctx, () => (contentComment = null), onChompKeep);
298
- if (contentComment)
299
- body = addComment.addComment(body, '', contentComment);
300
- if ((body[0] === '|' || body[0] === '>') &&
301
- lines[lines.length - 1] === '---') {
302
- // Top-level block scalars with a preceding doc marker ought to use the
303
- // same line for their header.
304
- lines[lines.length - 1] = `--- ${body}`;
305
- }
306
- else
307
- lines.push(body);
308
- }
309
- else {
310
- lines.push(stringify.stringify(this.contents, ctx));
311
- }
312
- if (this.comment) {
313
- if ((!chompKeep || contentComment) && lines[lines.length - 1] !== '')
314
- lines.push('');
315
- lines.push(this.comment.replace(/^/gm, '#'));
316
- }
317
- return lines.join('\n') + '\n';
292
+ return stringifyDocument.stringifyDocument(this, options);
318
293
  }
319
294
  }
320
295
  function assertCollection(contents) {
@@ -0,0 +1,24 @@
1
+ import { Node } from '../nodes/Node.js';
2
+ import type { Document } from './Document.js';
3
+ /**
4
+ * Verify that the input string is a valid anchor.
5
+ *
6
+ * Will throw on errors.
7
+ */
8
+ export declare function anchorIsValid(anchor: string): true;
9
+ export declare function anchorNames(root: Document | Node): Set<string>;
10
+ /** Find a new anchor name with the given `prefix` and a one-indexed suffix. */
11
+ export declare function findNewAnchor(prefix: string, exclude: Set<string>): string;
12
+ export declare function createNodeAnchors(doc: Document, prefix: string): {
13
+ onAnchor(source: unknown): string;
14
+ /**
15
+ * With circular references, the source node is only resolved after all
16
+ * of its child nodes are. This is why anchors are set only after all of
17
+ * the nodes have been created.
18
+ */
19
+ setAnchors(): void;
20
+ sourceObjects: Map<unknown, {
21
+ anchor: string | null;
22
+ node: Node | null;
23
+ }>;
24
+ };
@@ -0,0 +1,77 @@
1
+ 'use strict';
2
+
3
+ var Node = require('../nodes/Node.js');
4
+ var visit = require('../visit.js');
5
+
6
+ /**
7
+ * Verify that the input string is a valid anchor.
8
+ *
9
+ * Will throw on errors.
10
+ */
11
+ function anchorIsValid(anchor) {
12
+ if (/[\x00-\x19\s,[\]{}]/.test(anchor)) {
13
+ const sa = JSON.stringify(anchor);
14
+ const msg = `Anchor must not contain whitespace or control characters: ${sa}`;
15
+ throw new Error(msg);
16
+ }
17
+ return true;
18
+ }
19
+ function anchorNames(root) {
20
+ const anchors = new Set();
21
+ visit.visit(root, {
22
+ Value(_key, node) {
23
+ if (node.anchor)
24
+ anchors.add(node.anchor);
25
+ }
26
+ });
27
+ return anchors;
28
+ }
29
+ /** Find a new anchor name with the given `prefix` and a one-indexed suffix. */
30
+ function findNewAnchor(prefix, exclude) {
31
+ for (let i = 1; true; ++i) {
32
+ const name = `${prefix}${i}`;
33
+ if (!exclude.has(name))
34
+ return name;
35
+ }
36
+ }
37
+ function createNodeAnchors(doc, prefix) {
38
+ const aliasObjects = [];
39
+ const sourceObjects = new Map();
40
+ let prevAnchors = null;
41
+ return {
42
+ onAnchor(source) {
43
+ aliasObjects.push(source);
44
+ if (!prevAnchors)
45
+ prevAnchors = anchorNames(doc);
46
+ const anchor = findNewAnchor(prefix, prevAnchors);
47
+ prevAnchors.add(anchor);
48
+ return anchor;
49
+ },
50
+ /**
51
+ * With circular references, the source node is only resolved after all
52
+ * of its child nodes are. This is why anchors are set only after all of
53
+ * the nodes have been created.
54
+ */
55
+ setAnchors() {
56
+ for (const source of aliasObjects) {
57
+ const ref = sourceObjects.get(source);
58
+ if (typeof ref === 'object' &&
59
+ ref.anchor &&
60
+ (Node.isScalar(ref.node) || Node.isCollection(ref.node))) {
61
+ ref.node.anchor = ref.anchor;
62
+ }
63
+ else {
64
+ const error = new Error('Failed to resolve repeated object (this should not happen)');
65
+ error.source = source;
66
+ throw error;
67
+ }
68
+ }
69
+ },
70
+ sourceObjects
71
+ };
72
+ }
73
+
74
+ exports.anchorIsValid = anchorIsValid;
75
+ exports.anchorNames = anchorNames;
76
+ exports.createNodeAnchors = createNodeAnchors;
77
+ exports.findNewAnchor = findNewAnchor;
@@ -1,17 +1,16 @@
1
- import type { Alias } from '../nodes/Alias.js';
2
1
  import { Node } from '../nodes/Node.js';
3
- import type { TagObj } from '../tags/types.js';
2
+ import type { Schema } from '../schema/Schema.js';
3
+ import type { CollectionTag, ScalarTag } from '../schema/types.js';
4
4
  import type { Replacer } from './Document.js';
5
- import type { Schema } from './Schema.js';
6
- export interface CreateNodeAliasRef {
7
- node: Node | undefined;
8
- value: unknown;
9
- }
10
5
  export interface CreateNodeContext {
11
- keepUndefined?: boolean;
12
- onAlias(source: CreateNodeAliasRef): Alias;
13
- onTagObj?: (tagObj: TagObj) => void;
14
- prevObjects: Map<unknown, CreateNodeAliasRef>;
6
+ aliasDuplicateObjects: boolean;
7
+ keepUndefined: boolean;
8
+ onAnchor(source: unknown): string;
9
+ onTagObj?: (tagObj: ScalarTag | CollectionTag) => void;
10
+ sourceObjects: Map<unknown, {
11
+ anchor: string | null;
12
+ node: Node | null;
13
+ }>;
15
14
  replacer?: Replacer;
16
15
  schema: Schema;
17
16
  }
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var Alias = require('../nodes/Alias.js');
3
4
  var Node = require('../nodes/Node.js');
4
5
  var Scalar = require('../nodes/Scalar.js');
5
6
 
@@ -16,10 +17,12 @@ function findTagObject(value, tagName, tags) {
16
17
  }
17
18
  function createNode(value, tagName, ctx) {
18
19
  var _a, _b;
20
+ if (Node.isDocument(value))
21
+ value = value.contents;
19
22
  if (Node.isNode(value))
20
23
  return value;
21
24
  if (Node.isPair(value)) {
22
- const map = (_b = (_a = ctx.schema.map).createNode) === null || _b === void 0 ? void 0 : _b.call(_a, ctx.schema, null, ctx);
25
+ const map = (_b = (_a = ctx.schema[Node.MAP]).createNode) === null || _b === void 0 ? void 0 : _b.call(_a, ctx.schema, null, ctx);
23
26
  map.items.push(value);
24
27
  return map;
25
28
  }
@@ -31,39 +34,52 @@ function createNode(value, tagName, ctx) {
31
34
  // https://tc39.es/ecma262/#sec-serializejsonproperty
32
35
  value = value.valueOf();
33
36
  }
34
- const { onAlias, onTagObj, prevObjects } = ctx;
35
- const { map, seq, tags } = ctx.schema;
37
+ const { aliasDuplicateObjects, onAnchor, onTagObj, schema, sourceObjects } = ctx;
38
+ // Detect duplicate references to the same object & use Alias nodes for all
39
+ // after first. The `ref` wrapper allows for circular references to resolve.
40
+ let ref = undefined;
41
+ if (aliasDuplicateObjects && value && typeof value === 'object') {
42
+ ref = sourceObjects.get(value);
43
+ if (ref) {
44
+ if (!ref.anchor)
45
+ ref.anchor = onAnchor(value);
46
+ return new Alias.Alias(ref.anchor);
47
+ }
48
+ else {
49
+ ref = { anchor: null, node: null };
50
+ sourceObjects.set(value, ref);
51
+ }
52
+ }
36
53
  if (tagName && tagName.startsWith('!!'))
37
54
  tagName = defaultTagPrefix + tagName.slice(2);
38
- let tagObj = findTagObject(value, tagName, tags);
55
+ let tagObj = findTagObject(value, tagName, schema.tags);
39
56
  if (!tagObj) {
40
57
  if (value && typeof value.toJSON === 'function')
41
58
  value = value.toJSON();
42
- if (!value || typeof value !== 'object')
43
- return new Scalar.Scalar(value);
59
+ if (!value || typeof value !== 'object') {
60
+ const node = new Scalar.Scalar(value);
61
+ if (ref)
62
+ ref.node = node;
63
+ return node;
64
+ }
44
65
  tagObj =
45
- value instanceof Map ? map : Symbol.iterator in Object(value) ? seq : map;
66
+ value instanceof Map
67
+ ? schema[Node.MAP]
68
+ : Symbol.iterator in Object(value)
69
+ ? schema[Node.SEQ]
70
+ : schema[Node.MAP];
46
71
  }
47
72
  if (onTagObj) {
48
73
  onTagObj(tagObj);
49
74
  delete ctx.onTagObj;
50
75
  }
51
- // Detect duplicate references to the same object & use Alias nodes for all
52
- // after first. The `ref` wrapper allows for circular references to resolve.
53
- const ref = { value: undefined, node: undefined };
54
- if (value && typeof value === 'object') {
55
- const prev = prevObjects.get(value);
56
- if (prev)
57
- return onAlias(prev);
58
- ref.value = value;
59
- prevObjects.set(value, ref);
60
- }
61
76
  const node = (tagObj === null || tagObj === void 0 ? void 0 : tagObj.createNode)
62
77
  ? tagObj.createNode(ctx.schema, value, ctx)
63
78
  : new Scalar.Scalar(value);
64
79
  if (tagName)
65
80
  node.tag = tagName;
66
- ref.node = node;
81
+ if (ref)
82
+ ref.node = node;
67
83
  return node;
68
84
  }
69
85
 
@@ -20,6 +20,7 @@ export declare class Directives {
20
20
  */
21
21
  private atNextDocument?;
22
22
  constructor(yaml?: Directives['yaml'], tags?: Directives['tags']);
23
+ clone(): Directives;
23
24
  /**
24
25
  * During parsing, get a Directives instance for the current document and
25
26
  * update the stream state according to the current version's spec.
@@ -22,6 +22,11 @@ class Directives {
22
22
  this.yaml = Object.assign({}, Directives.defaultYaml, yaml);
23
23
  this.tags = Object.assign({}, Directives.defaultTags, tags);
24
24
  }
25
+ clone() {
26
+ const copy = new Directives(this.yaml, this.tags);
27
+ copy.marker = this.marker;
28
+ return copy;
29
+ }
25
30
  /**
26
31
  * During parsing, get a Directives instance for the current document and
27
32
  * update the stream state according to the current version's spec.
package/dist/errors.d.ts CHANGED
@@ -1,18 +1,21 @@
1
1
  import type { LineCounter } from './parse/line-counter';
2
+ export declare type ErrorCode = 'ALIAS_PROPS' | 'BAD_ALIAS' | 'BAD_DIRECTIVE' | 'BAD_DQ_ESCAPE' | 'BAD_INDENT' | 'BAD_PROP_ORDER' | 'BAD_SCALAR_START' | 'BLOCK_AS_IMPLICIT_KEY' | 'BLOCK_IN_FLOW' | 'DUPLICATE_KEY' | 'IMPOSSIBLE' | 'KEY_OVER_1024_CHARS' | 'MISSING_CHAR' | 'MULTILINE_IMPLICIT_KEY' | 'MULTIPLE_ANCHORS' | 'MULTIPLE_DOCS' | 'MULTIPLE_TAGS' | 'TAB_AS_INDENT' | 'TAG_RESOLVE_FAILED' | 'UNEXPECTED_TOKEN';
3
+ export declare type LinePos = {
4
+ line: number;
5
+ col: number;
6
+ };
2
7
  export declare class YAMLError extends Error {
3
8
  name: 'YAMLParseError' | 'YAMLWarning';
9
+ code: ErrorCode;
4
10
  message: string;
5
- offset: number;
6
- linePos?: {
7
- line: number;
8
- col: number;
9
- };
10
- constructor(name: YAMLError['name'], offset: number, message: string);
11
+ pos: [number, number];
12
+ linePos?: [LinePos] | [LinePos, LinePos];
13
+ constructor(name: YAMLError['name'], pos: [number, number], code: ErrorCode, message: string);
11
14
  }
12
15
  export declare class YAMLParseError extends YAMLError {
13
- constructor(offset: number, message: string);
16
+ constructor(pos: [number, number], code: ErrorCode, message: string);
14
17
  }
15
18
  export declare class YAMLWarning extends YAMLError {
16
- constructor(offset: number, message: string);
19
+ constructor(pos: [number, number], code: ErrorCode, message: string);
17
20
  }
18
21
  export declare const prettifyError: (src: string, lc: LineCounter) => (error: YAMLError) => void;
package/dist/errors.js CHANGED
@@ -1,30 +1,29 @@
1
1
  'use strict';
2
2
 
3
3
  class YAMLError extends Error {
4
- constructor(name, offset, message) {
5
- if (!message)
6
- throw new Error(`Invalid arguments for new ${name}`);
4
+ constructor(name, pos, code, message) {
7
5
  super();
8
6
  this.name = name;
7
+ this.code = code;
9
8
  this.message = message;
10
- this.offset = offset;
9
+ this.pos = pos;
11
10
  }
12
11
  }
13
12
  class YAMLParseError extends YAMLError {
14
- constructor(offset, message) {
15
- super('YAMLParseError', offset, message);
13
+ constructor(pos, code, message) {
14
+ super('YAMLParseError', pos, code, message);
16
15
  }
17
16
  }
18
17
  class YAMLWarning extends YAMLError {
19
- constructor(offset, message) {
20
- super('YAMLWarning', offset, message);
18
+ constructor(pos, code, message) {
19
+ super('YAMLWarning', pos, code, message);
21
20
  }
22
21
  }
23
22
  const prettifyError = (src, lc) => (error) => {
24
- if (error.offset === -1)
23
+ if (error.pos[0] === -1)
25
24
  return;
26
- error.linePos = lc.linePos(error.offset);
27
- const { line, col } = error.linePos;
25
+ error.linePos = error.pos.map(pos => lc.linePos(pos));
26
+ const { line, col } = error.linePos[0];
28
27
  error.message += ` at line ${line}, column ${col}`;
29
28
  let ci = col - 1;
30
29
  let lineStr = src
@@ -47,7 +46,12 @@ const prettifyError = (src, lc) => (error) => {
47
46
  lineStr = prev + lineStr;
48
47
  }
49
48
  if (/[^ ]/.test(lineStr)) {
50
- const pointer = ' '.repeat(ci) + '^';
49
+ let count = 1;
50
+ const end = error.linePos[1];
51
+ if (end && end.line === line && end.col > col) {
52
+ count = Math.min(end.col - col, 80 - ci);
53
+ }
54
+ const pointer = ' '.repeat(ci) + '^'.repeat(count);
51
55
  error.message += `:\n\n${lineStr}\n${pointer}\n`;
52
56
  }
53
57
  };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { Composer } from './compose/composer.js';
2
2
  export { Document } from './doc/Document.js';
3
- export { Schema } from './doc/Schema.js';
3
+ export { Schema } from './schema/Schema.js';
4
4
  export { YAMLError, YAMLParseError, YAMLWarning } from './errors.js';
5
5
  export { Alias } from './nodes/Alias.js';
6
6
  export { isAlias, isCollection, isDocument, isMap, isNode, isPair, isScalar, isSeq, Node, ParsedNode } from './nodes/Node.js';
@@ -8,10 +8,12 @@ export { Pair } from './nodes/Pair.js';
8
8
  export { Scalar } from './nodes/Scalar.js';
9
9
  export { YAMLMap } from './nodes/YAMLMap.js';
10
10
  export { YAMLSeq } from './nodes/YAMLSeq.js';
11
- export { CreateNodeOptions, defaultOptions, Options, SchemaOptions, ToJSOptions, ToStringOptions } from './options.js';
11
+ export { CreateNodeOptions, defaultOptions, DocumentOptions, ParseOptions, SchemaOptions, ToJSOptions, ToStringOptions } from './options.js';
12
+ export * as CST from './parse/cst.js';
12
13
  export { Lexer } from './parse/lexer.js';
13
14
  export { LineCounter } from './parse/line-counter.js';
14
15
  export { Parser } from './parse/parser.js';
15
- export * as tokens from './parse/tokens.js';
16
16
  export { EmptyStream, parse, parseAllDocuments, parseDocument, stringify } from './public-api.js';
17
+ export type { TagId, Tags } from './schema/tags';
18
+ export type { CollectionTag, ScalarTag } from './schema/types';
17
19
  export { visit, visitor, visitorFn } from './visit.js';
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  var composer = require('./compose/composer.js');
4
4
  var Document = require('./doc/Document.js');
5
- var Schema = require('./doc/Schema.js');
5
+ var Schema = require('./schema/Schema.js');
6
6
  var errors = require('./errors.js');
7
7
  var Alias = require('./nodes/Alias.js');
8
8
  var Node = require('./nodes/Node.js');
@@ -11,10 +11,10 @@ var Scalar = require('./nodes/Scalar.js');
11
11
  var YAMLMap = require('./nodes/YAMLMap.js');
12
12
  var YAMLSeq = require('./nodes/YAMLSeq.js');
13
13
  var options = require('./options.js');
14
+ var cst = require('./parse/cst.js');
14
15
  var lexer = require('./parse/lexer.js');
15
16
  var lineCounter = require('./parse/line-counter.js');
16
17
  var parser = require('./parse/parser.js');
17
- var tokens = require('./parse/tokens.js');
18
18
  var publicApi = require('./public-api.js');
19
19
  var visit = require('./visit.js');
20
20
 
@@ -40,10 +40,10 @@ exports.Scalar = Scalar.Scalar;
40
40
  exports.YAMLMap = YAMLMap.YAMLMap;
41
41
  exports.YAMLSeq = YAMLSeq.YAMLSeq;
42
42
  exports.defaultOptions = options.defaultOptions;
43
+ exports.CST = cst;
43
44
  exports.Lexer = lexer.Lexer;
44
45
  exports.LineCounter = lineCounter.LineCounter;
45
46
  exports.Parser = parser.Parser;
46
- exports.tokens = tokens;
47
47
  exports.parse = publicApi.parse;
48
48
  exports.parseAllDocuments = publicApi.parseAllDocuments;
49
49
  exports.parseDocument = publicApi.parseDocument;
@@ -1,14 +1,24 @@
1
- import { StringifyContext } from '../stringify/stringify.js';
2
- import { Node, NodeBase } from './Node.js';
3
- import { ToJSContext } from './toJS.js';
1
+ import type { Document } from '../doc/Document';
2
+ import type { StringifyContext } from '../stringify/stringify.js';
3
+ import { NodeBase, Range } from './Node.js';
4
+ import type { Scalar } from './Scalar';
5
+ import type { ToJSContext } from './toJS.js';
6
+ import type { YAMLMap } from './YAMLMap';
7
+ import type { YAMLSeq } from './YAMLSeq';
4
8
  export declare namespace Alias {
5
9
  interface Parsed extends Alias {
6
- range: [number, number];
10
+ range: Range;
7
11
  }
8
12
  }
9
- export declare class Alias<T extends Node = Node> extends NodeBase {
10
- source: T;
11
- constructor(source: T);
12
- toJSON(arg?: unknown, ctx?: ToJSContext): any;
13
- toString({ anchors, doc, implicitKey, inStringifyKey }: StringifyContext, _onComment?: () => void, _onChompKeep?: () => void): string;
13
+ export declare class Alias extends NodeBase {
14
+ source: string;
15
+ anchor?: never;
16
+ constructor(source: string);
17
+ /**
18
+ * Resolve the value of this alias within `doc`, finding the last
19
+ * instance of the `source` anchor before this node.
20
+ */
21
+ resolve(doc: Document): Scalar | YAMLMap | YAMLSeq | undefined;
22
+ toJSON(_arg?: unknown, ctx?: ToJSContext): unknown;
23
+ toString(ctx?: StringifyContext, _onComment?: () => void, _onChompKeep?: () => void): string;
14
24
  }