yaml 2.0.0-9 → 2.1.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 (120) hide show
  1. package/README.md +1 -1
  2. package/browser/dist/compose/compose-collection.js +1 -1
  3. package/browser/dist/compose/compose-doc.js +4 -3
  4. package/browser/dist/compose/compose-node.js +13 -4
  5. package/browser/dist/compose/compose-scalar.js +18 -13
  6. package/browser/dist/compose/composer.js +8 -10
  7. package/browser/dist/compose/resolve-block-map.js +15 -8
  8. package/browser/dist/compose/resolve-block-scalar.js +12 -3
  9. package/browser/dist/compose/resolve-block-seq.js +5 -0
  10. package/browser/dist/compose/resolve-flow-collection.js +13 -5
  11. package/browser/dist/compose/resolve-flow-scalar.js +1 -1
  12. package/browser/dist/compose/resolve-props.js +9 -1
  13. package/browser/dist/compose/util-empty-scalar-position.js +1 -1
  14. package/browser/dist/compose/util-flow-indent-check.js +15 -0
  15. package/browser/dist/doc/Document.js +53 -20
  16. package/browser/dist/doc/anchors.js +2 -2
  17. package/browser/dist/doc/createNode.js +8 -7
  18. package/browser/dist/doc/directives.js +7 -4
  19. package/browser/dist/index.js +1 -2
  20. package/browser/dist/nodes/Collection.js +2 -1
  21. package/browser/dist/nodes/Pair.js +2 -2
  22. package/browser/dist/nodes/Scalar.js +1 -1
  23. package/browser/dist/nodes/YAMLMap.js +7 -7
  24. package/browser/dist/nodes/YAMLSeq.js +2 -10
  25. package/browser/dist/nodes/addPairToJSMap.js +1 -1
  26. package/browser/dist/nodes/toJS.js +3 -1
  27. package/browser/dist/parse/cst-scalar.js +1 -2
  28. package/browser/dist/parse/cst-visit.js +2 -2
  29. package/browser/dist/parse/lexer.js +20 -8
  30. package/browser/dist/parse/parser.js +142 -68
  31. package/browser/dist/public-api.js +5 -7
  32. package/browser/dist/schema/Schema.js +14 -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 +9 -9
  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 +1 -1
  39. package/browser/dist/schema/yaml-1.1/set.js +4 -0
  40. package/browser/dist/stringify/stringify.js +49 -22
  41. package/browser/dist/stringify/stringifyCollection.js +114 -85
  42. package/browser/dist/stringify/stringifyComment.js +18 -12
  43. package/browser/dist/stringify/stringifyDocument.js +36 -15
  44. package/browser/dist/stringify/stringifyPair.js +34 -20
  45. package/browser/dist/stringify/stringifyString.js +8 -11
  46. package/browser/dist/visit.js +149 -62
  47. package/dist/compose/compose-collection.js +1 -1
  48. package/dist/compose/compose-doc.js +4 -3
  49. package/dist/compose/compose-node.d.ts +1 -0
  50. package/dist/compose/compose-node.js +13 -4
  51. package/dist/compose/compose-scalar.js +17 -12
  52. package/dist/compose/composer.d.ts +1 -1
  53. package/dist/compose/composer.js +10 -12
  54. package/dist/compose/resolve-block-map.js +15 -8
  55. package/dist/compose/resolve-block-scalar.js +12 -3
  56. package/dist/compose/resolve-block-seq.js +5 -0
  57. package/dist/compose/resolve-flow-collection.js +13 -5
  58. package/dist/compose/resolve-flow-scalar.js +1 -1
  59. package/dist/compose/resolve-props.d.ts +2 -1
  60. package/dist/compose/resolve-props.js +9 -1
  61. package/dist/compose/util-empty-scalar-position.js +1 -1
  62. package/dist/compose/util-flow-indent-check.d.ts +3 -0
  63. package/dist/compose/util-flow-indent-check.js +17 -0
  64. package/dist/doc/Document.d.ts +17 -14
  65. package/dist/doc/Document.js +58 -25
  66. package/dist/doc/anchors.d.ts +3 -3
  67. package/dist/doc/anchors.js +2 -2
  68. package/dist/doc/createNode.d.ts +1 -1
  69. package/dist/doc/createNode.js +8 -7
  70. package/dist/doc/directives.d.ts +4 -2
  71. package/dist/doc/directives.js +7 -4
  72. package/dist/index.d.ts +4 -2
  73. package/dist/index.js +1 -2
  74. package/dist/nodes/Collection.d.ts +2 -2
  75. package/dist/nodes/Collection.js +2 -1
  76. package/dist/nodes/Node.d.ts +14 -10
  77. package/dist/nodes/Pair.d.ts +1 -1
  78. package/dist/nodes/Pair.js +2 -2
  79. package/dist/nodes/Scalar.js +1 -1
  80. package/dist/nodes/YAMLMap.d.ts +9 -4
  81. package/dist/nodes/YAMLMap.js +7 -7
  82. package/dist/nodes/YAMLSeq.d.ts +4 -1
  83. package/dist/nodes/YAMLSeq.js +2 -10
  84. package/dist/nodes/addPairToJSMap.js +1 -1
  85. package/dist/nodes/toJS.js +3 -1
  86. package/dist/options.d.ts +44 -13
  87. package/dist/parse/cst-scalar.js +1 -2
  88. package/dist/parse/cst-visit.js +2 -2
  89. package/dist/parse/lexer.js +20 -8
  90. package/dist/parse/parser.js +142 -68
  91. package/dist/public-api.js +5 -7
  92. package/dist/schema/Schema.d.ts +5 -4
  93. package/dist/schema/Schema.js +13 -3
  94. package/dist/schema/common/null.js +3 -1
  95. package/dist/schema/core/float.js +4 -1
  96. package/dist/schema/json-schema.d.ts +69 -0
  97. package/dist/schema/tags.d.ts +1 -2
  98. package/dist/schema/tags.js +9 -9
  99. package/dist/schema/yaml-1.1/float.js +4 -1
  100. package/dist/schema/yaml-1.1/omap.d.ts +7 -3
  101. package/dist/schema/yaml-1.1/omap.js +1 -1
  102. package/dist/schema/yaml-1.1/pairs.js +1 -1
  103. package/dist/schema/yaml-1.1/set.d.ts +6 -2
  104. package/dist/schema/yaml-1.1/set.js +4 -0
  105. package/dist/stringify/stringify.d.ts +5 -3
  106. package/dist/stringify/stringify.js +49 -22
  107. package/dist/stringify/stringifyCollection.d.ts +2 -6
  108. package/dist/stringify/stringifyCollection.js +113 -84
  109. package/dist/stringify/stringifyComment.d.ts +10 -2
  110. package/dist/stringify/stringifyComment.js +19 -12
  111. package/dist/stringify/stringifyDocument.js +35 -14
  112. package/dist/stringify/stringifyPair.js +33 -19
  113. package/dist/stringify/stringifyString.js +8 -11
  114. package/dist/test-events.js +14 -14
  115. package/dist/visit.d.ts +49 -10
  116. package/dist/visit.js +148 -60
  117. package/package.json +11 -10
  118. package/browser/dist/options.js +0 -18
  119. package/dist/node_modules/tslib/tslib.es6.js +0 -76
  120. package/dist/options.js +0 -20
