yaml 2.4.2 → 2.4.4
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.
- package/browser/dist/compose/resolve-props.js +15 -4
- package/browser/dist/parse/lexer.js +26 -17
- package/browser/dist/parse/parser.js +11 -12
- package/browser/dist/schema/core/float.js +1 -1
- package/browser/dist/schema/yaml-1.1/float.js +1 -1
- package/browser/dist/stringify/stringifyPair.js +1 -1
- package/dist/compose/resolve-props.js +15 -4
- package/dist/parse/cst.d.ts +2 -0
- package/dist/parse/lexer.js +26 -17
- package/dist/parse/parser.js +11 -12
- package/dist/schema/core/float.js +1 -1
- package/dist/schema/yaml-1.1/float.js +1 -1
- package/dist/stringify/stringifyPair.js +1 -1
- package/package.json +3 -3
|
@@ -7,6 +7,7 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
|
|
|
7
7
|
let hasNewline = false;
|
|
8
8
|
let hasNewlineAfterProp = false;
|
|
9
9
|
let reqSpace = false;
|
|
10
|
+
let tab = null;
|
|
10
11
|
let anchor = null;
|
|
11
12
|
let tag = null;
|
|
12
13
|
let comma = null;
|
|
@@ -20,6 +21,12 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
|
|
|
20
21
|
onError(token.offset, 'MISSING_CHAR', 'Tags and anchors must be separated from the next token by white space');
|
|
21
22
|
reqSpace = false;
|
|
22
23
|
}
|
|
24
|
+
if (tab) {
|
|
25
|
+
if (token.type !== 'comment') {
|
|
26
|
+
onError(tab, 'TAB_AS_INDENT', 'Tabs are not allowed as indentation');
|
|
27
|
+
}
|
|
28
|
+
tab = null;
|
|
29
|
+
}
|
|
23
30
|
switch (token.type) {
|
|
24
31
|
case 'space':
|
|
25
32
|
// At the doc level, tabs at line start may be parsed
|
|
@@ -27,9 +34,10 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
|
|
|
27
34
|
// In a flow collection, only the parser handles indent.
|
|
28
35
|
if (!flow &&
|
|
29
36
|
atNewline &&
|
|
30
|
-
indicator !== 'doc-start' &&
|
|
31
|
-
token.source[0] === '\t')
|
|
32
|
-
|
|
37
|
+
(indicator !== 'doc-start' || next?.type !== 'flow-collection') &&
|
|
38
|
+
token.source[0] === '\t') {
|
|
39
|
+
tab = token;
|
|
40
|
+
}
|
|
33
41
|
hasSpace = true;
|
|
34
42
|
break;
|
|
35
43
|
case 'comment': {
|
|
@@ -115,8 +123,11 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
|
|
|
115
123
|
next.type !== 'space' &&
|
|
116
124
|
next.type !== 'newline' &&
|
|
117
125
|
next.type !== 'comma' &&
|
|
118
|
-
(next.type !== 'scalar' || next.source !== ''))
|
|
126
|
+
(next.type !== 'scalar' || next.source !== '')) {
|
|
119
127
|
onError(next.offset, 'MISSING_CHAR', 'Tags and anchors must be separated from the next token by white space');
|
|
128
|
+
}
|
|
129
|
+
if (tab)
|
|
130
|
+
onError(tab, 'TAB_AS_INDENT', 'Tabs are not allowed as indentation');
|
|
120
131
|
return {
|
|
121
132
|
comma,
|
|
122
133
|
found,
|
|
@@ -79,11 +79,11 @@ function isEmpty(ch) {
|
|
|
79
79
|
return false;
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
const hexDigits = '0123456789ABCDEFabcdef'
|
|
83
|
-
const tagChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()"
|
|
84
|
-
const
|
|
85
|
-
const invalidAnchorChars = ' ,[]{}\n\r\t'
|
|
86
|
-
const isNotAnchorChar = (ch) => !ch || invalidAnchorChars.
|
|
82
|
+
const hexDigits = new Set('0123456789ABCDEFabcdef');
|
|
83
|
+
const tagChars = new Set("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()");
|
|
84
|
+
const flowIndicatorChars = new Set(',[]{}');
|
|
85
|
+
const invalidAnchorChars = new Set(' ,[]{}\n\r\t');
|
|
86
|
+
const isNotAnchorChar = (ch) => !ch || invalidAnchorChars.has(ch);
|
|
87
87
|
/**
|
|
88
88
|
* Splits an input string into lexical tokens, i.e. smaller strings that are
|
|
89
89
|
* easily identifiable by `tokens.tokenType()`.
|
|
@@ -149,6 +149,8 @@ class Lexer {
|
|
|
149
149
|
*/
|
|
150
150
|
*lex(source, incomplete = false) {
|
|
151
151
|
if (source) {
|
|
152
|
+
if (typeof source !== 'string')
|
|
153
|
+
throw TypeError('source is not a string');
|
|
152
154
|
this.buffer = this.buffer ? this.buffer + source : source;
|
|
153
155
|
this.lineEndPos = null;
|
|
154
156
|
}
|
|
@@ -248,11 +250,16 @@ class Lexer {
|
|
|
248
250
|
}
|
|
249
251
|
if (line[0] === '%') {
|
|
250
252
|
let dirEnd = line.length;
|
|
251
|
-
|
|
252
|
-
|
|
253
|
+
let cs = line.indexOf('#');
|
|
254
|
+
while (cs !== -1) {
|
|
253
255
|
const ch = line[cs - 1];
|
|
254
|
-
if (ch === ' ' || ch === '\t')
|
|
256
|
+
if (ch === ' ' || ch === '\t') {
|
|
255
257
|
dirEnd = cs - 1;
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
cs = line.indexOf('#', cs + 1);
|
|
262
|
+
}
|
|
256
263
|
}
|
|
257
264
|
while (true) {
|
|
258
265
|
const ch = line[dirEnd - 1];
|
|
@@ -518,8 +525,10 @@ class Lexer {
|
|
|
518
525
|
if (indent >= this.indentNext) {
|
|
519
526
|
if (this.blockScalarIndent === -1)
|
|
520
527
|
this.indentNext = indent;
|
|
521
|
-
else
|
|
522
|
-
this.indentNext
|
|
528
|
+
else {
|
|
529
|
+
this.indentNext =
|
|
530
|
+
this.blockScalarIndent + (this.indentNext === 0 ? 1 : this.indentNext);
|
|
531
|
+
}
|
|
523
532
|
do {
|
|
524
533
|
const cs = this.continueScalar(nl + 1);
|
|
525
534
|
if (cs === -1)
|
|
@@ -559,7 +568,7 @@ class Lexer {
|
|
|
559
568
|
while ((ch = this.buffer[++i])) {
|
|
560
569
|
if (ch === ':') {
|
|
561
570
|
const next = this.buffer[i + 1];
|
|
562
|
-
if (isEmpty(next) || (inFlow && next
|
|
571
|
+
if (isEmpty(next) || (inFlow && flowIndicatorChars.has(next)))
|
|
563
572
|
break;
|
|
564
573
|
end = i;
|
|
565
574
|
}
|
|
@@ -574,7 +583,7 @@ class Lexer {
|
|
|
574
583
|
else
|
|
575
584
|
end = i;
|
|
576
585
|
}
|
|
577
|
-
if (next === '#' || (inFlow &&
|
|
586
|
+
if (next === '#' || (inFlow && flowIndicatorChars.has(next)))
|
|
578
587
|
break;
|
|
579
588
|
if (ch === '\n') {
|
|
580
589
|
const cs = this.continueScalar(i + 1);
|
|
@@ -584,7 +593,7 @@ class Lexer {
|
|
|
584
593
|
}
|
|
585
594
|
}
|
|
586
595
|
else {
|
|
587
|
-
if (inFlow &&
|
|
596
|
+
if (inFlow && flowIndicatorChars.has(ch))
|
|
588
597
|
break;
|
|
589
598
|
end = i;
|
|
590
599
|
}
|
|
@@ -629,7 +638,7 @@ class Lexer {
|
|
|
629
638
|
case ':': {
|
|
630
639
|
const inFlow = this.flowLevel > 0;
|
|
631
640
|
const ch1 = this.charAt(1);
|
|
632
|
-
if (isEmpty(ch1) || (inFlow &&
|
|
641
|
+
if (isEmpty(ch1) || (inFlow && flowIndicatorChars.has(ch1))) {
|
|
633
642
|
if (!inFlow)
|
|
634
643
|
this.indentNext = this.indentValue + 1;
|
|
635
644
|
else if (this.flowKey)
|
|
@@ -654,11 +663,11 @@ class Lexer {
|
|
|
654
663
|
let i = this.pos + 1;
|
|
655
664
|
let ch = this.buffer[i];
|
|
656
665
|
while (ch) {
|
|
657
|
-
if (tagChars.
|
|
666
|
+
if (tagChars.has(ch))
|
|
658
667
|
ch = this.buffer[++i];
|
|
659
668
|
else if (ch === '%' &&
|
|
660
|
-
hexDigits.
|
|
661
|
-
hexDigits.
|
|
669
|
+
hexDigits.has(this.buffer[i + 1]) &&
|
|
670
|
+
hexDigits.has(this.buffer[i + 2])) {
|
|
662
671
|
ch = this.buffer[(i += 3)];
|
|
663
672
|
}
|
|
664
673
|
else
|
|
@@ -304,7 +304,7 @@ class Parser {
|
|
|
304
304
|
}
|
|
305
305
|
else {
|
|
306
306
|
Object.assign(it, { key: token, sep: [] });
|
|
307
|
-
this.onKeyLine = !
|
|
307
|
+
this.onKeyLine = !it.explicitKey;
|
|
308
308
|
return;
|
|
309
309
|
}
|
|
310
310
|
break;
|
|
@@ -513,9 +513,9 @@ class Parser {
|
|
|
513
513
|
return;
|
|
514
514
|
}
|
|
515
515
|
if (this.indent >= map.indent) {
|
|
516
|
-
const
|
|
517
|
-
|
|
518
|
-
it.sep &&
|
|
516
|
+
const atMapIndent = !this.onKeyLine && this.indent === map.indent;
|
|
517
|
+
const atNextItem = atMapIndent &&
|
|
518
|
+
(it.sep || it.explicitKey) &&
|
|
519
519
|
this.type !== 'seq-item-ind';
|
|
520
520
|
// For empty nodes, assign newline-separated not indented empty tokens to following node
|
|
521
521
|
let start = [];
|
|
@@ -556,25 +556,26 @@ class Parser {
|
|
|
556
556
|
}
|
|
557
557
|
return;
|
|
558
558
|
case 'explicit-key-ind':
|
|
559
|
-
if (!it.sep && !
|
|
559
|
+
if (!it.sep && !it.explicitKey) {
|
|
560
560
|
it.start.push(this.sourceToken);
|
|
561
|
+
it.explicitKey = true;
|
|
561
562
|
}
|
|
562
563
|
else if (atNextItem || it.value) {
|
|
563
564
|
start.push(this.sourceToken);
|
|
564
|
-
map.items.push({ start });
|
|
565
|
+
map.items.push({ start, explicitKey: true });
|
|
565
566
|
}
|
|
566
567
|
else {
|
|
567
568
|
this.stack.push({
|
|
568
569
|
type: 'block-map',
|
|
569
570
|
offset: this.offset,
|
|
570
571
|
indent: this.indent,
|
|
571
|
-
items: [{ start: [this.sourceToken] }]
|
|
572
|
+
items: [{ start: [this.sourceToken], explicitKey: true }]
|
|
572
573
|
});
|
|
573
574
|
}
|
|
574
575
|
this.onKeyLine = true;
|
|
575
576
|
return;
|
|
576
577
|
case 'map-value-ind':
|
|
577
|
-
if (
|
|
578
|
+
if (it.explicitKey) {
|
|
578
579
|
if (!it.sep) {
|
|
579
580
|
if (includesToken(it.start, 'newline')) {
|
|
580
581
|
Object.assign(it, { key: null, sep: [this.sourceToken] });
|
|
@@ -665,9 +666,7 @@ class Parser {
|
|
|
665
666
|
default: {
|
|
666
667
|
const bv = this.startBlockValue(map);
|
|
667
668
|
if (bv) {
|
|
668
|
-
if (
|
|
669
|
-
bv.type !== 'block-seq' &&
|
|
670
|
-
includesToken(it.start, 'explicit-key-ind')) {
|
|
669
|
+
if (atMapIndent && bv.type !== 'block-seq') {
|
|
671
670
|
map.items.push({ start });
|
|
672
671
|
}
|
|
673
672
|
this.stack.push(bv);
|
|
@@ -888,7 +887,7 @@ class Parser {
|
|
|
888
887
|
type: 'block-map',
|
|
889
888
|
offset: this.offset,
|
|
890
889
|
indent: this.indent,
|
|
891
|
-
items: [{ start }]
|
|
890
|
+
items: [{ start, explicitKey: true }]
|
|
892
891
|
};
|
|
893
892
|
}
|
|
894
893
|
case 'map-value-ind': {
|
|
@@ -5,7 +5,7 @@ const floatNaN = {
|
|
|
5
5
|
identify: value => typeof value === 'number',
|
|
6
6
|
default: true,
|
|
7
7
|
tag: 'tag:yaml.org,2002:float',
|
|
8
|
-
test: /^(?:[-+]?\.(?:inf|Inf|INF
|
|
8
|
+
test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
|
|
9
9
|
resolve: str => str.slice(-3).toLowerCase() === 'nan'
|
|
10
10
|
? NaN
|
|
11
11
|
: str[0] === '-'
|
|
@@ -5,7 +5,7 @@ const floatNaN = {
|
|
|
5
5
|
identify: value => typeof value === 'number',
|
|
6
6
|
default: true,
|
|
7
7
|
tag: 'tag:yaml.org,2002:float',
|
|
8
|
-
test: /^[-+]?\.(?:inf|Inf|INF
|
|
8
|
+
test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
|
|
9
9
|
resolve: (str) => str.slice(-3).toLowerCase() === 'nan'
|
|
10
10
|
? NaN
|
|
11
11
|
: str[0] === '-'
|
|
@@ -10,7 +10,7 @@ function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
|
|
|
10
10
|
if (keyComment) {
|
|
11
11
|
throw new Error('With simple keys, key nodes cannot have comments');
|
|
12
12
|
}
|
|
13
|
-
if (isCollection(key)) {
|
|
13
|
+
if (isCollection(key) || (!isNode(key) && typeof key === 'object')) {
|
|
14
14
|
const msg = 'With simple keys, collection cannot be used as a key value';
|
|
15
15
|
throw new Error(msg);
|
|
16
16
|
}
|
|
@@ -9,6 +9,7 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
|
|
|
9
9
|
let hasNewline = false;
|
|
10
10
|
let hasNewlineAfterProp = false;
|
|
11
11
|
let reqSpace = false;
|
|
12
|
+
let tab = null;
|
|
12
13
|
let anchor = null;
|
|
13
14
|
let tag = null;
|
|
14
15
|
let comma = null;
|
|
@@ -22,6 +23,12 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
|
|
|
22
23
|
onError(token.offset, 'MISSING_CHAR', 'Tags and anchors must be separated from the next token by white space');
|
|
23
24
|
reqSpace = false;
|
|
24
25
|
}
|
|
26
|
+
if (tab) {
|
|
27
|
+
if (token.type !== 'comment') {
|
|
28
|
+
onError(tab, 'TAB_AS_INDENT', 'Tabs are not allowed as indentation');
|
|
29
|
+
}
|
|
30
|
+
tab = null;
|
|
31
|
+
}
|
|
25
32
|
switch (token.type) {
|
|
26
33
|
case 'space':
|
|
27
34
|
// At the doc level, tabs at line start may be parsed
|
|
@@ -29,9 +36,10 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
|
|
|
29
36
|
// In a flow collection, only the parser handles indent.
|
|
30
37
|
if (!flow &&
|
|
31
38
|
atNewline &&
|
|
32
|
-
indicator !== 'doc-start' &&
|
|
33
|
-
token.source[0] === '\t')
|
|
34
|
-
|
|
39
|
+
(indicator !== 'doc-start' || next?.type !== 'flow-collection') &&
|
|
40
|
+
token.source[0] === '\t') {
|
|
41
|
+
tab = token;
|
|
42
|
+
}
|
|
35
43
|
hasSpace = true;
|
|
36
44
|
break;
|
|
37
45
|
case 'comment': {
|
|
@@ -117,8 +125,11 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
|
|
|
117
125
|
next.type !== 'space' &&
|
|
118
126
|
next.type !== 'newline' &&
|
|
119
127
|
next.type !== 'comma' &&
|
|
120
|
-
(next.type !== 'scalar' || next.source !== ''))
|
|
128
|
+
(next.type !== 'scalar' || next.source !== '')) {
|
|
121
129
|
onError(next.offset, 'MISSING_CHAR', 'Tags and anchors must be separated from the next token by white space');
|
|
130
|
+
}
|
|
131
|
+
if (tab)
|
|
132
|
+
onError(tab, 'TAB_AS_INDENT', 'Tabs are not allowed as indentation');
|
|
122
133
|
return {
|
|
123
134
|
comma,
|
|
124
135
|
found,
|
package/dist/parse/cst.d.ts
CHANGED
|
@@ -51,11 +51,13 @@ export interface BlockMap {
|
|
|
51
51
|
indent: number;
|
|
52
52
|
items: Array<{
|
|
53
53
|
start: SourceToken[];
|
|
54
|
+
explicitKey?: true;
|
|
54
55
|
key?: never;
|
|
55
56
|
sep?: never;
|
|
56
57
|
value?: never;
|
|
57
58
|
} | {
|
|
58
59
|
start: SourceToken[];
|
|
60
|
+
explicitKey?: true;
|
|
59
61
|
key: Token | null;
|
|
60
62
|
sep: SourceToken[];
|
|
61
63
|
value?: Token;
|
package/dist/parse/lexer.js
CHANGED
|
@@ -81,11 +81,11 @@ function isEmpty(ch) {
|
|
|
81
81
|
return false;
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
const hexDigits = '0123456789ABCDEFabcdef'
|
|
85
|
-
const tagChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()"
|
|
86
|
-
const
|
|
87
|
-
const invalidAnchorChars = ' ,[]{}\n\r\t'
|
|
88
|
-
const isNotAnchorChar = (ch) => !ch || invalidAnchorChars.
|
|
84
|
+
const hexDigits = new Set('0123456789ABCDEFabcdef');
|
|
85
|
+
const tagChars = new Set("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()");
|
|
86
|
+
const flowIndicatorChars = new Set(',[]{}');
|
|
87
|
+
const invalidAnchorChars = new Set(' ,[]{}\n\r\t');
|
|
88
|
+
const isNotAnchorChar = (ch) => !ch || invalidAnchorChars.has(ch);
|
|
89
89
|
/**
|
|
90
90
|
* Splits an input string into lexical tokens, i.e. smaller strings that are
|
|
91
91
|
* easily identifiable by `tokens.tokenType()`.
|
|
@@ -151,6 +151,8 @@ class Lexer {
|
|
|
151
151
|
*/
|
|
152
152
|
*lex(source, incomplete = false) {
|
|
153
153
|
if (source) {
|
|
154
|
+
if (typeof source !== 'string')
|
|
155
|
+
throw TypeError('source is not a string');
|
|
154
156
|
this.buffer = this.buffer ? this.buffer + source : source;
|
|
155
157
|
this.lineEndPos = null;
|
|
156
158
|
}
|
|
@@ -250,11 +252,16 @@ class Lexer {
|
|
|
250
252
|
}
|
|
251
253
|
if (line[0] === '%') {
|
|
252
254
|
let dirEnd = line.length;
|
|
253
|
-
|
|
254
|
-
|
|
255
|
+
let cs = line.indexOf('#');
|
|
256
|
+
while (cs !== -1) {
|
|
255
257
|
const ch = line[cs - 1];
|
|
256
|
-
if (ch === ' ' || ch === '\t')
|
|
258
|
+
if (ch === ' ' || ch === '\t') {
|
|
257
259
|
dirEnd = cs - 1;
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
cs = line.indexOf('#', cs + 1);
|
|
264
|
+
}
|
|
258
265
|
}
|
|
259
266
|
while (true) {
|
|
260
267
|
const ch = line[dirEnd - 1];
|
|
@@ -520,8 +527,10 @@ class Lexer {
|
|
|
520
527
|
if (indent >= this.indentNext) {
|
|
521
528
|
if (this.blockScalarIndent === -1)
|
|
522
529
|
this.indentNext = indent;
|
|
523
|
-
else
|
|
524
|
-
this.indentNext
|
|
530
|
+
else {
|
|
531
|
+
this.indentNext =
|
|
532
|
+
this.blockScalarIndent + (this.indentNext === 0 ? 1 : this.indentNext);
|
|
533
|
+
}
|
|
525
534
|
do {
|
|
526
535
|
const cs = this.continueScalar(nl + 1);
|
|
527
536
|
if (cs === -1)
|
|
@@ -561,7 +570,7 @@ class Lexer {
|
|
|
561
570
|
while ((ch = this.buffer[++i])) {
|
|
562
571
|
if (ch === ':') {
|
|
563
572
|
const next = this.buffer[i + 1];
|
|
564
|
-
if (isEmpty(next) || (inFlow && next
|
|
573
|
+
if (isEmpty(next) || (inFlow && flowIndicatorChars.has(next)))
|
|
565
574
|
break;
|
|
566
575
|
end = i;
|
|
567
576
|
}
|
|
@@ -576,7 +585,7 @@ class Lexer {
|
|
|
576
585
|
else
|
|
577
586
|
end = i;
|
|
578
587
|
}
|
|
579
|
-
if (next === '#' || (inFlow &&
|
|
588
|
+
if (next === '#' || (inFlow && flowIndicatorChars.has(next)))
|
|
580
589
|
break;
|
|
581
590
|
if (ch === '\n') {
|
|
582
591
|
const cs = this.continueScalar(i + 1);
|
|
@@ -586,7 +595,7 @@ class Lexer {
|
|
|
586
595
|
}
|
|
587
596
|
}
|
|
588
597
|
else {
|
|
589
|
-
if (inFlow &&
|
|
598
|
+
if (inFlow && flowIndicatorChars.has(ch))
|
|
590
599
|
break;
|
|
591
600
|
end = i;
|
|
592
601
|
}
|
|
@@ -631,7 +640,7 @@ class Lexer {
|
|
|
631
640
|
case ':': {
|
|
632
641
|
const inFlow = this.flowLevel > 0;
|
|
633
642
|
const ch1 = this.charAt(1);
|
|
634
|
-
if (isEmpty(ch1) || (inFlow &&
|
|
643
|
+
if (isEmpty(ch1) || (inFlow && flowIndicatorChars.has(ch1))) {
|
|
635
644
|
if (!inFlow)
|
|
636
645
|
this.indentNext = this.indentValue + 1;
|
|
637
646
|
else if (this.flowKey)
|
|
@@ -656,11 +665,11 @@ class Lexer {
|
|
|
656
665
|
let i = this.pos + 1;
|
|
657
666
|
let ch = this.buffer[i];
|
|
658
667
|
while (ch) {
|
|
659
|
-
if (tagChars.
|
|
668
|
+
if (tagChars.has(ch))
|
|
660
669
|
ch = this.buffer[++i];
|
|
661
670
|
else if (ch === '%' &&
|
|
662
|
-
hexDigits.
|
|
663
|
-
hexDigits.
|
|
671
|
+
hexDigits.has(this.buffer[i + 1]) &&
|
|
672
|
+
hexDigits.has(this.buffer[i + 2])) {
|
|
664
673
|
ch = this.buffer[(i += 3)];
|
|
665
674
|
}
|
|
666
675
|
else
|
package/dist/parse/parser.js
CHANGED
|
@@ -308,7 +308,7 @@ class Parser {
|
|
|
308
308
|
}
|
|
309
309
|
else {
|
|
310
310
|
Object.assign(it, { key: token, sep: [] });
|
|
311
|
-
this.onKeyLine = !
|
|
311
|
+
this.onKeyLine = !it.explicitKey;
|
|
312
312
|
return;
|
|
313
313
|
}
|
|
314
314
|
break;
|
|
@@ -517,9 +517,9 @@ class Parser {
|
|
|
517
517
|
return;
|
|
518
518
|
}
|
|
519
519
|
if (this.indent >= map.indent) {
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
it.sep &&
|
|
520
|
+
const atMapIndent = !this.onKeyLine && this.indent === map.indent;
|
|
521
|
+
const atNextItem = atMapIndent &&
|
|
522
|
+
(it.sep || it.explicitKey) &&
|
|
523
523
|
this.type !== 'seq-item-ind';
|
|
524
524
|
// For empty nodes, assign newline-separated not indented empty tokens to following node
|
|
525
525
|
let start = [];
|
|
@@ -560,25 +560,26 @@ class Parser {
|
|
|
560
560
|
}
|
|
561
561
|
return;
|
|
562
562
|
case 'explicit-key-ind':
|
|
563
|
-
if (!it.sep && !
|
|
563
|
+
if (!it.sep && !it.explicitKey) {
|
|
564
564
|
it.start.push(this.sourceToken);
|
|
565
|
+
it.explicitKey = true;
|
|
565
566
|
}
|
|
566
567
|
else if (atNextItem || it.value) {
|
|
567
568
|
start.push(this.sourceToken);
|
|
568
|
-
map.items.push({ start });
|
|
569
|
+
map.items.push({ start, explicitKey: true });
|
|
569
570
|
}
|
|
570
571
|
else {
|
|
571
572
|
this.stack.push({
|
|
572
573
|
type: 'block-map',
|
|
573
574
|
offset: this.offset,
|
|
574
575
|
indent: this.indent,
|
|
575
|
-
items: [{ start: [this.sourceToken] }]
|
|
576
|
+
items: [{ start: [this.sourceToken], explicitKey: true }]
|
|
576
577
|
});
|
|
577
578
|
}
|
|
578
579
|
this.onKeyLine = true;
|
|
579
580
|
return;
|
|
580
581
|
case 'map-value-ind':
|
|
581
|
-
if (
|
|
582
|
+
if (it.explicitKey) {
|
|
582
583
|
if (!it.sep) {
|
|
583
584
|
if (includesToken(it.start, 'newline')) {
|
|
584
585
|
Object.assign(it, { key: null, sep: [this.sourceToken] });
|
|
@@ -669,9 +670,7 @@ class Parser {
|
|
|
669
670
|
default: {
|
|
670
671
|
const bv = this.startBlockValue(map);
|
|
671
672
|
if (bv) {
|
|
672
|
-
if (
|
|
673
|
-
bv.type !== 'block-seq' &&
|
|
674
|
-
includesToken(it.start, 'explicit-key-ind')) {
|
|
673
|
+
if (atMapIndent && bv.type !== 'block-seq') {
|
|
675
674
|
map.items.push({ start });
|
|
676
675
|
}
|
|
677
676
|
this.stack.push(bv);
|
|
@@ -892,7 +891,7 @@ class Parser {
|
|
|
892
891
|
type: 'block-map',
|
|
893
892
|
offset: this.offset,
|
|
894
893
|
indent: this.indent,
|
|
895
|
-
items: [{ start }]
|
|
894
|
+
items: [{ start, explicitKey: true }]
|
|
896
895
|
};
|
|
897
896
|
}
|
|
898
897
|
case 'map-value-ind': {
|
|
@@ -7,7 +7,7 @@ const floatNaN = {
|
|
|
7
7
|
identify: value => typeof value === 'number',
|
|
8
8
|
default: true,
|
|
9
9
|
tag: 'tag:yaml.org,2002:float',
|
|
10
|
-
test: /^(?:[-+]?\.(?:inf|Inf|INF
|
|
10
|
+
test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
|
|
11
11
|
resolve: str => str.slice(-3).toLowerCase() === 'nan'
|
|
12
12
|
? NaN
|
|
13
13
|
: str[0] === '-'
|
|
@@ -7,7 +7,7 @@ const floatNaN = {
|
|
|
7
7
|
identify: value => typeof value === 'number',
|
|
8
8
|
default: true,
|
|
9
9
|
tag: 'tag:yaml.org,2002:float',
|
|
10
|
-
test: /^[-+]?\.(?:inf|Inf|INF
|
|
10
|
+
test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
|
|
11
11
|
resolve: (str) => str.slice(-3).toLowerCase() === 'nan'
|
|
12
12
|
? NaN
|
|
13
13
|
: str[0] === '-'
|
|
@@ -12,7 +12,7 @@ function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
|
|
|
12
12
|
if (keyComment) {
|
|
13
13
|
throw new Error('With simple keys, key nodes cannot have comments');
|
|
14
14
|
}
|
|
15
|
-
if (identity.isCollection(key)) {
|
|
15
|
+
if (identity.isCollection(key) || (!identity.isNode(key) && typeof key === 'object')) {
|
|
16
16
|
const msg = 'With simple keys, collection cannot be used as a key value';
|
|
17
17
|
throw new Error(msg);
|
|
18
18
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yaml",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.4",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"author": "Eemeli Aro <eemeli@gmail.com>",
|
|
6
6
|
"repository": "github:eemeli/yaml",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"clean": "git clean -fdxe node_modules",
|
|
45
45
|
"lint": "eslint src/",
|
|
46
46
|
"prettier": "prettier --write .",
|
|
47
|
-
"prestart": "
|
|
48
|
-
"start": "node -i -e 'YAML=require(\"./dist/index.js\")'",
|
|
47
|
+
"prestart": "rollup --sourcemap -c config/rollup.node-config.mjs",
|
|
48
|
+
"start": "node --enable-source-maps -i -e 'YAML=require(\"./dist/index.js\");const{parse,parseDocument,parseAllDocuments}=YAML'",
|
|
49
49
|
"test": "jest --config config/jest.config.js",
|
|
50
50
|
"test:all": "npm test && npm run test:types && npm run test:dist && npm run test:dist:types",
|
|
51
51
|
"test:browsers": "cd playground && npm test",
|