yaml 2.0.0-7 → 2.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 (123) hide show
  1. package/README.md +1 -1
  2. package/browser/dist/compose/compose-doc.js +3 -2
  3. package/browser/dist/compose/compose-node.js +14 -3
  4. package/browser/dist/compose/compose-scalar.js +17 -10
  5. package/browser/dist/compose/composer.js +6 -7
  6. package/browser/dist/compose/resolve-block-map.js +19 -5
  7. package/browser/dist/compose/resolve-block-scalar.js +12 -3
  8. package/browser/dist/compose/resolve-block-seq.js +5 -0
  9. package/browser/dist/compose/resolve-flow-collection.js +18 -6
  10. package/browser/dist/compose/resolve-flow-scalar.js +9 -2
  11. package/browser/dist/compose/resolve-props.js +4 -0
  12. package/browser/dist/compose/util-flow-indent-check.js +15 -0
  13. package/browser/dist/doc/Document.js +73 -16
  14. package/browser/dist/doc/anchors.js +2 -2
  15. package/browser/dist/doc/createNode.js +12 -7
  16. package/browser/dist/doc/directives.js +11 -3
  17. package/browser/dist/index.js +1 -2
  18. package/browser/dist/node_modules/tslib/tslib.es6.js +164 -0
  19. package/browser/dist/nodes/Collection.js +28 -15
  20. package/browser/dist/nodes/Node.js +7 -0
  21. package/browser/dist/nodes/Pair.js +11 -3
  22. package/browser/dist/nodes/Scalar.js +1 -1
  23. package/browser/dist/nodes/YAMLMap.js +6 -5
  24. package/browser/dist/nodes/YAMLSeq.js +2 -2
  25. package/browser/dist/nodes/addPairToJSMap.js +3 -2
  26. package/browser/dist/nodes/toJS.js +3 -1
  27. package/browser/dist/parse/cst-scalar.js +2 -6
  28. package/browser/dist/parse/cst-visit.js +2 -2
  29. package/browser/dist/parse/lexer.js +50 -22
  30. package/browser/dist/parse/parser.js +121 -45
  31. package/browser/dist/public-api.js +4 -5
  32. package/browser/dist/schema/Schema.js +19 -4
  33. package/browser/dist/schema/common/null.js +3 -1
  34. package/browser/dist/schema/core/float.js +4 -1
  35. package/browser/dist/schema/tags.js +17 -13
  36. package/browser/dist/schema/yaml-1.1/float.js +4 -1
  37. package/browser/dist/schema/yaml-1.1/omap.js +1 -1
  38. package/browser/dist/schema/yaml-1.1/pairs.js +2 -1
  39. package/browser/dist/stringify/stringify.js +53 -23
  40. package/browser/dist/stringify/stringifyCollection.js +115 -85
  41. package/browser/dist/stringify/stringifyComment.js +18 -12
  42. package/browser/dist/stringify/stringifyDocument.js +37 -15
  43. package/browser/dist/stringify/stringifyPair.js +35 -21
  44. package/browser/dist/stringify/stringifyString.js +41 -43
  45. package/browser/dist/util.js +3 -0
  46. package/browser/dist/visit.js +150 -62
  47. package/dist/compose/compose-doc.js +3 -2
  48. package/dist/compose/compose-node.d.ts +1 -0
  49. package/dist/compose/compose-node.js +14 -3
  50. package/dist/compose/compose-scalar.js +16 -9
  51. package/dist/compose/composer.d.ts +1 -1
  52. package/dist/compose/composer.js +8 -9
  53. package/dist/compose/resolve-block-map.js +19 -5
  54. package/dist/compose/resolve-block-scalar.js +12 -3
  55. package/dist/compose/resolve-block-seq.js +5 -0
  56. package/dist/compose/resolve-flow-collection.js +18 -6
  57. package/dist/compose/resolve-flow-scalar.js +9 -2
  58. package/dist/compose/resolve-props.d.ts +1 -1
  59. package/dist/compose/resolve-props.js +4 -0
  60. package/dist/compose/util-flow-indent-check.d.ts +3 -0
  61. package/dist/compose/util-flow-indent-check.js +17 -0
  62. package/dist/doc/Document.d.ts +13 -4
  63. package/dist/doc/Document.js +79 -22
  64. package/dist/doc/anchors.d.ts +2 -2
  65. package/dist/doc/anchors.js +2 -2
  66. package/dist/doc/createNode.d.ts +3 -2
  67. package/dist/doc/createNode.js +11 -6
  68. package/dist/doc/directives.d.ts +5 -2
  69. package/dist/doc/directives.js +11 -3
  70. package/dist/index.d.ts +4 -4
  71. package/dist/index.js +1 -2
  72. package/dist/node_modules/tslib/tslib.es6.js +76 -0
  73. package/dist/nodes/Alias.d.ts +7 -3
  74. package/dist/nodes/Collection.d.ts +10 -4
  75. package/dist/nodes/Collection.js +27 -14
  76. package/dist/nodes/Node.d.ts +6 -1
  77. package/dist/nodes/Node.js +7 -0
  78. package/dist/nodes/Pair.d.ts +7 -2
  79. package/dist/nodes/Pair.js +10 -2
  80. package/dist/nodes/Scalar.d.ts +2 -0
  81. package/dist/nodes/Scalar.js +1 -1
  82. package/dist/nodes/YAMLMap.d.ts +5 -1
  83. package/dist/nodes/YAMLMap.js +6 -5
  84. package/dist/nodes/YAMLSeq.d.ts +2 -0
  85. package/dist/nodes/YAMLSeq.js +2 -2
  86. package/dist/nodes/addPairToJSMap.js +2 -1
  87. package/dist/nodes/toJS.js +3 -1
  88. package/dist/options.d.ts +67 -15
  89. package/dist/parse/cst-scalar.d.ts +6 -0
  90. package/dist/parse/cst-scalar.js +2 -6
  91. package/dist/parse/cst-visit.js +2 -2
  92. package/dist/parse/lexer.d.ts +2 -0
  93. package/dist/parse/lexer.js +50 -22
  94. package/dist/parse/parser.js +121 -45
  95. package/dist/public-api.js +4 -5
  96. package/dist/schema/Schema.d.ts +6 -4
  97. package/dist/schema/Schema.js +18 -3
  98. package/dist/schema/common/null.js +3 -1
  99. package/dist/schema/core/float.js +4 -1
  100. package/dist/schema/tags.d.ts +1 -2
  101. package/dist/schema/tags.js +17 -13
  102. package/dist/schema/yaml-1.1/float.js +4 -1
  103. package/dist/schema/yaml-1.1/omap.js +1 -1
  104. package/dist/schema/yaml-1.1/pairs.js +2 -1
  105. package/dist/stringify/stringify.d.ts +5 -3
  106. package/dist/stringify/stringify.js +53 -23
  107. package/dist/stringify/stringifyCollection.d.ts +2 -6
  108. package/dist/stringify/stringifyCollection.js +114 -84
  109. package/dist/stringify/stringifyComment.d.ts +10 -2
  110. package/dist/stringify/stringifyComment.js +19 -12
  111. package/dist/stringify/stringifyDocument.js +36 -14
  112. package/dist/stringify/stringifyPair.js +34 -20
  113. package/dist/stringify/stringifyString.js +41 -43
  114. package/dist/test-events.d.ts +1 -1
  115. package/dist/test-events.js +13 -12
  116. package/dist/util.d.ts +3 -0
  117. package/dist/util.js +6 -0
  118. package/dist/visit.d.ts +49 -10
  119. package/dist/visit.js +149 -60
  120. package/package.json +12 -10
  121. package/util.d.ts +3 -0
  122. package/browser/dist/options.js +0 -17
  123. package/dist/options.js +0 -19