@@ -9,7 +9,7 @@ function includesToken(list, type) {
9
9
  return true;
10
10
  return false;
11
11
  }
12
- function includesNonEmpty(list) {
12
+ function findNonEmptyIndex(list) {
13
13
  for (let i = 0; i < list.length; ++i) {
14
14
  switch (list[i].type) {
15
15
  case 'space':
@@ -17,13 +17,13 @@ function includesNonEmpty(list) {
17
17
  case 'newline':
18
18
  break;
19
19
  default:
20
- return true;
20
+ return i;
21
21
  }
22
22
  }
23
- return false;
23
+ return -1;
24
24
  }
25
25
  function isFlowToken(token) {
26
- switch (token === null || token === void 0 ? void 0 : token.type) {
26
+ switch (token?.type) {
27
27
  case 'alias':
28
28
  case 'scalar':
29
29
  case 'single-quoted-scalar':
@@ -40,7 +40,7 @@ function getPrevProps(parent) {
40
40
  return parent.start;
41
41
  case 'block-map': {
42
42
  const it = parent.items[parent.items.length - 1];
43
- return it.sep || it.start;
43
+ return it.sep ?? it.start;
44
44
  }
45
45
  case 'block-seq':
46
46
  return parent.items[parent.items.length - 1].start;
@@ -51,7 +51,6 @@ function getPrevProps(parent) {
51
51
  }
52
52
  /** Note: May modify input array */
53
53
  function getFirstKeyStartProps(prev) {
54
- var _a;
55
54
  if (prev.length === 0)
56
55
  return [];
57
56
  let i = prev.length;
@@ -65,7 +64,7 @@ function getFirstKeyStartProps(prev) {
65
64
  break loop;
66
65
  }
67
66
  }
68
- while (((_a = prev[++i]) === null || _a === void 0 ? void 0 : _a.type) === 'space') {
67
+ while (prev[++i]?.type === 'space') {
69
68
  /* loop */
70
69
  }
71
70
  return prev.splice(i, prev.length);
@@ -207,6 +206,7 @@ class Parser {
207
206
  this.indent += source.length;
208
207
  break;
209
208
  case 'doc-mode':
209
+ case 'flow-error-end':
210
210
  return;
211
211
  default:
212
212
  this.atNewLine = false;
@@ -268,7 +268,7 @@ class Parser {
268
268
  return this.stack[this.stack.length - n];
269
269
  }
270
270
  *pop(error) {
271
- const token = error || this.stack.pop();
271
+ const token = error ?? this.stack.pop();
272
272
  /* istanbul ignore if should not happen */
273
273
  if (!token) {
274
274
  const message = 'Tried to pop an empty stack';
@@ -279,9 +279,14 @@ class Parser {
279
279
  }
280
280
  else {
281
281
  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;
282
+ if (token.type === 'block-scalar') {
283
+ // Block scalars use their parent rather than header indent
284
+ token.indent = 'indent' in top ? top.indent : 0;
285
+ }
286
+ else if (token.type === 'flow-collection' && top.type === 'document') {
287
+ // Ignore all indent for top-level flow collections
288
+ token.indent = 0;
289
+ }
285
290
  if (token.type === 'flow-collection')
286
291
  fixFlowSeqItems(token);
287
292
  switch (top.type) {
@@ -340,7 +345,7 @@ class Parser {
340
345
  !last.sep &&
341
346
  !last.value &&
342
347
  last.start.length > 0 &&
343
- !includesNonEmpty(last.start) &&
348
+ findNonEmptyIndex(last.start) === -1 &&
344
349
  (token.indent === 0 ||
345
350
  last.start.every(st => st.type !== 'comment' || st.indent < token.indent))) {
346
351
  if (top.type === 'document')
@@ -388,7 +393,7 @@ class Parser {
388
393
  return yield* this.lineEnd(doc);
389
394
  switch (this.type) {
390
395
  case 'doc-start': {
391
- if (includesNonEmpty(doc.start)) {
396
+ if (findNonEmptyIndex(doc.start) !== -1) {
392
397
  yield* this.pop();
393
398
  yield* this.step();
394
399
  }
@@ -468,7 +473,6 @@ class Parser {
468
473
  }
469
474
  }
470
475
  *blockMap(map) {
471
- var _a;
472
476
  const it = map.items[map.items.length - 1];
473
477
  // it.sep is true-ish if pair already has key or : separator
474
478
  switch (this.type) {
@@ -477,26 +481,30 @@ class Parser {
477
481
  if (it.value) {
478
482
  const end = 'end' in it.value ? it.value.end : undefined;
479
483
  const last = Array.isArray(end) ? end[end.length - 1] : undefined;
480
- if ((last === null || last === void 0 ? void 0 : last.type) === 'comment')
481
- end === null || end === void 0 ? void 0 : end.push(this.sourceToken);
484
+ if (last?.type === 'comment')
485
+ end?.push(this.sourceToken);
482
486
  else
483
487
  map.items.push({ start: [this.sourceToken] });
484
488
  }
485
- else if (it.sep)
489
+ else if (it.sep) {
486
490
  it.sep.push(this.sourceToken);
487
- else
491
+ }
492
+ else {
488
493
  it.start.push(this.sourceToken);
494
+ }
489
495
  return;
490
496
  case 'space':
491
497
  case 'comment':
492
- if (it.value)
498
+ if (it.value) {
493
499
  map.items.push({ start: [this.sourceToken] });
494
- else if (it.sep)
500
+ }
501
+ else if (it.sep) {
495
502
  it.sep.push(this.sourceToken);
503
+ }
496
504
  else {
497
505
  if (this.atIndentedComment(it.start, map.indent)) {
498
506
  const prev = map.items[map.items.length - 2];
499
- const end = (_a = prev === null || prev === void 0 ? void 0 : prev.value) === null || _a === void 0 ? void 0 : _a.end;
507
+ const end = prev?.value?.end;
500
508
  if (Array.isArray(end)) {
501
509
  Array.prototype.push.apply(end, it.start);
502
510
  end.push(this.sourceToken);
@@ -509,66 +517,132 @@ class Parser {
509
517
  return;
510
518
  }
511
519
  if (this.indent >= map.indent) {
512
- const atNextItem = !this.onKeyLine &&
513
- this.indent === map.indent &&
514
- (it.sep || includesNonEmpty(it.start));
520
+ const atNextItem = !this.onKeyLine && this.indent === map.indent && it.sep;
521
+ // For empty nodes, assign newline-separated not indented empty tokens to following node
522
+ let start = [];
523
+ if (atNextItem && it.sep && !it.value) {
524
+ const nl = [];
525
+ for (let i = 0; i < it.sep.length; ++i) {
526
+ const st = it.sep[i];
527
+ switch (st.type) {
528
+ case 'newline':
529
+ nl.push(i);
530
+ break;
531
+ case 'space':
532
+ break;
533
+ case 'comment':
534
+ if (st.indent > map.indent)
535
+ nl.length = 0;
536
+ break;
537
+ default:
538
+ nl.length = 0;
539
+ }
540
+ }
541
+ if (nl.length >= 2)
542
+ start = it.sep.splice(nl[1]);
543
+ }
515
544
  switch (this.type) {
516
545
  case 'anchor':
517
546
  case 'tag':
518
547
  if (atNextItem || it.value) {
519
- map.items.push({ start: [this.sourceToken] });
548
+ start.push(this.sourceToken);
549
+ map.items.push({ start });
520
550
  this.onKeyLine = true;
521
551
  }
522
- else if (it.sep)
552
+ else if (it.sep) {
523
553
  it.sep.push(this.sourceToken);
524
- else
554
+ }
555
+ else {
525
556
  it.start.push(this.sourceToken);
557
+ }
526
558
  return;
527
559
  case 'explicit-key-ind':
528
- if (!it.sep && !includesToken(it.start, 'explicit-key-ind'))
560
+ if (!it.sep && !includesToken(it.start, 'explicit-key-ind')) {
529
561
  it.start.push(this.sourceToken);
530
- else if (atNextItem || it.value)
531
- map.items.push({ start: [this.sourceToken] });
532
- else
562
+ }
563
+ else if (atNextItem || it.value) {
564
+ start.push(this.sourceToken);
565
+ map.items.push({ start });
566
+ }
567
+ else {
533
568
  this.stack.push({
534
569
  type: 'block-map',
535
570
  offset: this.offset,
536
571
  indent: this.indent,
537
572
  items: [{ start: [this.sourceToken] }]
538
573
  });
574
+ }
539
575
  this.onKeyLine = true;
540
576
  return;
541
577
  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
- });
578
+ if (includesToken(it.start, 'explicit-key-ind')) {
579
+ if (!it.sep) {
580
+ if (includesToken(it.start, 'newline')) {
581
+ Object.assign(it, { key: null, sep: [this.sourceToken] });
582
+ }
583
+ else {
584
+ const start = getFirstKeyStartProps(it.start);
585
+ this.stack.push({
586
+ type: 'block-map',
587
+ offset: this.offset,
588
+ indent: this.indent,
589
+ items: [{ start, key: null, sep: [this.sourceToken] }]
590
+ });
591
+ }
592
+ }
593
+ else if (it.value) {
594
+ map.items.push({ start: [], key: null, sep: [this.sourceToken] });
595
+ }
596
+ else if (includesToken(it.sep, 'map-value-ind')) {
597
+ this.stack.push({
598
+ type: 'block-map',
599
+ offset: this.offset,
600
+ indent: this.indent,
601
+ items: [{ start, key: null, sep: [this.sourceToken] }]
602
+ });
603
+ }
604
+ else if (isFlowToken(it.key) &&
605
+ !includesToken(it.sep, 'newline')) {
606
+ const start = getFirstKeyStartProps(it.start);
607
+ const key = it.key;
608
+ const sep = it.sep;
609
+ sep.push(this.sourceToken);
610
+ // @ts-expect-error type guard is wrong here
611
+ delete it.key, delete it.sep;
612
+ this.stack.push({
613
+ type: 'block-map',
614
+ offset: this.offset,
615
+ indent: this.indent,
616
+ items: [{ start, key, sep }]
617
+ });
618
+ }
619
+ else if (start.length > 0) {
620
+ // Not actually at next item
621
+ it.sep = it.sep.concat(start, this.sourceToken);
622
+ }
623
+ else {
624
+ it.sep.push(this.sourceToken);
625
+ }
626
+ }
627
+ else {
628
+ if (!it.sep) {
629
+ Object.assign(it, { key: null, sep: [this.sourceToken] });
630
+ }
631
+ else if (it.value || atNextItem) {
632
+ map.items.push({ start, key: null, sep: [this.sourceToken] });
633
+ }
634
+ else if (includesToken(it.sep, 'map-value-ind')) {
635
+ this.stack.push({
636
+ type: 'block-map',
637
+ offset: this.offset,
638
+ indent: this.indent,
639
+ items: [{ start: [], key: null, sep: [this.sourceToken] }]
640
+ });
641
+ }
642
+ else {
643
+ it.sep.push(this.sourceToken);
644
+ }
569
645
  }
570
- else
571
- it.sep.push(this.sourceToken);
572
646
  this.onKeyLine = true;
573
647
  return;
574
648
  case 'alias':
@@ -577,7 +651,7 @@ class Parser {
577
651
  case 'double-quoted-scalar': {
578
652
  const fs = this.flowScalar(this.type);
579
653
  if (atNextItem || it.value) {
580
- map.items.push({ start: [], key: fs, sep: [] });
654
+ map.items.push({ start, key: fs, sep: [] });
581
655
  this.onKeyLine = true;
582
656
  }
583
657
  else if (it.sep) {
@@ -594,8 +668,9 @@ class Parser {
594
668
  if (bv) {
595
669
  if (atNextItem &&
596
670
  bv.type !== 'block-seq' &&
597
- includesToken(it.start, 'explicit-key-ind'))
598
- map.items.push({ start: [] });
671
+ includesToken(it.start, 'explicit-key-ind')) {
672
+ map.items.push({ start });
673
+ }
599
674
  this.stack.push(bv);
600
675
  return;
601
676
  }
@@ -606,15 +681,14 @@ class Parser {
606
681
  yield* this.step();
607
682
  }
608
683
  *blockSequence(seq) {
609
- var _a;
610
684
  const it = seq.items[seq.items.length - 1];
611
685
  switch (this.type) {
612
686
  case 'newline':
613
687
  if (it.value) {
614
688
  const end = 'end' in it.value ? it.value.end : undefined;
615
689
  const last = Array.isArray(end) ? end[end.length - 1] : undefined;
616
- if ((last === null || last === void 0 ? void 0 : last.type) === 'comment')
617
- end === null || end === void 0 ? void 0 : end.push(this.sourceToken);
690
+ if (last?.type === 'comment')
691
+ end?.push(this.sourceToken);
618
692
  else
619
693
  seq.items.push({ start: [this.sourceToken] });
620
694
  }
@@ -628,7 +702,7 @@ class Parser {
628
702
  else {
629
703
  if (this.atIndentedComment(it.start, seq.indent)) {
630
704
  const prev = seq.items[seq.items.length - 2];
631
- const end = (_a = prev === null || prev === void 0 ? void 0 : prev.value) === null || _a === void 0 ? void 0 : _a.end;
705
+ const end = prev?.value?.end;
632
706
  if (Array.isArray(end)) {
633
707
  Array.prototype.push.apply(end, it.start);
634
708
  end.push(this.sourceToken);
@@ -732,7 +806,7 @@ class Parser {
732
806
  else {
733
807
  const parent = this.peek(2);
734
808
  if (parent.type === 'block-map' &&
735
- (this.type === 'map-value-ind' ||
809
+ ((this.type === 'map-value-ind' && parent.indent === fc.indent) ||
736
810
  (this.type === 'newline' &&
737
811
  !parent.items[parent.items.length - 1].sep))) {
738
812
  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
  /**
@@ -25,7 +23,7 @@ function parseOptions(options) {
25
23
  */
26
24
  function parseAllDocuments(source, options = {}) {
27
25
  const { lineCounter, prettyErrors } = parseOptions(options);
28
- const parser$1 = new parser.Parser(lineCounter === null || lineCounter === void 0 ? void 0 : lineCounter.addNewLine);
26
+ const parser$1 = new parser.Parser(lineCounter?.addNewLine);
29
27
  const composer$1 = new composer.Composer(options);
30
28
  const docs = Array.from(composer$1.compose(parser$1.parse(source)));
31
29
  if (prettyErrors && lineCounter)
@@ -40,7 +38,7 @@ function parseAllDocuments(source, options = {}) {
40
38
  /** Parse an input string into a single YAML.Document */
41
39
  function parseDocument(source, options = {}) {
42
40
  const { lineCounter, prettyErrors } = parseOptions(options);
43
- const parser$1 = new parser.Parser(lineCounter === null || lineCounter === void 0 ? void 0 : lineCounter.addNewLine);
41
+ const parser$1 = new parser.Parser(lineCounter?.addNewLine);
44
42
  const composer$1 = new composer.Composer(options);
45
43
  // `doc` is always set by compose.end(true) at the very latest
46
44
  let doc = null;
@@ -93,7 +91,7 @@ function stringify(value, replacer, options) {
93
91
  options = indent < 1 ? undefined : indent > 8 ? { indent: 8 } : { indent };
94
92
  }
95
93
  if (value === undefined) {
96
- const { keepUndefined } = options || replacer || {};
94
+ const { keepUndefined } = options ?? replacer ?? {};
97
95
  if (!keepUndefined)
98
96
  return undefined;
99
97
  }
@@ -1,17 +1,18 @@
1
1
  import { MAP, SCALAR, SEQ } from '../nodes/Node.js';
2
2
  import type { Pair } from '../nodes/Pair.js';
3
- import type { SchemaOptions } from '../options.js';
3
+ import type { SchemaOptions, ToStringOptions } from '../options.js';
4
4
  import type { CollectionTag, ScalarTag } from './types.js';
5
- export declare type SchemaName = 'core' | 'failsafe' | 'json' | 'yaml-1.1';
6
5
  export declare class Schema {
6
+ compat: Array<CollectionTag | ScalarTag> | null;
7
7
  knownTags: Record<string, CollectionTag | ScalarTag>;
8
8
  merge: boolean;
9
- name: SchemaName;
9
+ name: string;
10
10
  sortMapEntries: ((a: Pair, b: Pair) => number) | null;
11
11
  tags: Array<CollectionTag | ScalarTag>;
12
+ toStringOptions: Readonly<ToStringOptions> | null;
12
13
  [MAP]: CollectionTag;
13
14
  [SCALAR]: ScalarTag;
14
15
  [SEQ]: CollectionTag;
15
- constructor({ customTags, merge, resolveKnownTags, schema, sortMapEntries }: SchemaOptions);
16
+ constructor({ compat, customTags, merge, resolveKnownTags, schema, sortMapEntries, toStringDefaults }: SchemaOptions);
16
17
  clone(): Schema;
17
18
  }
@@ -8,17 +8,27 @@ var tags = require('./tags.js');
8
8
 
9
9
  const sortMapEntriesByKey = (a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0;
10
10
  class Schema {
11
- constructor({ customTags, merge, resolveKnownTags, schema, sortMapEntries }) {
11
+ constructor({ compat, customTags, merge, resolveKnownTags, schema, sortMapEntries, toStringDefaults }) {
12
+ this.compat = Array.isArray(compat)
13
+ ? tags.getTags(compat, 'compat')
14
+ : compat
15
+ ? tags.getTags(null, compat)
16
+ : null;
12
17
  this.merge = !!merge;
13
- this.name = schema || 'core';
18
+ this.name = (typeof schema === 'string' && schema) || 'core';
14
19
  this.knownTags = resolveKnownTags ? tags.coreKnownTags : {};
15
20
  this.tags = tags.getTags(customTags, this.name);
21
+ this.toStringOptions = toStringDefaults ?? null;
16
22
  Object.defineProperty(this, Node.MAP, { value: map.map });
17
23
  Object.defineProperty(this, Node.SCALAR, { value: string.string });
18
24
  Object.defineProperty(this, Node.SEQ, { value: seq.seq });
19
25
  // Used by createMap()
20
26
  this.sortMapEntries =
21
- sortMapEntries === true ? sortMapEntriesByKey : sortMapEntries || null;
27
+ typeof sortMapEntries === 'function'
28
+ ? sortMapEntries
29
+ : sortMapEntries === true
30
+ ? sortMapEntriesByKey
31
+ : null;
22
32
  }
23
33
  clone() {
24
34
  const copy = Object.create(Schema.prototype, Object.getOwnPropertyDescriptors(this));
@@ -9,7 +9,9 @@ const nullTag = {
9
9
  tag: 'tag:yaml.org,2002:null',
10
10
  test: /^(?:~|[Nn]ull|NULL)?$/,
11
11
  resolve: () => new Scalar.Scalar(null),
12
- stringify: ({ source }, ctx) => source && nullTag.test.test(source) ? source : ctx.options.nullStr
12
+ stringify: ({ source }, ctx) => typeof source === 'string' && nullTag.test.test(source)
13
+ ? source
14
+ : ctx.options.nullStr
13
15
  };
14
16
 
15
17
  exports.nullTag = nullTag;
@@ -22,7 +22,10 @@ const floatExp = {
22
22
  format: 'EXP',
23
23
  test: /^[-+]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)[eE][-+]?[0-9]+$/,
24
24
  resolve: str => parseFloat(str),
25
- stringify: ({ value }) => Number(value).toExponential()
25
+ stringify(node) {
26
+ const num = Number(node.value);
27
+ return isFinite(num) ? num.toExponential() : stringifyNumber.stringifyNumber(node);
28
+ }
26
29
  };
27
30
  const float = {
28
31
  identify: value => typeof value === 'number',
@@ -0,0 +1,69 @@
1
+ declare type JsonSchema = boolean | ArraySchema | ObjectSchema | NumberSchema | StringSchema;
2
+ declare type JsonType = 'array' | 'object' | 'string' | 'number' | 'integer' | 'boolean' | 'null';
3
+ interface CommonSchema {
4
+ type?: JsonType | JsonType[];
5
+ const?: unknown;
6
+ enum?: unknown[];
7
+ format?: string;
8
+ allOf?: JsonSchema[];
9
+ anyOf?: JsonSchema[];
10
+ oneOf?: JsonSchema[];
11
+ not?: JsonSchema;
12
+ if?: JsonSchema;
13
+ then?: JsonSchema;
14
+ else?: JsonSchema;
15
+ $id?: string;
16
+ $defs?: Record<string, JsonSchema>;
17
+ $anchor?: string;
18
+ $dynamicAnchor?: string;
19
+ $ref?: string;
20
+ $dynamicRef?: string;
21
+ $schema?: string;
22
+ $vocabulary?: Record<string, boolean>;
23
+ $comment?: string;
24
+ default?: unknown;
25
+ deprecated?: boolean;
26
+ readOnly?: boolean;
27
+ writeOnly?: boolean;
28
+ title?: string;
29
+ description?: string;
30
+ examples?: unknown[];
31
+ }
32
+ interface ArraySchema extends CommonSchema {
33
+ prefixItems?: JsonSchema[];
34
+ items?: JsonSchema;
35
+ contains?: JsonSchema;
36
+ unevaluatedItems?: JsonSchema;
37
+ maxItems?: number;
38
+ minItems?: number;
39
+ uniqueItems?: boolean;
40
+ maxContains?: number;
41
+ minContains?: number;
42
+ }
43
+ interface ObjectSchema extends CommonSchema {
44
+ properties?: Record<string, JsonSchema>;
45
+ patternProperties?: Record<string, JsonSchema>;
46
+ additionalProperties?: JsonSchema;
47
+ propertyNames?: JsonSchema;
48
+ unevaluatedProperties?: JsonSchema;
49
+ maxProperties?: number;
50
+ minProperties?: number;
51
+ required?: string[];
52
+ dependentRequired?: Record<string, string[]>;
53
+ dependentSchemas?: Record<string, JsonSchema>;
54
+ }
55
+ interface StringSchema extends CommonSchema {
56
+ maxLength?: number;
57
+ minLength?: number;
58
+ patter?: string;
59
+ contentEncoding?: string;
60
+ contentMediaType?: string;
61
+ contentSchema?: JsonSchema;
62
+ }
63
+ interface NumberSchema extends CommonSchema {
64
+ multipleOf?: number;
65
+ maximum?: number;
66
+ exclusiveMaximum?: number;
67
+ minimum?: number;
68
+ exclusiveMinimum?: number;
69
+ }
@@ -1,5 +1,4 @@
1
1
  import { SchemaOptions } from '../options.js';
2
- import type { SchemaName } from './Schema.js';
3
2
  import type { CollectionTag, ScalarTag } from './types.js';
4
3
  declare const tagsByName: {
5
4
  binary: ScalarTag;
@@ -37,5 +36,5 @@ export declare const coreKnownTags: {
37
36
  test: RegExp;
38
37
  };
39
38
  };
40
- export declare function getTags(customTags: SchemaOptions['customTags'] | undefined, schemaName: SchemaName): (ScalarTag | CollectionTag)[];
39
+ export declare function getTags(customTags: SchemaOptions['customTags'] | undefined, schemaName: string): (ScalarTag | CollectionTag)[];
41
40
  export {};
@@ -16,13 +16,13 @@ var schema$2 = require('./yaml-1.1/schema.js');
16
16
  var set = require('./yaml-1.1/set.js');
17
17
  var timestamp = require('./yaml-1.1/timestamp.js');
18
18
 
19
- const schemas = {
20
- core: schema.schema,
21
- failsafe: [map.map, seq.seq, string.string],
22
- json: schema$1.schema,
23
- yaml11: schema$2.schema,
24
- 'yaml-1.1': schema$2.schema
25
- };
19
+ const schemas = new Map([
20
+ ['core', schema.schema],
21
+ ['failsafe', [map.map, seq.seq, string.string]],
22
+ ['json', schema$1.schema],
23
+ ['yaml11', schema$2.schema],
24
+ ['yaml-1.1', schema$2.schema]
25
+ ]);
26
26
  const tagsByName = {
27
27
  binary: binary.binary,
28
28
  bool: bool.boolTag,
@@ -50,12 +50,12 @@ const coreKnownTags = {
50
50
  'tag:yaml.org,2002:timestamp': timestamp.timestamp
51
51
  };
52
52
  function getTags(customTags, schemaName) {
53
- let tags = schemas[schemaName];
53
+ let tags = schemas.get(schemaName);
54
54
  if (!tags) {
55
55
  if (Array.isArray(customTags))
56
56
  tags = [];
57
57
  else {
58
- const keys = Object.keys(schemas)
58
+ const keys = Array.from(schemas.keys())
59
59
  .filter(key => key !== 'yaml11')
60
60
  .map(key => JSON.stringify(key))
61
61
  .join(', ');
@@ -22,7 +22,10 @@ const floatExp = {
22
22
  format: 'EXP',
23
23
  test: /^[-+]?(?:[0-9][0-9_]*)?(?:\.[0-9_]*)?[eE][-+]?[0-9]+$/,
24
24
  resolve: (str) => parseFloat(str.replace(/_/g, '')),
25
- stringify: ({ value }) => Number(value).toExponential()
25
+ stringify(node) {
26
+ const num = Number(node.value);
27
+ return isFinite(num) ? num.toExponential() : stringifyNumber.stringifyNumber(node);
28
+ }
26
29
  };
27
30
  const float = {
28
31
  identify: value => typeof value === 'number',
@@ -8,9 +8,13 @@ export declare class YAMLOMap extends YAMLSeq {
8
8
  key: any;
9
9
  value: any;
10
10
  }, overwrite?: boolean | undefined) => void;
11
- delete: (key: any) => boolean;
12
- get: (key: any, keepScalar?: boolean | undefined) => unknown;
13
- has: (key: any) => boolean;
11
+ delete: (key: unknown) => boolean;
12
+ get: {
13
+ (key: unknown, keepScalar: true): import("../../index.js").Scalar<any> | undefined;
14
+ (key: unknown, keepScalar?: false | undefined): any;
15
+ (key: unknown, keepScalar?: boolean | undefined): any;
16
+ };
17
+ has: (key: unknown) => boolean;
14
18
  set: (key: any, value: any) => void;
15
19
  /**
16
20
  * If `ctx` is given, the return type is actually `Map<unknown, unknown>`,
@@ -24,7 +24,7 @@ class YAMLOMap extends YAMLSeq.YAMLSeq {
24
24
  if (!ctx)
25
25
  return super.toJSON(_);
26
26
  const map = new Map();
27
- if (ctx && ctx.onCreate)
27
+ if (ctx?.onCreate)
28
28
  ctx.onCreate(map);
29
29
  for (const pair of this.items) {
30
30
  let key, value;