yaml 2.0.0-4 → 2.0.0-5

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 (210) 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 +20 -17
  5. package/browser/dist/compose/compose-scalar.js +20 -23
  6. package/browser/dist/compose/composer.js +105 -76
  7. package/browser/dist/compose/resolve-block-map.js +38 -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 +6 -7
  11. package/browser/dist/compose/resolve-flow-collection.js +153 -199
  12. package/browser/dist/compose/resolve-flow-scalar.js +49 -25
  13. package/browser/dist/compose/resolve-props.js +47 -35
  14. package/browser/dist/compose/util-contains-newline.js +15 -12
  15. package/browser/dist/doc/Document.js +50 -99
  16. package/browser/dist/doc/anchors.js +72 -0
  17. package/browser/dist/doc/createNode.js +27 -17
  18. package/browser/dist/errors.js +16 -12
  19. package/browser/dist/index.js +3 -3
  20. package/browser/dist/nodes/Alias.js +51 -28
  21. package/browser/dist/nodes/Collection.js +5 -83
  22. package/browser/dist/nodes/Node.js +2 -1
  23. package/browser/dist/nodes/Pair.js +9 -232
  24. package/browser/dist/nodes/YAMLMap.js +8 -4
  25. package/browser/dist/nodes/YAMLSeq.js +7 -4
  26. package/browser/dist/nodes/addPairToJSMap.js +103 -0
  27. package/browser/dist/nodes/toJS.js +12 -10
  28. package/browser/dist/options.js +0 -2
  29. package/browser/dist/parse/cst-scalar.js +219 -0
  30. package/browser/dist/parse/cst-stringify.js +61 -0
  31. package/browser/dist/parse/cst-visit.js +97 -0
  32. package/{dist/parse/tokens.js → browser/dist/parse/cst.js} +12 -7
  33. package/browser/dist/parse/lexer.js +99 -105
  34. package/browser/dist/parse/parser.js +219 -144
  35. package/browser/dist/public-api.js +11 -14
  36. package/browser/dist/schema/Schema.js +23 -0
  37. package/browser/dist/{tags/failsafe → schema/common}/map.js +0 -0
  38. package/browser/dist/schema/common/null.js +13 -0
  39. package/browser/dist/{tags/failsafe → schema/common}/seq.js +1 -1
  40. package/browser/dist/{tags/failsafe → schema/common}/string.js +0 -0
  41. package/browser/dist/schema/core/bool.js +19 -0
  42. package/browser/dist/schema/core/float.js +40 -0
  43. package/browser/dist/schema/core/int.js +38 -0
  44. package/browser/dist/schema/core/schema.js +23 -0
  45. package/browser/dist/{tags/json.js → schema/json/schema.js} +5 -6
  46. package/browser/dist/schema/tags.js +79 -0
  47. package/browser/dist/{tags → schema}/yaml-1.1/binary.js +0 -0
  48. package/browser/dist/schema/yaml-1.1/bool.js +26 -0
  49. package/browser/dist/schema/yaml-1.1/float.js +43 -0
  50. package/browser/dist/schema/yaml-1.1/int.js +71 -0
  51. package/browser/dist/{tags → schema}/yaml-1.1/omap.js +0 -0
  52. package/browser/dist/{tags → schema}/yaml-1.1/pairs.js +9 -6
  53. package/browser/dist/schema/yaml-1.1/schema.js +37 -0
  54. package/browser/dist/{tags → schema}/yaml-1.1/set.js +0 -0
  55. package/browser/dist/{tags → schema}/yaml-1.1/timestamp.js +0 -0
  56. package/browser/dist/stringify/addComment.js +1 -7
  57. package/browser/dist/stringify/stringify.js +8 -6
  58. package/browser/dist/stringify/stringifyCollection.js +108 -0
  59. package/browser/dist/stringify/stringifyDocument.js +61 -0
  60. package/browser/dist/stringify/stringifyPair.js +113 -0
  61. package/browser/dist/stringify/stringifyString.js +53 -52
  62. package/browser/dist/visit.js +20 -1
  63. package/dist/compose/compose-collection.d.ts +4 -4
  64. package/dist/compose/compose-collection.js +12 -9
  65. package/dist/compose/compose-doc.d.ts +4 -3
  66. package/dist/compose/compose-doc.js +23 -6
  67. package/dist/compose/compose-node.d.ts +15 -7
  68. package/dist/compose/compose-node.js +20 -17
  69. package/dist/compose/compose-scalar.d.ts +4 -3
  70. package/dist/compose/compose-scalar.js +19 -22
  71. package/dist/compose/composer.d.ts +28 -23
  72. package/dist/compose/composer.js +106 -77
  73. package/dist/compose/resolve-block-map.d.ts +4 -4
  74. package/dist/compose/resolve-block-map.js +38 -29
  75. package/dist/compose/resolve-block-scalar.d.ts +5 -3
  76. package/dist/compose/resolve-block-scalar.js +14 -17
  77. package/dist/compose/resolve-block-seq.d.ts +4 -4
  78. package/dist/compose/resolve-block-seq.js +21 -17
  79. package/dist/compose/resolve-end.d.ts +3 -2
  80. package/dist/compose/resolve-end.js +6 -7
  81. package/dist/compose/resolve-flow-collection.d.ts +4 -5
  82. package/dist/compose/resolve-flow-collection.js +152 -198
  83. package/dist/compose/resolve-flow-scalar.d.ts +5 -3
  84. package/dist/compose/resolve-flow-scalar.js +49 -25
  85. package/dist/compose/resolve-props.d.ts +17 -10
  86. package/dist/compose/resolve-props.js +47 -35
  87. package/dist/compose/util-contains-newline.d.ts +1 -1
  88. package/dist/compose/util-contains-newline.js +15 -12
  89. package/dist/compose/util-empty-scalar-position.d.ts +1 -1
  90. package/dist/doc/Document.d.ts +27 -15
  91. package/dist/doc/Document.js +48 -97
  92. package/dist/doc/anchors.d.ts +24 -0
  93. package/dist/doc/anchors.js +77 -0
  94. package/dist/doc/createNode.d.ts +8 -10
  95. package/dist/doc/createNode.js +26 -16
  96. package/dist/errors.d.ts +11 -8
  97. package/dist/errors.js +16 -12
  98. package/dist/index.d.ts +5 -3
  99. package/dist/index.js +3 -3
  100. package/dist/nodes/Alias.d.ts +19 -9
  101. package/dist/nodes/Alias.js +51 -28
  102. package/dist/nodes/Collection.d.ts +3 -17
  103. package/dist/nodes/Collection.js +4 -82
  104. package/dist/nodes/Node.d.ts +6 -4
  105. package/dist/nodes/Node.js +2 -0
  106. package/dist/nodes/Pair.d.ts +6 -11
  107. package/dist/nodes/Pair.js +8 -231
  108. package/dist/nodes/Scalar.d.ts +6 -3
  109. package/dist/nodes/YAMLMap.d.ts +3 -3
  110. package/dist/nodes/YAMLMap.js +8 -4
  111. package/dist/nodes/YAMLSeq.d.ts +3 -3
  112. package/dist/nodes/YAMLSeq.js +7 -4
  113. package/dist/nodes/addPairToJSMap.d.ts +3 -0
  114. package/dist/nodes/addPairToJSMap.js +105 -0
  115. package/dist/nodes/toJS.d.ts +4 -5
  116. package/dist/nodes/toJS.js +12 -10
  117. package/dist/options.d.ts +20 -26
  118. package/dist/options.js +0 -2
  119. package/dist/parse/cst-scalar.d.ts +58 -0
  120. package/dist/parse/cst-scalar.js +223 -0
  121. package/dist/parse/cst-stringify.d.ts +8 -0
  122. package/dist/parse/cst-stringify.js +63 -0
  123. package/dist/parse/cst-visit.d.ts +39 -0
  124. package/dist/parse/cst-visit.js +99 -0
  125. package/dist/parse/{tokens.d.ts → cst.d.ts} +23 -7
  126. package/{browser/dist/parse/tokens.js → dist/parse/cst.js} +27 -1
  127. package/dist/parse/lexer.d.ts +4 -13
  128. package/dist/parse/lexer.js +100 -106
  129. package/dist/parse/parser.d.ts +30 -24
  130. package/dist/parse/parser.js +221 -146
  131. package/dist/public-api.d.ts +7 -7
  132. package/dist/public-api.js +11 -14
  133. package/dist/{doc → schema}/Schema.d.ts +5 -3
  134. package/dist/schema/Schema.js +25 -0
  135. package/dist/{tags/failsafe → schema/common}/map.d.ts +0 -0
  136. package/dist/{tags/failsafe → schema/common}/map.js +0 -0
  137. package/dist/schema/common/null.d.ts +4 -0
  138. package/dist/schema/common/null.js +15 -0
  139. package/dist/{tags/failsafe → schema/common}/seq.d.ts +0 -0
  140. package/dist/{tags/failsafe → schema/common}/seq.js +1 -1
  141. package/dist/{tags/failsafe → schema/common}/string.d.ts +0 -0
  142. package/dist/{tags/failsafe → schema/common}/string.js +0 -0
  143. package/dist/schema/core/bool.d.ts +4 -0
  144. package/dist/schema/core/bool.js +21 -0
  145. package/dist/schema/core/float.d.ts +4 -0
  146. package/dist/schema/core/float.js +44 -0
  147. package/dist/schema/core/int.d.ts +4 -0
  148. package/dist/schema/core/int.js +42 -0
  149. package/dist/schema/core/schema.d.ts +1 -0
  150. package/dist/schema/core/schema.js +25 -0
  151. package/dist/schema/json/schema.d.ts +2 -0
  152. package/dist/{tags/json.js → schema/json/schema.js} +5 -6
  153. package/dist/schema/tags.d.ts +41 -0
  154. package/dist/schema/tags.js +82 -0
  155. package/dist/{tags → schema}/types.d.ts +3 -7
  156. package/dist/{tags → schema}/yaml-1.1/binary.d.ts +0 -0
  157. package/dist/{tags → schema}/yaml-1.1/binary.js +0 -0
  158. package/dist/schema/yaml-1.1/bool.d.ts +7 -0
  159. package/dist/schema/yaml-1.1/bool.js +29 -0
  160. package/dist/schema/yaml-1.1/float.d.ts +4 -0
  161. package/dist/schema/yaml-1.1/float.js +47 -0
  162. package/dist/schema/yaml-1.1/int.d.ts +5 -0
  163. package/dist/schema/yaml-1.1/int.js +76 -0
  164. package/dist/{tags → schema}/yaml-1.1/omap.d.ts +0 -0
  165. package/dist/{tags → schema}/yaml-1.1/omap.js +0 -0
  166. package/dist/{tags → schema}/yaml-1.1/pairs.d.ts +3 -2
  167. package/dist/{tags → schema}/yaml-1.1/pairs.js +9 -6
  168. package/dist/schema/yaml-1.1/schema.d.ts +1 -0
  169. package/dist/schema/yaml-1.1/schema.js +39 -0
  170. package/dist/{tags → schema}/yaml-1.1/set.d.ts +1 -1
  171. package/dist/{tags → schema}/yaml-1.1/set.js +0 -0
  172. package/dist/{tags → schema}/yaml-1.1/timestamp.d.ts +0 -0
  173. package/dist/{tags → schema}/yaml-1.1/timestamp.js +0 -0
  174. package/dist/stringify/addComment.js +0 -7
  175. package/dist/stringify/stringify.d.ts +1 -2
  176. package/dist/stringify/stringify.js +8 -6
  177. package/dist/stringify/stringifyCollection.d.ts +21 -0
  178. package/dist/stringify/stringifyCollection.js +110 -0
  179. package/dist/stringify/stringifyDocument.d.ts +3 -0
  180. package/dist/stringify/stringifyDocument.js +63 -0
  181. package/dist/stringify/stringifyPair.d.ts +3 -0
  182. package/dist/stringify/stringifyPair.js +115 -0
  183. package/dist/stringify/stringifyString.js +53 -52
  184. package/dist/test-events.d.ts +1 -2
  185. package/dist/test-events.js +25 -12
  186. package/dist/util.d.ts +1 -1
  187. package/dist/visit.d.ts +10 -1
  188. package/dist/visit.js +20 -1
  189. package/package.json +4 -3
  190. package/browser/dist/doc/Anchors.js +0 -102
  191. package/browser/dist/doc/Schema.js +0 -27
  192. package/browser/dist/doc/getSchemaTags.js +0 -30
  193. package/browser/dist/tags/core.js +0 -109
  194. package/browser/dist/tags/failsafe/index.js +0 -7
  195. package/browser/dist/tags/index.js +0 -34
  196. package/browser/dist/tags/yaml-1.1/index.js +0 -152
  197. package/dist/doc/Anchors.d.ts +0 -36
  198. package/dist/doc/Anchors.js +0 -104
  199. package/dist/doc/Schema.js +0 -29
  200. package/dist/doc/getSchemaTags.d.ts +0 -3
  201. package/dist/doc/getSchemaTags.js +0 -32
  202. package/dist/tags/core.d.ts +0 -14
  203. package/dist/tags/core.js +0 -119
  204. package/dist/tags/failsafe/index.d.ts +0 -1
  205. package/dist/tags/failsafe/index.js +0 -9
  206. package/dist/tags/index.d.ts +0 -31
  207. package/dist/tags/index.js +0 -37
  208. package/dist/tags/json.d.ts +0 -2
  209. package/dist/tags/yaml-1.1/index.d.ts +0 -2
  210. package/dist/tags/yaml-1.1/index.js +0 -154