package/dist/options.d.ts CHANGED
@@ -5,7 +5,7 @@ import type { ParsedNode } from './nodes/Node.js';
5
5
  import type { Pair } from './nodes/Pair.js';
6
6
  import type { Scalar } from './nodes/Scalar.js';
7
7
  import type { LineCounter } from './parse/line-counter.js';
8
- import type { SchemaName } from './schema/Schema.js';
8
+ import type { Schema } from './schema/Schema.js';
9
9
  import type { Tags } from './schema/tags.js';
10
10
  import type { CollectionTag, ScalarTag } from './schema/types.js';
11
11
  export declare type ParseOptions = {
@@ -17,6 +17,13 @@ export declare type ParseOptions = {
17
17
  * https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/BigInt
18
18
  */
19
19
  intAsBigInt?: boolean;
20
+ /**
21
+ * Include a `srcToken` value on each parsed `Node`, containing the CST token
22
+ * that was composed into this node.
23
+ *
24
+ * Default: `false`
25
+ */
26
+ keepSourceTokens?: boolean;
20
27
  /**
21
28
  * If set, newlines will be tracked, to allow for `lineCounter.linePos(offset)`
22
29
  * to provide the `{ line, col }` positions within the input.
@@ -66,9 +73,17 @@ export declare type DocumentOptions = {
66
73
  *
67
74
  * Default: `"1.2"`
68
75
  */
69
- version?: '1.1' | '1.2';
76
+ version?: '1.1' | '1.2' | 'next';
70
77
  };
71
78
  export declare type SchemaOptions = {
79
+ /**
80
+ * When parsing, warn about compatibility issues with the given schema.
81
+ * When stringifying, use scalar styles that are parsed correctly
82
+ * by the `compat` schema as well as the actual schema.
83
+ *
84
+ * Default: `null`
85
+ */
86
+ compat?: string | Tags | null;
72
87
  /**
73
88
  * Array of additional tags to include in the schema, or a function that may
74
89
  * modify the schema's base tag array.
@@ -92,9 +107,18 @@ export declare type SchemaOptions = {
92
107
  /**
93
108
  * The base schema to use.
94
109
  *
95
- * Default: `"core"` for YAML 1.2, `"yaml-1.1"` for earlier versions
110
+ * The core library has built-in support for the following:
111
+ * - `'failsafe'`: A minimal schema that parses all scalars as strings
112
+ * - `'core'`: The YAML 1.2 core schema
113
+ * - `'json'`: The YAML 1.2 JSON schema, with minimal rules for JSON compatibility
114
+ * - `'yaml-1.1'`: The YAML 1.1 schema
115
+ *
116
+ * If using another (custom) schema, the `customTags` array needs to
117
+ * fully define the schema's tags.
118
+ *
119
+ * Default: `'core'` for YAML 1.2, `'yaml-1.1'` for earlier versions
96
120
  */
97
- schema?: SchemaName;
121
+ schema?: string | Schema;
98
122
  /**
99
123
  * When adding to or stringifying a map, sort the entries.
100
124
  * If `true`, sort by comparing key values with `<`.
@@ -103,8 +127,19 @@ export declare type SchemaOptions = {
103
127
  * Default: `false`
104
128
  */
105
129
  sortMapEntries?: boolean | ((a: Pair, b: Pair) => number);
130
+ /**
131
+ * Override default values for `toString()` options.
132
+ */
133
+ toStringDefaults?: ToStringOptions;
106
134
  };
107
135
  export declare type CreateNodeOptions = {
136
+ /**
137
+ * During node construction, use anchors and aliases to keep strictly equal
138
+ * non-null objects as equivalent in YAML.
139
+ *
140
+ * Default: `true`
141
+ */
142
+ aliasDuplicateObjects?: boolean;
108
143
  /**
109
144
  * Default prefix for anchors.
110
145
  *
@@ -154,6 +189,30 @@ export declare type ToJSOptions = {
154
189
  reviver?: Reviver;
155
190
  };
156
191
  export declare type ToStringOptions = {
192
+ /**
193
+ * Use block quote styles for scalar values where applicable.
194
+ * Set to `false` to disable block quotes completely.
195
+ *
196
+ * Default: `true`
197
+ */
198
+ blockQuote?: boolean | 'folded' | 'literal';
199
+ /**
200
+ * Enforce `'block'` or `'flow'` style on maps and sequences.
201
+ * Empty collections will always be stringified as `{}` or `[]`.
202
+ *
203
+ * Default: `'any'`, allowing each node to set its style separately
204
+ * with its `flow: boolean` (default `false`) property.
205
+ */
206
+ collectionStyle?: 'any' | 'block' | 'flow';
207
+ /**
208
+ * Comment stringifier.
209
+ * Output should be valid for the current schema.
210
+ *
211
+ * By default, empty comment lines are left empty,
212
+ * lines consisting of a single space are replaced by `#`,
213
+ * and all other lines are prefixed with a `#`.
214
+ */
215
+ commentString?: (comment: string) => string;
157
216
  /**
158
217
  * The default type of string literal used to stringify implicit key values.
159
218
  * Output may use other types if required to fully represent the value.
@@ -247,11 +306,12 @@ export declare type ToStringOptions = {
247
306
  */
248
307
  simpleKeys?: boolean;
249
308
  /**
250
- * Prefer 'single quote' rather than "double quote" where applicable.
309
+ * Use 'single quote' rather than "double quote" where applicable.
310
+ * Set to `false` to disable single quotes completely.
251
311
  *
252
- * Default: `false`
312
+ * Default: `null`
253
313
  */
254
- singleQuote?: boolean;
314
+ singleQuote?: boolean | null;
255
315
  /**
256
316
  * String representation for `true`.
257
317
  * With the core schema, use `'true'`, `'True'`, or `'TRUE'`.
@@ -268,11 +328,3 @@ export declare type ToStringOptions = {
268
328
  */
269
329
  verifyAliasOrder?: boolean;
270
330
  };
271
- /**
272
- * `yaml` defines document-specific options in three places: as an argument of
273
- * parse, create and stringify calls, in the values of `YAML.defaultOptions`,
274
- * and in the version-dependent `YAML.Document.defaults` object. Values set in
275
- * `YAML.defaultOptions` override version-dependent defaults, and argument
276
- * options override both.
277
- */
278
- export declare const defaultOptions: Required<Omit<ParseOptions, 'lineCounter'> & Omit<DocumentOptions, 'directives'>>;
@@ -6,6 +6,12 @@ import type { BlockScalar, FlowScalar, SourceToken, Token } from './cst.js';
6
6
  * If `token` is a CST flow or block scalar, determine its string value and a few other attributes.
7
7
  * Otherwise, return `null`.
8
8
  */
9
+ export declare function resolveAsScalar(token: FlowScalar | BlockScalar, strict?: boolean, onError?: (offset: number, code: ErrorCode, message: string) => void): {
10
+ value: string;
11
+ type: Scalar.Type | null;
12
+ comment: string;
13
+ range: Range;
14
+ };
9
15
  export declare function resolveAsScalar(token: Token | null | undefined, strict?: boolean, onError?: (offset: number, code: ErrorCode, message: string) => void): {
10
16
  value: string;
11
17
  type: Scalar.Type | null;
@@ -5,10 +5,6 @@ var resolveFlowScalar = require('../compose/resolve-flow-scalar.js');
5
5
  var errors = require('../errors.js');
6
6
  var stringifyString = require('../stringify/stringifyString.js');
7
7
 
8
- /**
9
- * If `token` is a CST flow or block scalar, determine its string value and a few other attributes.
10
- * Otherwise, return `null`.
11
- */
12
8
  function resolveAsScalar(token, strict = true, onError) {
13
9
  if (token) {
14
10
  const _onError = (pos, code, message) => {
@@ -50,7 +46,7 @@ function createScalarToken(value, context) {
50
46
  implicitKey,
51
47
  indent: indent > 0 ? ' '.repeat(indent) : '',
52
48
  inFlow,
53
- options: { lineWidth: -1 }
49
+ options: { blockQuote: true, lineWidth: -1 }
54
50
  });
55
51
  const end = (_a = context.end) !== null && _a !== void 0 ? _a : [
56
52
  { type: 'newline', offset: -1, indent, source: '\n' }
@@ -119,7 +115,7 @@ function setScalarValue(token, value, context = {}) {
119
115
  implicitKey: implicitKey || indent === null,
120
116
  indent: indent !== null && indent > 0 ? ' '.repeat(indent) : '',
121
117
  inFlow,
122
- options: { lineWidth: -1 }
118
+ options: { blockQuote: true, lineWidth: -1 }
123
119
  });
124
120
  switch (source[0]) {
125
121
  case '|':
@@ -49,7 +49,7 @@ visit.REMOVE = REMOVE;
49
49
  visit.itemAtPath = (cst, path) => {
50
50
  let item = cst;
51
51
  for (const [field, index] of path) {
52
- const tok = item && item[field];
52
+ const tok = item === null || item === void 0 ? void 0 : item[field];
53
53
  if (tok && 'items' in tok) {
54
54
  item = tok.items[index];
55
55
  }
@@ -66,7 +66,7 @@ visit.itemAtPath = (cst, path) => {
66
66
  visit.parentCollection = (cst, path) => {
67
67
  const parent = visit.itemAtPath(cst, path.slice(0, -1));
68
68
  const field = path[path.length - 1][0];
69
- const coll = parent && parent[field];
69
+ const coll = parent === null || parent === void 0 ? void 0 : parent[field];
70
70
  if (coll && 'items' in coll)
71
71
  return coll;
72
72
  throw new Error('Parent collection not found');
@@ -47,6 +47,8 @@ export declare class Lexer {
47
47
  private indentNext;
48
48
  /** Indentation level of the current line. */
49
49
  private indentValue;
50
+ /** Position of the next \n character. */
51
+ private lineEndPos;
50
52
  /** Stores the state of the lexer if reaching the end of incpomplete input */
51
53
  private next;
52
54
  /** A pointer to `buffer`; the current position of the lexer. */
@@ -136,6 +136,8 @@ class Lexer {
136
136
  this.indentNext = 0;
137
137
  /** Indentation level of the current line. */
138
138
  this.indentValue = 0;
139
+ /** Position of the next \n character. */
140
+ this.lineEndPos = null;
139
141
  /** Stores the state of the lexer if reaching the end of incpomplete input */
140
142
  this.next = null;
141
143
  /** A pointer to `buffer`; the current position of the lexer. */
@@ -148,10 +150,13 @@ class Lexer {
148
150
  * @returns A generator of lexical tokens
149
151
  */
150
152
  *lex(source, incomplete = false) {
151
- if (source)
153
+ var _a;
154
+ if (source) {
152
155
  this.buffer = this.buffer ? this.buffer + source : source;
156
+ this.lineEndPos = null;
157
+ }
153
158
  this.atEnd = !incomplete;
154
- let next = this.next || 'stream';
159
+ let next = (_a = this.next) !== null && _a !== void 0 ? _a : 'stream';
155
160
  while (next && (incomplete || this.hasChars(1)))
156
161
  next = yield* this.parseNext(next);
157
162
  }
@@ -192,7 +197,11 @@ class Lexer {
192
197
  return offset;
193
198
  }
194
199
  getLine() {
195
- let end = this.buffer.indexOf('\n', this.pos);
200
+ let end = this.lineEndPos;
201
+ if (typeof end !== 'number' || (end !== -1 && end < this.pos)) {
202
+ end = this.buffer.indexOf('\n', this.pos);
203
+ this.lineEndPos = end;
204
+ }
196
205
  if (end === -1)
197
206
  return this.atEnd ? this.buffer.substring(this.pos) : null;
198
207
  if (this.buffer[end - 1] === '\r')
@@ -205,6 +214,7 @@ class Lexer {
205
214
  setNext(state) {
206
215
  this.buffer = this.buffer.substring(this.pos);
207
216
  this.pos = 0;
217
+ this.lineEndPos = null;
208
218
  this.next = state;
209
219
  return null;
210
220
  }
@@ -350,14 +360,19 @@ class Lexer {
350
360
  let indent = -1;
351
361
  do {
352
362
  nl = yield* this.pushNewline();
353
- sp = yield* this.pushSpaces(true);
354
- if (nl > 0)
363
+ if (nl > 0) {
364
+ sp = yield* this.pushSpaces(false);
355
365
  this.indentValue = indent = sp;
366
+ }
367
+ else {
368
+ sp = 0;
369
+ }
370
+ sp += yield* this.pushSpaces(true);
356
371
  } while (nl + sp > 0);
357
372
  const line = this.getLine();
358
373
  if (line === null)
359
374
  return this.setNext('flow');
360
- if ((indent !== -1 && indent < this.indentNext) ||
375
+ if ((indent !== -1 && indent < this.indentNext && line[0] !== '#') ||
361
376
  (indent === 0 &&
362
377
  (line.startsWith('---') || line.startsWith('...')) &&
363
378
  isEmpty(line[3]))) {
@@ -375,8 +390,11 @@ class Lexer {
375
390
  }
376
391
  }
377
392
  let n = 0;
378
- while (line[n] === ',')
379
- n += (yield* this.pushCount(1)) + (yield* this.pushSpaces(true));
393
+ while (line[n] === ',') {
394
+ n += yield* this.pushCount(1);
395
+ n += yield* this.pushSpaces(true);
396
+ this.flowKey = false;
397
+ }
380
398
  n += yield* this.pushIndicators();
381
399
  switch (line[n]) {
382
400
  case undefined:
@@ -406,6 +424,7 @@ class Lexer {
406
424
  case ':': {
407
425
  const next = this.charAt(1);
408
426
  if (this.flowKey || isEmpty(next) || next === ',') {
427
+ this.flowKey = false;
409
428
  yield* this.pushCount(1);
410
429
  yield* this.pushSpaces(true);
411
430
  return 'flow';
@@ -435,17 +454,19 @@ class Lexer {
435
454
  end = this.buffer.indexOf('"', end + 1);
436
455
  }
437
456
  }
438
- let nl = this.buffer.indexOf('\n', this.pos);
439
- if (nl !== -1 && nl < end) {
440
- while (nl !== -1 && nl < end) {
457
+ // Only looking for newlines within the quotes
458
+ const qb = this.buffer.substring(0, end);
459
+ let nl = qb.indexOf('\n', this.pos);
460
+ if (nl !== -1) {
461
+ while (nl !== -1) {
441
462
  const cs = this.continueScalar(nl + 1);
442
463
  if (cs === -1)
443
464
  break;
444
- nl = this.buffer.indexOf('\n', cs);
465
+ nl = qb.indexOf('\n', cs);
445
466
  }
446
- if (nl !== -1 && nl < end) {
467
+ if (nl !== -1) {
447
468
  // this is an error caused by an unexpected unindent
448
- end = nl - 1;
469
+ end = nl - (qb[nl - 1] === '\r' ? 2 : 1);
449
470
  }
450
471
  }
451
472
  if (end === -1) {
@@ -520,9 +541,10 @@ class Lexer {
520
541
  let ch = this.buffer[i];
521
542
  if (ch === '\r')
522
543
  ch = this.buffer[--i];
544
+ const lastChar = i; // Drop the line if last char not more indented
523
545
  while (ch === ' ' || ch === '\t')
524
546
  ch = this.buffer[--i];
525
- if (ch === '\n' && i >= this.pos)
547
+ if (ch === '\n' && i >= this.pos && i + 1 + indent > lastChar)
526
548
  nl = i;
527
549
  else
528
550
  break;
@@ -545,17 +567,18 @@ class Lexer {
545
567
  end = i;
546
568
  }
547
569
  else if (isEmpty(ch)) {
548
- const next = this.buffer[i + 1];
549
- if (next === '#' || (inFlow && invalidFlowScalarChars.includes(next)))
550
- break;
570
+ let next = this.buffer[i + 1];
551
571
  if (ch === '\r') {
552
572
  if (next === '\n') {
553
573
  i += 1;
554
574
  ch = '\n';
575
+ next = this.buffer[i + 1];
555
576
  }
556
577
  else
557
578
  end = i;
558
579
  }
580
+ if (next === '#' || (inFlow && invalidFlowScalarChars.includes(next)))
581
+ break;
559
582
  if (ch === '\n') {
560
583
  const cs = this.continueScalar(i + 1);
561
584
  if (cs === -1)
@@ -604,16 +627,21 @@ class Lexer {
604
627
  return ((yield* this.pushUntil(isNotAnchorChar)) +
605
628
  (yield* this.pushSpaces(true)) +
606
629
  (yield* this.pushIndicators()));
607
- case ':':
608
- case '?': // this is an error outside flow collections
609
630
  case '-': // this is an error
610
- if (isEmpty(this.charAt(1))) {
611
- if (this.flowLevel === 0)
631
+ case '?': // this is an error outside flow collections
632
+ case ':': {
633
+ const inFlow = this.flowLevel > 0;
634
+ const ch1 = this.charAt(1);
635
+ if (isEmpty(ch1) || (inFlow && invalidFlowScalarChars.includes(ch1))) {
636
+ if (!inFlow)
612
637
  this.indentNext = this.indentValue + 1;
638
+ else if (this.flowKey)
639
+ this.flowKey = false;
613
640
  return ((yield* this.pushCount(1)) +
614
641
  (yield* this.pushSpaces(true)) +
615
642
  (yield* this.pushIndicators()));
616
643
  }
644
+ }
617
645
  }
618
646
  return 0;
619
647
  }
@@ -35,12 +35,13 @@ function isFlowToken(token) {
35
35
  }
36
36
  }
37
37
  function getPrevProps(parent) {
38
+ var _a;
38
39
  switch (parent.type) {
39
40
  case 'document':
40
41
  return parent.start;
41
42
  case 'block-map': {
42
43
  const it = parent.items[parent.items.length - 1];
43
- return it.sep || it.start;
44
+ return (_a = it.sep) !== null && _a !== void 0 ? _a : it.start;
44
45
  }
45
46
  case 'block-seq':
46
47
  return parent.items[parent.items.length - 1].start;
@@ -207,6 +208,7 @@ class Parser {
207
208
  this.indent += source.length;
208
209
  break;
209
210
  case 'doc-mode':
211
+ case 'flow-error-end':
210
212
  return;
211
213
  default:
212
214
  this.atNewLine = false;
@@ -268,7 +270,7 @@ class Parser {
268
270
  return this.stack[this.stack.length - n];
269
271
  }
270
272
  *pop(error) {
271
- const token = error || this.stack.pop();
273
+ const token = error !== null && error !== void 0 ? error : this.stack.pop();
272
274
  /* istanbul ignore if should not happen */
273
275
  if (!token) {
274
276
  const message = 'Tried to pop an empty stack';
@@ -279,9 +281,14 @@ class Parser {
279
281
  }
280
282
  else {
281
283
  const top = this.peek(1);
282
- // For these, parent indent is needed instead of own
283
- if (token.type === 'block-scalar' || token.type === 'flow-collection')
284
- token.indent = 'indent' in top ? top.indent : -1;
284
+ if (token.type === 'block-scalar') {
285
+ // Block scalars use their parent rather than header indent
286
+ token.indent = 'indent' in top ? top.indent : 0;
287
+ }
288
+ else if (token.type === 'flow-collection' && top.type === 'document') {
289
+ // Ignore all indent for top-level flow collections
290
+ token.indent = 0;
291
+ }
285
292
  if (token.type === 'flow-collection')
286
293
  fixFlowSeqItems(token);
287
294
  switch (top.type) {
@@ -512,63 +519,131 @@ class Parser {
512
519
  const atNextItem = !this.onKeyLine &&
513
520
  this.indent === map.indent &&
514
521
  (it.sep || includesNonEmpty(it.start));
522
+ // For empty nodes, assign newline-separated not indented empty tokens to following node
523
+ let start = [];
524
+ if (atNextItem && it.sep && !it.value) {
525
+ const nl = [];
526
+ for (let i = 0; i < it.sep.length; ++i) {
527
+ const st = it.sep[i];
528
+ switch (st.type) {
529
+ case 'newline':
530
+ nl.push(i);
531
+ break;
532
+ case 'space':
533
+ break;
534
+ case 'comment':
535
+ if (st.indent > map.indent)
536
+ nl.length = 0;
537
+ break;
538
+ default:
539
+ nl.length = 0;
540
+ }
541
+ }
542
+ if (nl.length >= 2)
543
+ start = it.sep.splice(nl[1]);
544
+ }
515
545
  switch (this.type) {
516
546
  case 'anchor':
517
547
  case 'tag':
518
548
  if (atNextItem || it.value) {
519
- map.items.push({ start: [this.sourceToken] });
549
+ start.push(this.sourceToken);
550
+ map.items.push({ start });
520
551
  this.onKeyLine = true;
521
552
  }
522
- else if (it.sep)
553
+ else if (it.sep) {
523
554
  it.sep.push(this.sourceToken);
524
- else
555
+ }
556
+ else {
525
557
  it.start.push(this.sourceToken);
558
+ }
526
559
  return;
527
560
  case 'explicit-key-ind':
528
- if (!it.sep && !includesToken(it.start, 'explicit-key-ind'))
561
+ if (!it.sep && !includesToken(it.start, 'explicit-key-ind')) {
529
562
  it.start.push(this.sourceToken);
530
- else if (atNextItem || it.value)
531
- map.items.push({ start: [this.sourceToken] });
532
- else
563
+ }
564
+ else if (atNextItem || it.value) {
565
+ start.push(this.sourceToken);
566
+ map.items.push({ start });
567
+ }
568
+ else {
533
569
  this.stack.push({
534
570
  type: 'block-map',
535
571
  offset: this.offset,
536
572
  indent: this.indent,
537
573
  items: [{ start: [this.sourceToken] }]
538
574
  });
575
+ }
539
576
  this.onKeyLine = true;
540
577
  return;
541
578
  case 'map-value-ind':
542
- if (!it.sep)
543
- Object.assign(it, { key: null, sep: [this.sourceToken] });
544
- else if (it.value ||
545
- (atNextItem && !includesToken(it.start, 'explicit-key-ind')))
546
- map.items.push({ start: [], key: null, sep: [this.sourceToken] });
547
- else if (includesToken(it.sep, 'map-value-ind'))
548
- this.stack.push({
549
- type: 'block-map',
550
- offset: this.offset,
551
- indent: this.indent,
552
- items: [{ start: [], key: null, sep: [this.sourceToken] }]
553
- });
554
- else if (includesToken(it.start, 'explicit-key-ind') &&
555
- isFlowToken(it.key) &&
556
- !includesToken(it.sep, 'newline')) {
557
- const start = getFirstKeyStartProps(it.start);
558
- const key = it.key;
559
- const sep = it.sep;
560
- sep.push(this.sourceToken);
561
- // @ts-ignore type guard is wrong here
562
- delete it.key, delete it.sep;
563
- this.stack.push({
564
- type: 'block-map',
565
- offset: this.offset,
566
- indent: this.indent,
567
- items: [{ start, key, sep }]
568
- });
579
+ if (includesToken(it.start, 'explicit-key-ind')) {
580
+ if (!it.sep) {
581
+ if (includesToken(it.start, 'newline')) {
582
+ Object.assign(it, { key: null, sep: [this.sourceToken] });
583
+ }
584
+ else {
585
+ const start = getFirstKeyStartProps(it.start);
586
+ this.stack.push({
587
+ type: 'block-map',
588
+ offset: this.offset,
589
+ indent: this.indent,
590
+ items: [{ start, key: null, sep: [this.sourceToken] }]
591
+ });
592
+ }
593
+ }
594
+ else if (it.value) {
595
+ map.items.push({ start: [], key: null, sep: [this.sourceToken] });
596
+ }
597
+ else if (includesToken(it.sep, 'map-value-ind')) {
598
+ this.stack.push({
599
+ type: 'block-map',
600
+ offset: this.offset,
601
+ indent: this.indent,
602
+ items: [{ start, key: null, sep: [this.sourceToken] }]
603
+ });
604
+ }
605
+ else if (isFlowToken(it.key) &&
606
+ !includesToken(it.sep, 'newline')) {
607
+ const start = getFirstKeyStartProps(it.start);
608
+ const key = it.key;
609
+ const sep = it.sep;
610
+ sep.push(this.sourceToken);
611
+ // @ts-expect-error type guard is wrong here
612
+ delete it.key, delete it.sep;
613
+ this.stack.push({
614
+ type: 'block-map',
615
+ offset: this.offset,
616
+ indent: this.indent,
617
+ items: [{ start, key, sep }]
618
+ });
619
+ }
620
+ else if (start.length > 0) {
621
+ // Not actually at next item
622
+ it.sep = it.sep.concat(start, this.sourceToken);
623
+ }
624
+ else {
625
+ it.sep.push(this.sourceToken);
626
+ }
627
+ }
628
+ else {
629
+ if (!it.sep) {
630
+ Object.assign(it, { key: null, sep: [this.sourceToken] });
631
+ }
632
+ else if (it.value || atNextItem) {
633
+ map.items.push({ start, key: null, sep: [this.sourceToken] });
634
+ }
635
+ else if (includesToken(it.sep, 'map-value-ind')) {
636
+ this.stack.push({
637
+ type: 'block-map',
638
+ offset: this.offset,
639
+ indent: this.indent,
640
+ items: [{ start: [], key: null, sep: [this.sourceToken] }]
641
+ });
642
+ }
643
+ else {
644
+ it.sep.push(this.sourceToken);
645
+ }
569
646
  }
570
- else
571
- it.sep.push(this.sourceToken);
572
647
  this.onKeyLine = true;
573
648
  return;
574
649
  case 'alias':
@@ -577,7 +652,7 @@ class Parser {
577
652
  case 'double-quoted-scalar': {
578
653
  const fs = this.flowScalar(this.type);
579
654
  if (atNextItem || it.value) {
580
- map.items.push({ start: [], key: fs, sep: [] });
655
+ map.items.push({ start, key: fs, sep: [] });
581
656
  this.onKeyLine = true;
582
657
  }
583
658
  else if (it.sep) {
@@ -594,8 +669,9 @@ class Parser {
594
669
  if (bv) {
595
670
  if (atNextItem &&
596
671
  bv.type !== 'block-seq' &&
597
- includesToken(it.start, 'explicit-key-ind'))
598
- map.items.push({ start: [] });
672
+ includesToken(it.start, 'explicit-key-ind')) {
673
+ map.items.push({ start });
674
+ }
599
675
  this.stack.push(bv);
600
676
  return;
601
677
  }
@@ -732,7 +808,7 @@ class Parser {
732
808
  else {
733
809
  const parent = this.peek(2);
734
810
  if (parent.type === 'block-map' &&
735
- (this.type === 'map-value-ind' ||
811
+ ((this.type === 'map-value-ind' && parent.indent === fc.indent) ||
736
812
  (this.type === 'newline' &&
737
813
  !parent.items[parent.items.length - 1].sep))) {
738
814
  yield* this.pop();
@@ -8,10 +8,8 @@ var lineCounter = require('./parse/line-counter.js');
8
8
  var parser = require('./parse/parser.js');
9
9
 
10
10
  function parseOptions(options) {
11
- const prettyErrors = !options || options.prettyErrors !== false;
12
- const lineCounter$1 = (options && options.lineCounter) ||
13
- (prettyErrors && new lineCounter.LineCounter()) ||
14
- null;
11
+ const prettyErrors = options.prettyErrors !== false;
12
+ const lineCounter$1 = options.lineCounter || (prettyErrors && new lineCounter.LineCounter()) || null;
15
13
  return { lineCounter: lineCounter$1, prettyErrors };
16
14
  }
17
15
  /**
@@ -79,6 +77,7 @@ function parse(src, reviver, options) {
79
77
  return doc.toJS(Object.assign({ reviver: _reviver }, options));
80
78
  }
81
79
  function stringify(value, replacer, options) {
80
+ var _a;
82
81
  let _replacer = null;
83
82
  if (typeof replacer === 'function' || Array.isArray(replacer)) {
84
83
  _replacer = replacer;
@@ -93,7 +92,7 @@ function stringify(value, replacer, options) {
93
92
  options = indent < 1 ? undefined : indent > 8 ? { indent: 8 } : { indent };
94
93
  }
95
94
  if (value === undefined) {
96
- const { keepUndefined } = options || replacer || {};
95
+ const { keepUndefined } = (_a = options !== null && options !== void 0 ? options : replacer) !== null && _a !== void 0 ? _a : {};
97
96
  if (!keepUndefined)
98
97
  return undefined;
99
98
  }