@@ -1,5 +1,5 @@
1
+ import { tokenType } from './cst.js';
1
2
  import { Lexer } from './lexer.js';
2
- import { tokenType } from './tokens.js';
3
3
 
4
4
  function includesToken(list, type) {
5
5
  for (let i = 0; i < list.length; ++i)
@@ -87,6 +87,7 @@ function getFirstKeyStartProps(prev) {
87
87
  let i = prev.length;
88
88
  loop: while (--i >= 0) {
89
89
  switch (prev[i].type) {
90
+ case 'doc-start':
90
91
  case 'explicit-key-ind':
91
92
  case 'map-value-ind':
92
93
  case 'seq-item-ind':
@@ -99,31 +100,62 @@ function getFirstKeyStartProps(prev) {
99
100
  }
100
101
  return prev.splice(i, prev.length);
101
102
  }
103
+ function fixFlowSeqItems(fc) {
104
+ if (fc.start.type === 'flow-seq-start') {
105
+ for (const it of fc.items) {
106
+ if (it.sep &&
107
+ !it.value &&
108
+ !includesToken(it.start, 'explicit-key-ind') &&
109
+ !includesToken(it.sep, 'map-value-ind')) {
110
+ if (it.key)
111
+ it.value = it.key;
112
+ delete it.key;
113
+ if (isFlowToken(it.value)) {
114
+ if (it.value.end)
115
+ Array.prototype.push.apply(it.value.end, it.sep);
116
+ else
117
+ it.value.end = it.sep;
118
+ }
119
+ else
120
+ Array.prototype.push.apply(it.start, it.sep);
121
+ delete it.sep;
122
+ }
123
+ }
124
+ }
125
+ }
102
126
  /**
103
127
  * A YAML concrete syntax tree (CST) parser
104
128
  *
105
- * While the `parse()` method provides an API for parsing a source string
106
- * directly, the parser may also be used with a user-provided lexer:
107
- *
108
129
  * ```ts
109
- * const cst: Token[] = []
110
- * const parser = new Parser(tok => cst.push(tok))
111
130
  * const src: string = ...
131
+ * for (const token of new Parser().parse(src)) {
132
+ * // token: Token
133
+ * }
134
+ * ```
135
+ *
136
+ * To use the parser with a user-provided lexer:
112
137
  *
113
- * // The following would be equivalent to `parser.parse(src, false)`
114
- * const lexer = new Lexer(parser.next)
115
- * lexer.lex(src, false)
116
- * parser.end()
138
+ * ```ts
139
+ * function* parse(source: string, lexer: Lexer) {
140
+ * const parser = new Parser()
141
+ * for (const lexeme of lexer.lex(source))
142
+ * yield* parser.next(lexeme)
143
+ * yield* parser.end()
144
+ * }
145
+ *
146
+ * const src: string = ...
147
+ * const lexer = new Lexer()
148
+ * for (const token of parse(src, lexer)) {
149
+ * // token: Token
150
+ * }
117
151
  * ```
118
152
  */
119
153
  class Parser {
120
154
  /**
121
- * @param push - Called separately with each parsed token
122
155
  * @param onNewLine - If defined, called separately with the start position of
123
156
  * each new line (in `parse()`, including the start of input).
124
- * @public
125
157
  */
126
- constructor(push, onNewLine) {
158
+ constructor(onNewLine) {
127
159
  /** If true, space and sequence indicators count as indentation */
128
160
  this.atNewLine = true;
129
161
  /** If true, next token is a scalar value */
@@ -140,94 +172,95 @@ class Parser {
140
172
  this.source = '';
141
173
  /** The type of the current token, set in parse() */
142
174
  this.type = '';
143
- /**
144
- * Advance the parser by the `source` of one lexical token. Bound to the
145
- * Parser instance, so may be used directly as a callback function.
146
- */
147
- this.next = (source) => {
148
- this.source = source;
149
- if (this.atScalar) {
150
- this.atScalar = false;
151
- this.step();
152
- this.offset += source.length;
153
- return;
154
- }
155
- const type = tokenType(source);
156
- if (!type) {
157
- const message = `Not a YAML token: ${source}`;
158
- this.pop({ type: 'error', offset: this.offset, message, source });
159
- this.offset += source.length;
160
- }
161
- else if (type === 'scalar') {
162
- this.atNewLine = false;
163
- this.atScalar = true;
164
- this.type = 'scalar';
165
- }
166
- else {
167
- this.type = type;
168
- this.step();
169
- switch (type) {
170
- case 'newline':
171
- this.atNewLine = true;
172
- this.indent = 0;
173
- if (this.onNewLine)
174
- this.onNewLine(this.offset + source.length);
175
- break;
176
- case 'space':
177
- if (this.atNewLine && source[0] === ' ')
178
- this.indent += source.length;
179
- break;
180
- case 'explicit-key-ind':
181
- case 'map-value-ind':
182
- case 'seq-item-ind':
183
- if (this.atNewLine)
184
- this.indent += source.length;
185
- break;
186
- case 'doc-mode':
187
- return;
188
- default:
189
- this.atNewLine = false;
190
- }
191
- this.offset += source.length;
192
- }
193
- };
194
175
  // Must be defined after `next()`
195
- this.lexer = new Lexer(this.next);
196
- this.push = push;
176
+ this.lexer = new Lexer();
197
177
  this.onNewLine = onNewLine;
198
178
  }
199
179
  /**
200
- * Parse `source` as a YAML stream, calling `push` with each directive,
201
- * document and other structure as it is completely parsed. If `incomplete`,
202
- * a part of the last line may be left as a buffer for the next call.
180
+ * Parse `source` as a YAML stream.
181
+ * If `incomplete`, a part of the last line may be left as a buffer for the next call.
203
182
  *
204
- * Errors are not thrown, but pushed out as `{ type: 'error', message }` tokens.
205
- * @public
183
+ * Errors are not thrown, but yielded as `{ type: 'error', message }` tokens.
184
+ *
185
+ * @returns A generator of tokens representing each directive, document, and other structure.
206
186
  */
207
- parse(source, incomplete = false) {
187
+ *parse(source, incomplete = false) {
208
188
  if (this.onNewLine && this.offset === 0)
209
189
  this.onNewLine(0);
210
- this.lexer.lex(source, incomplete);
190
+ for (const lexeme of this.lexer.lex(source, incomplete))
191
+ yield* this.next(lexeme);
211
192
  if (!incomplete)
212
- this.end();
193
+ yield* this.end();
194
+ }
195
+ /**
196
+ * Advance the parser by the `source` of one lexical token.
197
+ */
198
+ *next(source) {
199
+ this.source = source;
200
+ if (this.atScalar) {
201
+ this.atScalar = false;
202
+ yield* this.step();
203
+ this.offset += source.length;
204
+ return;
205
+ }
206
+ const type = tokenType(source);
207
+ if (!type) {
208
+ const message = `Not a YAML token: ${source}`;
209
+ yield* this.pop({ type: 'error', offset: this.offset, message, source });
210
+ this.offset += source.length;
211
+ }
212
+ else if (type === 'scalar') {
213
+ this.atNewLine = false;
214
+ this.atScalar = true;
215
+ this.type = 'scalar';
216
+ }
217
+ else {
218
+ this.type = type;
219
+ yield* this.step();
220
+ switch (type) {
221
+ case 'newline':
222
+ this.atNewLine = true;
223
+ this.indent = 0;
224
+ if (this.onNewLine)
225
+ this.onNewLine(this.offset + source.length);
226
+ break;
227
+ case 'space':
228
+ if (this.atNewLine && source[0] === ' ')
229
+ this.indent += source.length;
230
+ break;
231
+ case 'explicit-key-ind':
232
+ case 'map-value-ind':
233
+ case 'seq-item-ind':
234
+ if (this.atNewLine)
235
+ this.indent += source.length;
236
+ break;
237
+ case 'doc-mode':
238
+ return;
239
+ default:
240
+ this.atNewLine = false;
241
+ }
242
+ this.offset += source.length;
243
+ }
213
244
  }
214
245
  /** Call at end of input to push out any remaining constructions */
215
- end() {
246
+ *end() {
216
247
  while (this.stack.length > 0)
217
- this.pop();
248
+ yield* this.pop();
218
249
  }
219
250
  get sourceToken() {
220
- return {
251
+ const st = {
221
252
  type: this.type,
253
+ offset: this.offset,
222
254
  indent: this.indent,
223
255
  source: this.source
224
256
  };
257
+ return st;
225
258
  }
226
- step() {
259
+ *step() {
227
260
  const top = this.peek(1);
228
261
  if (this.type === 'doc-end' && (!top || top.type !== 'doc-end')) {
229
262
  while (this.stack.length > 0)
230
- this.pop();
263
+ yield* this.pop();
231
264
  this.stack.push({
232
265
  type: 'doc-end',
233
266
  offset: this.offset,
@@ -236,47 +269,49 @@ class Parser {
236
269
  return;
237
270
  }
238
271
  if (!top)
239
- return this.stream();
272
+ return yield* this.stream();
240
273
  switch (top.type) {
241
274
  case 'document':
242
- return this.document(top);
275
+ return yield* this.document(top);
243
276
  case 'alias':
244
277
  case 'scalar':
245
278
  case 'single-quoted-scalar':
246
279
  case 'double-quoted-scalar':
247
- return this.scalar(top);
280
+ return yield* this.scalar(top);
248
281
  case 'block-scalar':
249
- return this.blockScalar(top);
282
+ return yield* this.blockScalar(top);
250
283
  case 'block-map':
251
- return this.blockMap(top);
284
+ return yield* this.blockMap(top);
252
285
  case 'block-seq':
253
- return this.blockSequence(top);
286
+ return yield* this.blockSequence(top);
254
287
  case 'flow-collection':
255
- return this.flowCollection(top);
288
+ return yield* this.flowCollection(top);
256
289
  case 'doc-end':
257
- return this.documentEnd(top);
290
+ return yield* this.documentEnd(top);
258
291
  }
259
292
  /* istanbul ignore next should not happen */
260
- this.pop();
293
+ yield* this.pop();
261
294
  }
262
295
  peek(n) {
263
296
  return this.stack[this.stack.length - n];
264
297
  }
265
- pop(error) {
298
+ *pop(error) {
266
299
  const token = error || this.stack.pop();
267
300
  /* istanbul ignore if should not happen */
268
301
  if (!token) {
269
302
  const message = 'Tried to pop an empty stack';
270
- this.push({ type: 'error', source: '', message });
303
+ yield { type: 'error', offset: this.offset, source: '', message };
271
304
  }
272
305
  else if (this.stack.length === 0) {
273
- this.push(token);
306
+ yield token;
274
307
  }
275
308
  else {
276
309
  const top = this.peek(1);
277
310
  // For these, parent indent is needed instead of own
278
311
  if (token.type === 'block-scalar' || token.type === 'flow-collection')
279
312
  token.indent = 'indent' in top ? top.indent : -1;
313
+ if (token.type === 'flow-collection')
314
+ fixFlowSeqItems(token);
280
315
  switch (top.type) {
281
316
  case 'document':
282
317
  top.value = token;
@@ -309,13 +344,20 @@ class Parser {
309
344
  it.value = token;
310
345
  break;
311
346
  }
312
- case 'flow-collection':
313
- top.items.push(token);
314
- break;
347
+ case 'flow-collection': {
348
+ const it = top.items[top.items.length - 1];
349
+ if (!it || it.value)
350
+ top.items.push({ start: [], key: token, sep: [] });
351
+ else if (it.sep)
352
+ it.value = token;
353
+ else
354
+ Object.assign(it, { key: token, sep: [] });
355
+ return;
356
+ }
315
357
  /* istanbul ignore next should not happen */
316
358
  default:
317
- this.pop();
318
- this.pop(token);
359
+ yield* this.pop();
360
+ yield* this.pop(token);
319
361
  }
320
362
  if ((top.type === 'document' ||
321
363
  top.type === 'block-map' ||
@@ -338,16 +380,16 @@ class Parser {
338
380
  }
339
381
  }
340
382
  }
341
- stream() {
383
+ *stream() {
342
384
  switch (this.type) {
343
385
  case 'directive-line':
344
- this.push({ type: 'directive', source: this.source });
386
+ yield { type: 'directive', offset: this.offset, source: this.source };
345
387
  return;
346
388
  case 'byte-order-mark':
347
389
  case 'space':
348
390
  case 'comment':
349
391
  case 'newline':
350
- this.push(this.sourceToken);
392
+ yield this.sourceToken;
351
393
  return;
352
394
  case 'doc-mode':
353
395
  case 'doc-start': {
@@ -362,21 +404,21 @@ class Parser {
362
404
  return;
363
405
  }
364
406
  }
365
- this.push({
407
+ yield {
366
408
  type: 'error',
367
409
  offset: this.offset,
368
410
  message: `Unexpected ${this.type} token in YAML stream`,
369
411
  source: this.source
370
- });
412
+ };
371
413
  }
372
- document(doc) {
414
+ *document(doc) {
373
415
  if (doc.value)
374
- return this.lineEnd(doc);
416
+ return yield* this.lineEnd(doc);
375
417
  switch (this.type) {
376
418
  case 'doc-start': {
377
419
  if (includesNonEmpty(doc.start)) {
378
- this.pop();
379
- this.step();
420
+ yield* this.pop();
421
+ yield* this.step();
380
422
  }
381
423
  else
382
424
  doc.start.push(this.sourceToken);
@@ -394,15 +436,15 @@ class Parser {
394
436
  if (bv)
395
437
  this.stack.push(bv);
396
438
  else {
397
- this.push({
439
+ yield {
398
440
  type: 'error',
399
441
  offset: this.offset,
400
442
  message: `Unexpected ${this.type} token in YAML document`,
401
443
  source: this.source
402
- });
444
+ };
403
445
  }
404
446
  }
405
- scalar(scalar) {
447
+ *scalar(scalar) {
406
448
  if (this.type === 'map-value-ind') {
407
449
  const prev = getPrevProps(this.peek(2));
408
450
  const start = getFirstKeyStartProps(prev);
@@ -424,9 +466,9 @@ class Parser {
424
466
  this.stack[this.stack.length - 1] = map;
425
467
  }
426
468
  else
427
- this.lineEnd(scalar);
469
+ yield* this.lineEnd(scalar);
428
470
  }
429
- blockScalar(scalar) {
471
+ *blockScalar(scalar) {
430
472
  switch (this.type) {
431
473
  case 'space':
432
474
  case 'comment':
@@ -445,15 +487,15 @@ class Parser {
445
487
  nl = this.source.indexOf('\n', nl) + 1;
446
488
  }
447
489
  }
448
- this.pop();
490
+ yield* this.pop();
449
491
  break;
450
492
  /* istanbul ignore next should not happen */
451
493
  default:
452
- this.pop();
453
- this.step();
494
+ yield* this.pop();
495
+ yield* this.step();
454
496
  }
455
497
  }
456
- blockMap(map) {
498
+ *blockMap(map) {
457
499
  var _a;
458
500
  const it = map.items[map.items.length - 1];
459
501
  // it.sep is true-ish if pair already has key or : separator
@@ -574,10 +616,10 @@ class Parser {
574
616
  }
575
617
  }
576
618
  }
577
- this.pop();
578
- this.step();
619
+ yield* this.pop();
620
+ yield* this.step();
579
621
  }
580
- blockSequence(seq) {
622
+ *blockSequence(seq) {
581
623
  var _a;
582
624
  const it = seq.items[seq.items.length - 1];
583
625
  switch (this.type) {
@@ -616,38 +658,65 @@ class Parser {
616
658
  }
617
659
  if (this.indent > seq.indent) {
618
660
  const bv = this.startBlockValue(seq);
619
- if (bv)
620
- return this.stack.push(bv);
661
+ if (bv) {
662
+ this.stack.push(bv);
663
+ return;
664
+ }
621
665
  }
622
- this.pop();
623
- this.step();
666
+ yield* this.pop();
667
+ yield* this.step();
624
668
  }
625
- flowCollection(fc) {
669
+ *flowCollection(fc) {
670
+ const it = fc.items[fc.items.length - 1];
626
671
  if (this.type === 'flow-error-end') {
627
672
  let top;
628
673
  do {
629
- this.pop();
674
+ yield* this.pop();
630
675
  top = this.peek(1);
631
676
  } while (top && top.type === 'flow-collection');
632
677
  }
633
678
  else if (fc.end.length === 0) {
634
679
  switch (this.type) {
635
- case 'space':
636
- case 'comment':
637
- case 'newline':
638
680
  case 'comma':
639
681
  case 'explicit-key-ind':
682
+ if (!it || it.sep)
683
+ fc.items.push({ start: [this.sourceToken] });
684
+ else
685
+ it.start.push(this.sourceToken);
686
+ return;
640
687
  case 'map-value-ind':
688
+ if (!it || it.value)
689
+ fc.items.push({ start: [], key: null, sep: [this.sourceToken] });
690
+ else if (it.sep)
691
+ it.sep.push(this.sourceToken);
692
+ else
693
+ Object.assign(it, { key: null, sep: [this.sourceToken] });
694
+ return;
695
+ case 'space':
696
+ case 'comment':
697
+ case 'newline':
641
698
  case 'anchor':
642
699
  case 'tag':
643
- fc.items.push(this.sourceToken);
700
+ if (!it || it.value)
701
+ fc.items.push({ start: [this.sourceToken] });
702
+ else if (it.sep)
703
+ it.sep.push(this.sourceToken);
704
+ else
705
+ it.start.push(this.sourceToken);
644
706
  return;
645
707
  case 'alias':
646
708
  case 'scalar':
647
709
  case 'single-quoted-scalar':
648
- case 'double-quoted-scalar':
649
- fc.items.push(this.flowScalar(this.type));
710
+ case 'double-quoted-scalar': {
711
+ const fs = this.flowScalar(this.type);
712
+ if (!it || it.value)
713
+ fc.items.push({ start: [], key: fs, sep: [] });
714
+ else if (it.sep)
715
+ this.stack.push(fs);
716
+ else
717
+ Object.assign(it, { key: fs, sep: [] });
650
718
  return;
719
+ }
651
720
  case 'flow-map-end':
652
721
  case 'flow-seq-end':
653
722
  fc.end.push(this.sourceToken);
@@ -656,10 +725,10 @@ class Parser {
656
725
  const bv = this.startBlockValue(fc);
657
726
  /* istanbul ignore else should not happen */
658
727
  if (bv)
659
- return this.stack.push(bv);
728
+ this.stack.push(bv);
660
729
  else {
661
- this.pop();
662
- this.step();
730
+ yield* this.pop();
731
+ yield* this.step();
663
732
  }
664
733
  }
665
734
  else {
@@ -668,13 +737,14 @@ class Parser {
668
737
  (this.type === 'map-value-ind' ||
669
738
  (this.type === 'newline' &&
670
739
  !parent.items[parent.items.length - 1].sep))) {
671
- this.pop();
672
- this.step();
740
+ yield* this.pop();
741
+ yield* this.step();
673
742
  }
674
743
  else if (this.type === 'map-value-ind' &&
675
744
  parent.type !== 'flow-collection') {
676
745
  const prev = getPrevProps(parent);
677
746
  const start = getFirstKeyStartProps(prev);
747
+ fixFlowSeqItems(fc);
678
748
  const sep = fc.end.splice(1, fc.end.length);
679
749
  sep.push(this.sourceToken);
680
750
  const map = {
@@ -687,7 +757,7 @@ class Parser {
687
757
  this.stack[this.stack.length - 1] = map;
688
758
  }
689
759
  else {
690
- this.lineEnd(fc);
760
+ yield* this.lineEnd(fc);
691
761
  }
692
762
  }
693
763
  }
@@ -718,7 +788,8 @@ class Parser {
718
788
  type: 'block-scalar',
719
789
  offset: this.offset,
720
790
  indent: this.indent,
721
- props: [this.sourceToken]
791
+ props: [this.sourceToken],
792
+ source: ''
722
793
  };
723
794
  case 'flow-map-start':
724
795
  case 'flow-seq-start':
@@ -737,14 +808,18 @@ class Parser {
737
808
  indent: this.indent,
738
809
  items: [{ start: [this.sourceToken] }]
739
810
  };
740
- case 'explicit-key-ind':
811
+ case 'explicit-key-ind': {
741
812
  this.onKeyLine = true;
813
+ const prev = getPrevProps(parent);
814
+ const start = getFirstKeyStartProps(prev);
815
+ start.push(this.sourceToken);
742
816
  return {
743
817
  type: 'block-map',
744
818
  offset: this.offset,
745
819
  indent: this.indent,
746
- items: [{ start: [this.sourceToken] }]
820
+ items: [{ start }]
747
821
  };
822
+ }
748
823
  case 'map-value-ind': {
749
824
  this.onKeyLine = true;
750
825
  const prev = getPrevProps(parent);
@@ -759,17 +834,17 @@ class Parser {
759
834
  }
760
835
  return null;
761
836
  }
762
- documentEnd(docEnd) {
837
+ *documentEnd(docEnd) {
763
838
  if (this.type !== 'doc-mode') {
764
839
  if (docEnd.end)
765
840
  docEnd.end.push(this.sourceToken);
766
841
  else
767
842
  docEnd.end = [this.sourceToken];
768
843
  if (this.type === 'newline')
769
- this.pop();
844
+ yield* this.pop();
770
845
  }
771
846
  }
772
- lineEnd(token) {
847
+ *lineEnd(token) {
773
848
  switch (this.type) {
774
849
  case 'comma':
775
850
  case 'doc-start':
@@ -777,8 +852,8 @@ class Parser {
777
852
  case 'flow-seq-end':
778
853
  case 'flow-map-end':
779
854
  case 'map-value-ind':
780
- this.pop();
781
- this.step();
855
+ yield* this.pop();
856
+ yield* this.step();
782
857
  break;
783
858
  case 'newline':
784
859
  this.onKeyLine = false;
@@ -792,7 +867,7 @@ class Parser {
792
867
  else
793
868
  token.end = [this.sourceToken];
794
869
  if (this.type === 'newline')
795
- this.pop();
870
+ yield* this.pop();
796
871
  }
797
872
  }
798
873
  }
@@ -21,13 +21,11 @@ function parseOptions(options) {
21
21
  * EmptyStream and contain additional stream information. In
22
22
  * TypeScript, you should use `'empty' in docs` as a type guard for it.
23
23
  */
24
- function parseAllDocuments(source, options) {
24
+ function parseAllDocuments(source, options = {}) {
25
25
  const { lineCounter, prettyErrors } = parseOptions(options);
26
- const docs = [];
27
- const composer = new Composer(doc => docs.push(doc), options);
28
- const parser = new Parser(composer.next, lineCounter === null || lineCounter === void 0 ? void 0 : lineCounter.addNewLine);
29
- parser.parse(source);
30
- composer.end();
26
+ const parser = new Parser(lineCounter === null || lineCounter === void 0 ? void 0 : lineCounter.addNewLine);
27
+ const composer = new Composer(options);
28
+ const docs = Array.from(composer.compose(parser.parse(source)));
31
29
  if (prettyErrors && lineCounter)
32
30
  for (const doc of docs) {
33
31
  doc.errors.forEach(prettifyError(source, lineCounter));
@@ -38,21 +36,20 @@ function parseAllDocuments(source, options) {
38
36
  return Object.assign([], { empty: true }, composer.streamInfo());
39
37
  }
40
38
  /** Parse an input string into a single YAML.Document */
41
- function parseDocument(source, options) {
39
+ function parseDocument(source, options = {}) {
42
40
  const { lineCounter, prettyErrors } = parseOptions(options);
41
+ const parser = new Parser(lineCounter === null || lineCounter === void 0 ? void 0 : lineCounter.addNewLine);
42
+ const composer = new Composer(options);
43
43
  // `doc` is always set by compose.end(true) at the very latest
44
44
  let doc = null;
45
- const composer = new Composer(_doc => {
45
+ for (const _doc of composer.compose(parser.parse(source), true, source.length)) {
46
46
  if (!doc)
47
47
  doc = _doc;
48
48
  else if (doc.options.logLevel !== 'silent') {
49
- const errMsg = 'Source contains multiple documents; please use YAML.parseAllDocuments()';
50
- doc.errors.push(new YAMLParseError(_doc.range[0], errMsg));
49
+ doc.errors.push(new YAMLParseError(_doc.range.slice(0, 2), 'MULTIPLE_DOCS', 'Source contains multiple documents; please use YAML.parseAllDocuments()'));
50
+ break;
51
51
  }
52
- }, options);
53
- const parser = new Parser(composer.next, lineCounter === null || lineCounter === void 0 ? void 0 : lineCounter.addNewLine);
54
- parser.parse(source);
55
- composer.end(true, source.length);
52
+ }
56
53
  if (prettyErrors && lineCounter) {
57
54
  doc.errors.forEach(prettifyError(source, lineCounter));
58
55
  doc.warnings.forEach(prettifyError(source, lineCounter));