yaml 2.0.0-9 → 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.
- package/README.md +1 -1
- package/browser/dist/compose/compose-doc.js +3 -2
- package/browser/dist/compose/compose-node.js +13 -4
- package/browser/dist/compose/compose-scalar.js +16 -10
- package/browser/dist/compose/composer.js +6 -7
- package/browser/dist/compose/resolve-block-map.js +9 -2
- package/browser/dist/compose/resolve-block-scalar.js +12 -3
- package/browser/dist/compose/resolve-block-seq.js +5 -0
- package/browser/dist/compose/resolve-flow-collection.js +14 -5
- package/browser/dist/compose/resolve-flow-scalar.js +2 -1
- package/browser/dist/compose/resolve-props.js +4 -0
- package/browser/dist/compose/util-flow-indent-check.js +15 -0
- package/browser/dist/doc/Document.js +49 -16
- package/browser/dist/doc/anchors.js +2 -2
- package/browser/dist/doc/createNode.js +7 -4
- package/browser/dist/doc/directives.js +7 -4
- package/browser/dist/index.js +1 -2
- package/browser/dist/nodes/Pair.js +2 -2
- package/browser/dist/nodes/Scalar.js +1 -1
- package/browser/dist/nodes/YAMLMap.js +6 -5
- package/browser/dist/nodes/YAMLSeq.js +2 -2
- package/browser/dist/nodes/addPairToJSMap.js +1 -1
- package/browser/dist/nodes/toJS.js +3 -1
- package/browser/dist/parse/cst-visit.js +2 -2
- package/browser/dist/parse/lexer.js +21 -8
- package/browser/dist/parse/parser.js +121 -45
- package/browser/dist/public-api.js +4 -5
- package/browser/dist/schema/Schema.js +14 -4
- package/browser/dist/schema/common/null.js +3 -1
- package/browser/dist/schema/core/float.js +4 -1
- package/browser/dist/schema/tags.js +9 -9
- package/browser/dist/schema/yaml-1.1/float.js +4 -1
- package/browser/dist/schema/yaml-1.1/omap.js +1 -1
- package/browser/dist/schema/yaml-1.1/pairs.js +2 -1
- package/browser/dist/stringify/stringify.js +51 -22
- package/browser/dist/stringify/stringifyCollection.js +115 -85
- package/browser/dist/stringify/stringifyComment.js +18 -12
- package/browser/dist/stringify/stringifyDocument.js +37 -15
- package/browser/dist/stringify/stringifyPair.js +34 -20
- package/browser/dist/stringify/stringifyString.js +8 -11
- package/browser/dist/visit.js +150 -62
- package/dist/compose/compose-doc.js +3 -2
- package/dist/compose/compose-node.d.ts +1 -0
- package/dist/compose/compose-node.js +13 -4
- package/dist/compose/compose-scalar.js +15 -9
- package/dist/compose/composer.d.ts +1 -1
- package/dist/compose/composer.js +8 -9
- package/dist/compose/resolve-block-map.js +9 -2
- package/dist/compose/resolve-block-scalar.js +12 -3
- package/dist/compose/resolve-block-seq.js +5 -0
- package/dist/compose/resolve-flow-collection.js +14 -5
- package/dist/compose/resolve-flow-scalar.js +2 -1
- package/dist/compose/resolve-props.d.ts +1 -1
- package/dist/compose/resolve-props.js +4 -0
- package/dist/compose/util-flow-indent-check.d.ts +3 -0
- package/dist/compose/util-flow-indent-check.js +17 -0
- package/dist/doc/Document.d.ts +7 -4
- package/dist/doc/Document.js +56 -23
- package/dist/doc/anchors.d.ts +2 -2
- package/dist/doc/anchors.js +2 -2
- package/dist/doc/createNode.d.ts +1 -1
- package/dist/doc/createNode.js +7 -4
- package/dist/doc/directives.d.ts +4 -2
- package/dist/doc/directives.js +7 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -2
- package/dist/nodes/Pair.js +2 -2
- package/dist/nodes/Scalar.js +1 -1
- package/dist/nodes/YAMLMap.d.ts +3 -1
- package/dist/nodes/YAMLMap.js +6 -5
- package/dist/nodes/YAMLSeq.js +2 -2
- package/dist/nodes/addPairToJSMap.js +1 -1
- package/dist/nodes/toJS.js +3 -1
- package/dist/options.d.ts +42 -12
- package/dist/parse/cst-visit.js +2 -2
- package/dist/parse/lexer.js +21 -8
- package/dist/parse/parser.js +121 -45
- package/dist/public-api.js +4 -5
- package/dist/schema/Schema.d.ts +5 -4
- package/dist/schema/Schema.js +13 -3
- package/dist/schema/common/null.js +3 -1
- package/dist/schema/core/float.js +4 -1
- package/dist/schema/tags.d.ts +1 -2
- package/dist/schema/tags.js +9 -9
- package/dist/schema/yaml-1.1/float.js +4 -1
- package/dist/schema/yaml-1.1/omap.js +1 -1
- package/dist/schema/yaml-1.1/pairs.js +2 -1
- package/dist/stringify/stringify.d.ts +5 -3
- package/dist/stringify/stringify.js +51 -22
- package/dist/stringify/stringifyCollection.d.ts +2 -6
- package/dist/stringify/stringifyCollection.js +114 -84
- package/dist/stringify/stringifyComment.d.ts +10 -2
- package/dist/stringify/stringifyComment.js +19 -12
- package/dist/stringify/stringifyDocument.js +36 -14
- package/dist/stringify/stringifyPair.js +33 -19
- package/dist/stringify/stringifyString.js +8 -11
- package/dist/test-events.js +13 -12
- package/dist/visit.d.ts +49 -10
- package/dist/visit.js +149 -60
- package/package.json +9 -8
- package/browser/dist/options.js +0 -18
- package/dist/options.js +0 -20
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ For more information, see the project's documentation site: [**eemeli.org/yaml**
|
|
|
19
19
|
To install:
|
|
20
20
|
|
|
21
21
|
```sh
|
|
22
|
-
npm install
|
|
22
|
+
npm install yaml
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
**Note:** These docs are for `yaml@2`. For v1, see the [v1.10.0 tag](https://github.com/eemeli/yaml/tree/v1.10.0) for the source and [eemeli.org/yaml/v1](https://eemeli.org/yaml/v1/) for the documentation.
|
|
@@ -7,19 +7,20 @@ function composeDoc(options, directives, { offset, start, value, end }, onError)
|
|
|
7
7
|
const opts = Object.assign({ directives }, options);
|
|
8
8
|
const doc = new Document(undefined, opts);
|
|
9
9
|
const ctx = {
|
|
10
|
+
atRoot: true,
|
|
10
11
|
directives: doc.directives,
|
|
11
12
|
options: doc.options,
|
|
12
13
|
schema: doc.schema
|
|
13
14
|
};
|
|
14
15
|
const props = resolveProps(start, {
|
|
15
16
|
indicator: 'doc-start',
|
|
16
|
-
next: value
|
|
17
|
+
next: value !== null && value !== void 0 ? value : end === null || end === void 0 ? void 0 : end[0],
|
|
17
18
|
offset,
|
|
18
19
|
onError,
|
|
19
20
|
startOnNewline: true
|
|
20
21
|
});
|
|
21
22
|
if (props.found) {
|
|
22
|
-
doc.directives.
|
|
23
|
+
doc.directives.docStart = true;
|
|
23
24
|
if (value &&
|
|
24
25
|
(value.type === 'block-map' || value.type === 'block-seq') &&
|
|
25
26
|
!props.hasNewline)
|
|
@@ -8,6 +8,7 @@ const CN = { composeNode, composeEmptyNode };
|
|
|
8
8
|
function composeNode(ctx, token, props, onError) {
|
|
9
9
|
const { spaceBefore, comment, anchor, tag } = props;
|
|
10
10
|
let node;
|
|
11
|
+
let isSrcToken = true;
|
|
11
12
|
switch (token.type) {
|
|
12
13
|
case 'alias':
|
|
13
14
|
node = composeAlias(ctx, token, onError);
|
|
@@ -29,9 +30,14 @@ function composeNode(ctx, token, props, onError) {
|
|
|
29
30
|
if (anchor)
|
|
30
31
|
node.anchor = anchor.source.substring(1);
|
|
31
32
|
break;
|
|
32
|
-
default:
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
default: {
|
|
34
|
+
const message = token.type === 'error'
|
|
35
|
+
? token.message
|
|
36
|
+
: `Unsupported token (type: ${token.type})`;
|
|
37
|
+
onError(token, 'UNEXPECTED_TOKEN', message);
|
|
38
|
+
node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError);
|
|
39
|
+
isSrcToken = false;
|
|
40
|
+
}
|
|
35
41
|
}
|
|
36
42
|
if (anchor && node.anchor === '')
|
|
37
43
|
onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');
|
|
@@ -43,7 +49,8 @@ function composeNode(ctx, token, props, onError) {
|
|
|
43
49
|
else
|
|
44
50
|
node.commentBefore = comment;
|
|
45
51
|
}
|
|
46
|
-
|
|
52
|
+
// @ts-expect-error Type checking misses meaning of isSrcToken
|
|
53
|
+
if (ctx.options.keepSourceTokens && isSrcToken)
|
|
47
54
|
node.srcToken = token;
|
|
48
55
|
return node;
|
|
49
56
|
}
|
|
@@ -70,6 +77,8 @@ function composeAlias({ options }, { offset, source, end }, onError) {
|
|
|
70
77
|
const alias = new Alias(source.substring(1));
|
|
71
78
|
if (alias.source === '')
|
|
72
79
|
onError(offset, 'BAD_ALIAS', 'Alias cannot be an empty string');
|
|
80
|
+
if (alias.source.endsWith(':'))
|
|
81
|
+
onError(offset + source.length - 1, 'BAD_ALIAS', 'Alias ending in : is ambiguous', true);
|
|
73
82
|
const valueEnd = offset + source.length;
|
|
74
83
|
const re = resolveEnd(end, valueEnd, options.strict, onError);
|
|
75
84
|
alias.range = [offset, valueEnd, re.offset];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SCALAR, isScalar } from '../nodes/Node.js';
|
|
2
2
|
import { Scalar } from '../nodes/Scalar.js';
|
|
3
3
|
import { resolveBlockScalar } from './resolve-block-scalar.js';
|
|
4
4
|
import { resolveFlowScalar } from './resolve-flow-scalar.js';
|
|
@@ -12,15 +12,17 @@ function composeScalar(ctx, token, tagToken, onError) {
|
|
|
12
12
|
: null;
|
|
13
13
|
const tag = tagToken && tagName
|
|
14
14
|
? findScalarTagByName(ctx.schema, value, tagName, tagToken, onError)
|
|
15
|
-
:
|
|
15
|
+
: token.type === 'scalar'
|
|
16
|
+
? findScalarTagByTest(ctx, value, token, onError)
|
|
17
|
+
: ctx.schema[SCALAR];
|
|
16
18
|
let scalar;
|
|
17
19
|
try {
|
|
18
|
-
const res = tag.resolve(value, msg => onError(tagToken
|
|
20
|
+
const res = tag.resolve(value, msg => onError(tagToken !== null && tagToken !== void 0 ? tagToken : token, 'TAG_RESOLVE_FAILED', msg), ctx.options);
|
|
19
21
|
scalar = isScalar(res) ? res : new Scalar(res);
|
|
20
22
|
}
|
|
21
23
|
catch (error) {
|
|
22
24
|
const msg = error instanceof Error ? error.message : String(error);
|
|
23
|
-
onError(tagToken
|
|
25
|
+
onError(tagToken !== null && tagToken !== void 0 ? tagToken : token, 'TAG_RESOLVE_FAILED', msg);
|
|
24
26
|
scalar = new Scalar(value);
|
|
25
27
|
}
|
|
26
28
|
scalar.range = range;
|
|
@@ -61,15 +63,19 @@ function findScalarTagByName(schema, value, tagName, tagToken, onError) {
|
|
|
61
63
|
onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, tagName !== 'tag:yaml.org,2002:str');
|
|
62
64
|
return schema[SCALAR];
|
|
63
65
|
}
|
|
64
|
-
function findScalarTagByTest(schema, value,
|
|
66
|
+
function findScalarTagByTest({ directives, schema }, value, token, onError) {
|
|
65
67
|
var _a;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
const tag = schema.tags.find(tag => { var _a; return tag.default && ((_a = tag.test) === null || _a === void 0 ? void 0 : _a.test(value)); }) || schema[SCALAR];
|
|
69
|
+
if (schema.compat) {
|
|
70
|
+
const compat = (_a = schema.compat.find(tag => { var _a; return tag.default && ((_a = tag.test) === null || _a === void 0 ? void 0 : _a.test(value)); })) !== null && _a !== void 0 ? _a : schema[SCALAR];
|
|
71
|
+
if (tag.tag !== compat.tag) {
|
|
72
|
+
const ts = directives.tagString(tag.tag);
|
|
73
|
+
const cs = directives.tagString(compat.tag);
|
|
74
|
+
const msg = `Value may be parsed as either ${ts} or ${cs}`;
|
|
75
|
+
onError(token, 'TAG_RESOLVE_FAILED', msg, true);
|
|
70
76
|
}
|
|
71
77
|
}
|
|
72
|
-
return
|
|
78
|
+
return tag;
|
|
73
79
|
}
|
|
74
80
|
|
|
75
81
|
export { composeScalar };
|
|
@@ -2,7 +2,6 @@ import { Directives } from '../doc/directives.js';
|
|
|
2
2
|
import { Document } from '../doc/Document.js';
|
|
3
3
|
import { YAMLWarning, YAMLParseError } from '../errors.js';
|
|
4
4
|
import { isCollection, isPair } from '../nodes/Node.js';
|
|
5
|
-
import { defaultOptions } from '../options.js';
|
|
6
5
|
import { composeDoc } from './compose-doc.js';
|
|
7
6
|
import { resolveEnd } from './resolve-end.js';
|
|
8
7
|
|
|
@@ -68,9 +67,8 @@ class Composer {
|
|
|
68
67
|
else
|
|
69
68
|
this.errors.push(new YAMLParseError(pos, code, message));
|
|
70
69
|
};
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
});
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
71
|
+
this.directives = new Directives({ version: options.version || '1.2' });
|
|
74
72
|
this.options = options;
|
|
75
73
|
}
|
|
76
74
|
decorate(doc, afterDoc) {
|
|
@@ -81,7 +79,7 @@ class Composer {
|
|
|
81
79
|
if (afterDoc) {
|
|
82
80
|
doc.comment = doc.comment ? `${doc.comment}\n${comment}` : comment;
|
|
83
81
|
}
|
|
84
|
-
else if (afterEmptyLine || doc.directives.
|
|
82
|
+
else if (afterEmptyLine || doc.directives.docStart || !dc) {
|
|
85
83
|
doc.commentBefore = comment;
|
|
86
84
|
}
|
|
87
85
|
else if (isCollection(dc) && !dc.flow && dc.items.length > 0) {
|
|
@@ -146,8 +144,8 @@ class Composer {
|
|
|
146
144
|
break;
|
|
147
145
|
case 'document': {
|
|
148
146
|
const doc = composeDoc(this.options, this.directives, token, this.onError);
|
|
149
|
-
if (this.atDirectives && !doc.directives.
|
|
150
|
-
this.onError(token, 'MISSING_CHAR', 'Missing directives-end indicator line');
|
|
147
|
+
if (this.atDirectives && !doc.directives.docStart)
|
|
148
|
+
this.onError(token, 'MISSING_CHAR', 'Missing directives-end/doc-start indicator line');
|
|
151
149
|
this.decorate(doc, false);
|
|
152
150
|
if (this.doc)
|
|
153
151
|
yield this.doc;
|
|
@@ -179,6 +177,7 @@ class Composer {
|
|
|
179
177
|
this.errors.push(new YAMLParseError(getErrorPos(token), 'UNEXPECTED_TOKEN', msg));
|
|
180
178
|
break;
|
|
181
179
|
}
|
|
180
|
+
this.doc.directives.docEnd = true;
|
|
182
181
|
const end = resolveEnd(token.end, token.offset + token.source.length, this.doc.options.strict, this.onError);
|
|
183
182
|
this.decorate(this.doc, true);
|
|
184
183
|
if (end.comment) {
|
|
@@ -2,19 +2,22 @@ import { Pair } from '../nodes/Pair.js';
|
|
|
2
2
|
import { YAMLMap } from '../nodes/YAMLMap.js';
|
|
3
3
|
import { resolveProps } from './resolve-props.js';
|
|
4
4
|
import { containsNewline } from './util-contains-newline.js';
|
|
5
|
+
import { flowIndentCheck } from './util-flow-indent-check.js';
|
|
5
6
|
import { mapIncludes } from './util-map-includes.js';
|
|
6
7
|
|
|
7
8
|
const startColMsg = 'All mapping items must start at the same column';
|
|
8
9
|
function resolveBlockMap({ composeNode, composeEmptyNode }, ctx, bm, onError) {
|
|
9
10
|
var _a;
|
|
10
11
|
const map = new YAMLMap(ctx.schema);
|
|
12
|
+
if (ctx.atRoot)
|
|
13
|
+
ctx.atRoot = false;
|
|
11
14
|
let offset = bm.offset;
|
|
12
15
|
for (const collItem of bm.items) {
|
|
13
16
|
const { start, key, sep, value } = collItem;
|
|
14
17
|
// key properties
|
|
15
18
|
const keyProps = resolveProps(start, {
|
|
16
19
|
indicator: 'explicit-key-ind',
|
|
17
|
-
next: key
|
|
20
|
+
next: key !== null && key !== void 0 ? key : sep === null || sep === void 0 ? void 0 : sep[0],
|
|
18
21
|
offset,
|
|
19
22
|
onError,
|
|
20
23
|
startOnNewline: true
|
|
@@ -48,10 +51,12 @@ function resolveBlockMap({ composeNode, composeEmptyNode }, ctx, bm, onError) {
|
|
|
48
51
|
const keyNode = key
|
|
49
52
|
? composeNode(ctx, key, keyProps, onError)
|
|
50
53
|
: composeEmptyNode(ctx, keyStart, start, null, keyProps, onError);
|
|
54
|
+
if (ctx.schema.compat)
|
|
55
|
+
flowIndentCheck(bm.indent, key, onError);
|
|
51
56
|
if (mapIncludes(ctx, map.items, keyNode))
|
|
52
57
|
onError(keyStart, 'DUPLICATE_KEY', 'Map keys must be unique');
|
|
53
58
|
// value properties
|
|
54
|
-
const valueProps = resolveProps(sep
|
|
59
|
+
const valueProps = resolveProps(sep !== null && sep !== void 0 ? sep : [], {
|
|
55
60
|
indicator: 'map-value-ind',
|
|
56
61
|
next: value,
|
|
57
62
|
offset: keyNode.range[2],
|
|
@@ -71,6 +76,8 @@ function resolveBlockMap({ composeNode, composeEmptyNode }, ctx, bm, onError) {
|
|
|
71
76
|
const valueNode = value
|
|
72
77
|
? composeNode(ctx, value, valueProps, onError)
|
|
73
78
|
: composeEmptyNode(ctx, offset, sep, null, valueProps, onError);
|
|
79
|
+
if (ctx.schema.compat)
|
|
80
|
+
flowIndentCheck(bm.indent, value, onError);
|
|
74
81
|
offset = valueNode.range[2];
|
|
75
82
|
const pair = new Pair(keyNode, valueNode);
|
|
76
83
|
if (ctx.options.keepSourceTokens)
|
|
@@ -17,8 +17,10 @@ function resolveBlockScalar(scalar, strict, onError) {
|
|
|
17
17
|
break;
|
|
18
18
|
}
|
|
19
19
|
// shortcut for empty contents
|
|
20
|
-
if (
|
|
21
|
-
const value = header.chomp === '+'
|
|
20
|
+
if (chompStart === 0) {
|
|
21
|
+
const value = header.chomp === '+' && lines.length > 0
|
|
22
|
+
? '\n'.repeat(Math.max(1, lines.length - 1))
|
|
23
|
+
: '';
|
|
22
24
|
let end = start + header.length;
|
|
23
25
|
if (scalar.source)
|
|
24
26
|
end += scalar.source.length;
|
|
@@ -46,6 +48,11 @@ function resolveBlockScalar(scalar, strict, onError) {
|
|
|
46
48
|
}
|
|
47
49
|
offset += indent.length + content.length + 1;
|
|
48
50
|
}
|
|
51
|
+
// include trailing more-indented empty lines in content
|
|
52
|
+
for (let i = lines.length - 1; i >= chompStart; --i) {
|
|
53
|
+
if (lines[i][0].length > trimIndent)
|
|
54
|
+
chompStart = i + 1;
|
|
55
|
+
}
|
|
49
56
|
let value = '';
|
|
50
57
|
let sep = '';
|
|
51
58
|
let prevMoreIndented = false;
|
|
@@ -175,7 +182,9 @@ function splitLines(source) {
|
|
|
175
182
|
const split = source.split(/\n( *)/);
|
|
176
183
|
const first = split[0];
|
|
177
184
|
const m = first.match(/^( *)/);
|
|
178
|
-
const line0 = m
|
|
185
|
+
const line0 = (m === null || m === void 0 ? void 0 : m[1])
|
|
186
|
+
? [m[1], first.slice(m[1].length)]
|
|
187
|
+
: ['', first];
|
|
179
188
|
const lines = [line0];
|
|
180
189
|
for (let i = 1; i < split.length; i += 2)
|
|
181
190
|
lines.push([split[i], split[i + 1]]);
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { YAMLSeq } from '../nodes/YAMLSeq.js';
|
|
2
2
|
import { resolveProps } from './resolve-props.js';
|
|
3
|
+
import { flowIndentCheck } from './util-flow-indent-check.js';
|
|
3
4
|
|
|
4
5
|
function resolveBlockSeq({ composeNode, composeEmptyNode }, ctx, bs, onError) {
|
|
5
6
|
const seq = new YAMLSeq(ctx.schema);
|
|
7
|
+
if (ctx.atRoot)
|
|
8
|
+
ctx.atRoot = false;
|
|
6
9
|
let offset = bs.offset;
|
|
7
10
|
for (const { start, value } of bs.items) {
|
|
8
11
|
const props = resolveProps(start, {
|
|
@@ -30,6 +33,8 @@ function resolveBlockSeq({ composeNode, composeEmptyNode }, ctx, bs, onError) {
|
|
|
30
33
|
const node = value
|
|
31
34
|
? composeNode(ctx, value, props, onError)
|
|
32
35
|
: composeEmptyNode(ctx, offset, start, null, props, onError);
|
|
36
|
+
if (ctx.schema.compat)
|
|
37
|
+
flowIndentCheck(bs.indent, value, onError);
|
|
33
38
|
offset = node.range[2];
|
|
34
39
|
seq.items.push(node);
|
|
35
40
|
}
|
|
@@ -10,20 +10,24 @@ import { mapIncludes } from './util-map-includes.js';
|
|
|
10
10
|
const blockMsg = 'Block collections are not allowed within flow collections';
|
|
11
11
|
const isBlock = (token) => token && (token.type === 'block-map' || token.type === 'block-seq');
|
|
12
12
|
function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onError) {
|
|
13
|
+
var _a;
|
|
13
14
|
const isMap = fc.start.source === '{';
|
|
14
15
|
const fcName = isMap ? 'flow map' : 'flow sequence';
|
|
15
16
|
const coll = isMap
|
|
16
17
|
? new YAMLMap(ctx.schema)
|
|
17
18
|
: new YAMLSeq(ctx.schema);
|
|
18
19
|
coll.flow = true;
|
|
19
|
-
|
|
20
|
+
const atRoot = ctx.atRoot;
|
|
21
|
+
if (atRoot)
|
|
22
|
+
ctx.atRoot = false;
|
|
23
|
+
let offset = fc.offset + fc.start.source.length;
|
|
20
24
|
for (let i = 0; i < fc.items.length; ++i) {
|
|
21
25
|
const collItem = fc.items[i];
|
|
22
26
|
const { start, key, sep, value } = collItem;
|
|
23
27
|
const props = resolveProps(start, {
|
|
24
28
|
flow: fcName,
|
|
25
29
|
indicator: 'explicit-key-ind',
|
|
26
|
-
next: key
|
|
30
|
+
next: key !== null && key !== void 0 ? key : sep === null || sep === void 0 ? void 0 : sep[0],
|
|
27
31
|
offset,
|
|
28
32
|
onError,
|
|
29
33
|
startOnNewline: false
|
|
@@ -40,6 +44,7 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr
|
|
|
40
44
|
else
|
|
41
45
|
coll.comment = props.comment;
|
|
42
46
|
}
|
|
47
|
+
offset = props.end;
|
|
43
48
|
continue;
|
|
44
49
|
}
|
|
45
50
|
if (!isMap && ctx.options.strict && containsNewline(key))
|
|
@@ -70,7 +75,7 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr
|
|
|
70
75
|
if (prevItemComment) {
|
|
71
76
|
let prev = coll.items[coll.items.length - 1];
|
|
72
77
|
if (isPair(prev))
|
|
73
|
-
prev = prev.value
|
|
78
|
+
prev = (_a = prev.value) !== null && _a !== void 0 ? _a : prev.key;
|
|
74
79
|
if (prev.comment)
|
|
75
80
|
prev.comment += '\n' + prevItemComment;
|
|
76
81
|
else
|
|
@@ -100,7 +105,7 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr
|
|
|
100
105
|
if (isBlock(key))
|
|
101
106
|
onError(keyNode.range, 'BLOCK_IN_FLOW', blockMsg);
|
|
102
107
|
// value properties
|
|
103
|
-
const valueProps = resolveProps(sep
|
|
108
|
+
const valueProps = resolveProps(sep !== null && sep !== void 0 ? sep : [], {
|
|
104
109
|
flow: fcName,
|
|
105
110
|
indicator: 'map-value-ind',
|
|
106
111
|
next: value,
|
|
@@ -169,7 +174,11 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr
|
|
|
169
174
|
if (ce && ce.source === expectedEnd)
|
|
170
175
|
cePos = ce.offset + ce.source.length;
|
|
171
176
|
else {
|
|
172
|
-
|
|
177
|
+
const name = fcName[0].toUpperCase() + fcName.substring(1);
|
|
178
|
+
const msg = atRoot
|
|
179
|
+
? `${name} must end with a ${expectedEnd}`
|
|
180
|
+
: `${name} in block collection must be sufficiently indented and end with a ${expectedEnd}`;
|
|
181
|
+
onError(offset, atRoot ? 'MISSING_CHAR' : 'BAD_INDENT', msg);
|
|
173
182
|
if (ce && ce.source.length !== 1)
|
|
174
183
|
ee.unshift(ce);
|
|
175
184
|
}
|
|
@@ -72,6 +72,7 @@ function singleQuotedValue(source, onError) {
|
|
|
72
72
|
return foldLines(source.slice(1, -1)).replace(/''/g, "'");
|
|
73
73
|
}
|
|
74
74
|
function foldLines(source) {
|
|
75
|
+
var _a;
|
|
75
76
|
/**
|
|
76
77
|
* The negative lookbehind here and in the `re` RegExp is to
|
|
77
78
|
* prevent causing a polynomial search time in certain cases.
|
|
@@ -111,7 +112,7 @@ function foldLines(source) {
|
|
|
111
112
|
const last = /[ \t]*(.*)/sy;
|
|
112
113
|
last.lastIndex = pos;
|
|
113
114
|
match = last.exec(source);
|
|
114
|
-
return res + sep + ((match
|
|
115
|
+
return res + sep + ((_a = match === null || match === void 0 ? void 0 : match[1]) !== null && _a !== void 0 ? _a : '');
|
|
115
116
|
}
|
|
116
117
|
function doubleQuotedValue(source, onError) {
|
|
117
118
|
let res = '';
|
|
@@ -59,6 +59,8 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
|
|
|
59
59
|
case 'anchor':
|
|
60
60
|
if (anchor)
|
|
61
61
|
onError(token, 'MULTIPLE_ANCHORS', 'A node can have at most one anchor');
|
|
62
|
+
if (token.source.endsWith(':'))
|
|
63
|
+
onError(token.offset + token.source.length - 1, 'BAD_ALIAS', 'Anchor ending in : is ambiguous', true);
|
|
62
64
|
anchor = token;
|
|
63
65
|
if (start === null)
|
|
64
66
|
start = token.offset;
|
|
@@ -81,6 +83,8 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
|
|
|
81
83
|
// Could here handle preceding comments differently
|
|
82
84
|
if (anchor || tag)
|
|
83
85
|
onError(token, 'BAD_PROP_ORDER', `Anchors and tags must be after the ${token.source} indicator`);
|
|
86
|
+
if (found)
|
|
87
|
+
onError(token, 'UNEXPECTED_TOKEN', `Unexpected ${token.source} in ${flow !== null && flow !== void 0 ? flow : 'collection'}`);
|
|
84
88
|
found = token;
|
|
85
89
|
atNewline = false;
|
|
86
90
|
hasSpace = false;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { containsNewline } from './util-contains-newline.js';
|
|
2
|
+
|
|
3
|
+
function flowIndentCheck(indent, fc, onError) {
|
|
4
|
+
if ((fc === null || fc === void 0 ? void 0 : fc.type) === 'flow-collection') {
|
|
5
|
+
const end = fc.end[0];
|
|
6
|
+
if (end.indent === indent &&
|
|
7
|
+
(end.source === ']' || end.source === '}') &&
|
|
8
|
+
containsNewline(fc)) {
|
|
9
|
+
const msg = 'Flow end indicator should be more indented than parent';
|
|
10
|
+
onError(end, 'BAD_INDENT', msg, true);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { flowIndentCheck };
|
|
@@ -3,7 +3,6 @@ import { isEmptyPath, collectionFromPath } from '../nodes/Collection.js';
|
|
|
3
3
|
import { NODE_TYPE, DOC, isNode, isCollection, isScalar } from '../nodes/Node.js';
|
|
4
4
|
import { Pair } from '../nodes/Pair.js';
|
|
5
5
|
import { toJS } from '../nodes/toJS.js';
|
|
6
|
-
import { defaultOptions } from '../options.js';
|
|
7
6
|
import { Schema } from '../schema/Schema.js';
|
|
8
7
|
import { stringify } from '../stringify/stringify.js';
|
|
9
8
|
import { stringifyDocument } from '../stringify/stringifyDocument.js';
|
|
@@ -31,7 +30,15 @@ class Document {
|
|
|
31
30
|
options = replacer;
|
|
32
31
|
replacer = undefined;
|
|
33
32
|
}
|
|
34
|
-
const opt = Object.assign({
|
|
33
|
+
const opt = Object.assign({
|
|
34
|
+
intAsBigInt: false,
|
|
35
|
+
keepSourceTokens: false,
|
|
36
|
+
logLevel: 'warn',
|
|
37
|
+
prettyErrors: true,
|
|
38
|
+
strict: true,
|
|
39
|
+
uniqueKeys: true,
|
|
40
|
+
version: '1.2'
|
|
41
|
+
}, options);
|
|
35
42
|
this.options = opt;
|
|
36
43
|
let { version } = opt;
|
|
37
44
|
if (options === null || options === void 0 ? void 0 : options.directives) {
|
|
@@ -62,7 +69,8 @@ class Document {
|
|
|
62
69
|
copy.errors = this.errors.slice();
|
|
63
70
|
copy.warnings = this.warnings.slice();
|
|
64
71
|
copy.options = Object.assign({}, this.options);
|
|
65
|
-
|
|
72
|
+
if (this.directives)
|
|
73
|
+
copy.directives = this.directives.clone();
|
|
66
74
|
copy.schema = this.schema.clone();
|
|
67
75
|
copy.contents = isNode(this.contents)
|
|
68
76
|
? this.contents.clone(copy.schema)
|
|
@@ -94,6 +102,7 @@ class Document {
|
|
|
94
102
|
if (!node.anchor) {
|
|
95
103
|
const prev = anchorNames(this);
|
|
96
104
|
node.anchor =
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
97
106
|
!name || prev.has(name) ? findNewAnchor(name || 'a', prev) : name;
|
|
98
107
|
}
|
|
99
108
|
return new Alias(node.anchor);
|
|
@@ -115,8 +124,10 @@ class Document {
|
|
|
115
124
|
options = replacer;
|
|
116
125
|
replacer = undefined;
|
|
117
126
|
}
|
|
118
|
-
const { aliasDuplicateObjects, anchorPrefix, flow, keepUndefined, onTagObj, tag } = options
|
|
119
|
-
const { onAnchor, setAnchors, sourceObjects } = createNodeAnchors(this,
|
|
127
|
+
const { aliasDuplicateObjects, anchorPrefix, flow, keepUndefined, onTagObj, tag } = options !== null && options !== void 0 ? options : {};
|
|
128
|
+
const { onAnchor, setAnchors, sourceObjects } = createNodeAnchors(this,
|
|
129
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
130
|
+
anchorPrefix || 'a');
|
|
120
131
|
const ctx = {
|
|
121
132
|
aliasDuplicateObjects: aliasDuplicateObjects !== null && aliasDuplicateObjects !== void 0 ? aliasDuplicateObjects : true,
|
|
122
133
|
keepUndefined: keepUndefined !== null && keepUndefined !== void 0 ? keepUndefined : false,
|
|
@@ -229,26 +240,48 @@ class Document {
|
|
|
229
240
|
}
|
|
230
241
|
/**
|
|
231
242
|
* Change the YAML version and schema used by the document.
|
|
243
|
+
* A `null` version disables support for directives, explicit tags, anchors, and aliases.
|
|
244
|
+
* It also requires the `schema` option to be given as a `Schema` instance value.
|
|
232
245
|
*
|
|
233
|
-
* Overrides all previously set schema options
|
|
246
|
+
* Overrides all previously set schema options.
|
|
234
247
|
*/
|
|
235
|
-
setSchema(version, options) {
|
|
236
|
-
|
|
237
|
-
|
|
248
|
+
setSchema(version, options = {}) {
|
|
249
|
+
if (typeof version === 'number')
|
|
250
|
+
version = String(version);
|
|
251
|
+
let opt;
|
|
252
|
+
switch (version) {
|
|
238
253
|
case '1.1':
|
|
239
|
-
this.directives
|
|
240
|
-
|
|
254
|
+
if (this.directives)
|
|
255
|
+
this.directives.yaml.version = '1.1';
|
|
256
|
+
else
|
|
257
|
+
this.directives = new Directives({ version: '1.1' });
|
|
258
|
+
opt = { merge: true, resolveKnownTags: false, schema: 'yaml-1.1' };
|
|
241
259
|
break;
|
|
242
260
|
case '1.2':
|
|
243
|
-
|
|
244
|
-
|
|
261
|
+
case 'next':
|
|
262
|
+
if (this.directives)
|
|
263
|
+
this.directives.yaml.version = version;
|
|
264
|
+
else
|
|
265
|
+
this.directives = new Directives({ version });
|
|
266
|
+
opt = { merge: false, resolveKnownTags: true, schema: 'core' };
|
|
267
|
+
break;
|
|
268
|
+
case null:
|
|
269
|
+
if (this.directives)
|
|
270
|
+
delete this.directives;
|
|
271
|
+
opt = null;
|
|
245
272
|
break;
|
|
246
273
|
default: {
|
|
247
274
|
const sv = JSON.stringify(version);
|
|
248
|
-
throw new Error(`Expected '1.1'
|
|
275
|
+
throw new Error(`Expected '1.1', '1.2' or null as first argument, but found: ${sv}`);
|
|
249
276
|
}
|
|
250
277
|
}
|
|
251
|
-
|
|
278
|
+
// Not using `instanceof Schema` to allow for duck typing
|
|
279
|
+
if (options.schema instanceof Object)
|
|
280
|
+
this.schema = options.schema;
|
|
281
|
+
else if (opt)
|
|
282
|
+
this.schema = new Schema(Object.assign(opt, options));
|
|
283
|
+
else
|
|
284
|
+
throw new Error(`With a null YAML version, the { schema: Schema } option is required`);
|
|
252
285
|
}
|
|
253
286
|
// json & jsonArg are only used from toJSON()
|
|
254
287
|
toJS({ json, jsonArg, mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {
|
|
@@ -261,7 +294,7 @@ class Document {
|
|
|
261
294
|
maxAliasCount: typeof maxAliasCount === 'number' ? maxAliasCount : 100,
|
|
262
295
|
stringify
|
|
263
296
|
};
|
|
264
|
-
const res = toJS(this.contents, jsonArg
|
|
297
|
+
const res = toJS(this.contents, jsonArg !== null && jsonArg !== void 0 ? jsonArg : '', ctx);
|
|
265
298
|
if (typeof onAnchor === 'function')
|
|
266
299
|
for (const { count, res } of ctx.anchors.values())
|
|
267
300
|
onAnchor(res, count);
|
|
@@ -37,7 +37,7 @@ function createNodeAnchors(doc, prefix) {
|
|
|
37
37
|
const sourceObjects = new Map();
|
|
38
38
|
let prevAnchors = null;
|
|
39
39
|
return {
|
|
40
|
-
onAnchor(source) {
|
|
40
|
+
onAnchor: (source) => {
|
|
41
41
|
aliasObjects.push(source);
|
|
42
42
|
if (!prevAnchors)
|
|
43
43
|
prevAnchors = anchorNames(doc);
|
|
@@ -50,7 +50,7 @@ function createNodeAnchors(doc, prefix) {
|
|
|
50
50
|
* of its child nodes are. This is why anchors are set only after all of
|
|
51
51
|
* the nodes have been created.
|
|
52
52
|
*/
|
|
53
|
-
setAnchors() {
|
|
53
|
+
setAnchors: () => {
|
|
54
54
|
for (const source of aliasObjects) {
|
|
55
55
|
const ref = sourceObjects.get(source);
|
|
56
56
|
if (typeof ref === 'object' &&
|
|
@@ -4,14 +4,15 @@ import { Scalar } from '../nodes/Scalar.js';
|
|
|
4
4
|
|
|
5
5
|
const defaultTagPrefix = 'tag:yaml.org,2002:';
|
|
6
6
|
function findTagObject(value, tagName, tags) {
|
|
7
|
+
var _a;
|
|
7
8
|
if (tagName) {
|
|
8
9
|
const match = tags.filter(t => t.tag === tagName);
|
|
9
|
-
const tagObj = match.find(t => !t.format)
|
|
10
|
+
const tagObj = (_a = match.find(t => !t.format)) !== null && _a !== void 0 ? _a : match[0];
|
|
10
11
|
if (!tagObj)
|
|
11
12
|
throw new Error(`Tag ${tagName} not found`);
|
|
12
13
|
return tagObj;
|
|
13
14
|
}
|
|
14
|
-
return tags.find(t => t.identify
|
|
15
|
+
return tags.find(t => { var _a; return ((_a = t.identify) === null || _a === void 0 ? void 0 : _a.call(t, value)) && !t.format; });
|
|
15
16
|
}
|
|
16
17
|
function createNode(value, tagName, ctx) {
|
|
17
18
|
var _a, _b;
|
|
@@ -48,12 +49,14 @@ function createNode(value, tagName, ctx) {
|
|
|
48
49
|
sourceObjects.set(value, ref);
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
|
-
if (tagName
|
|
52
|
+
if (tagName === null || tagName === void 0 ? void 0 : tagName.startsWith('!!'))
|
|
52
53
|
tagName = defaultTagPrefix + tagName.slice(2);
|
|
53
54
|
let tagObj = findTagObject(value, tagName, schema.tags);
|
|
54
55
|
if (!tagObj) {
|
|
55
|
-
if (value && typeof value.toJSON === 'function')
|
|
56
|
+
if (value && typeof value.toJSON === 'function') {
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
56
58
|
value = value.toJSON();
|
|
59
|
+
}
|
|
57
60
|
if (!value || typeof value !== 'object') {
|
|
58
61
|
const node = new Scalar(value);
|
|
59
62
|
if (ref)
|
|
@@ -16,13 +16,15 @@ class Directives {
|
|
|
16
16
|
* The directives-end/doc-start marker `---`. If `null`, a marker may still be
|
|
17
17
|
* included in the document's stringified representation.
|
|
18
18
|
*/
|
|
19
|
-
this.
|
|
19
|
+
this.docStart = null;
|
|
20
|
+
/** The doc-end marker `...`. */
|
|
21
|
+
this.docEnd = false;
|
|
20
22
|
this.yaml = Object.assign({}, Directives.defaultYaml, yaml);
|
|
21
23
|
this.tags = Object.assign({}, Directives.defaultTags, tags);
|
|
22
24
|
}
|
|
23
25
|
clone() {
|
|
24
26
|
const copy = new Directives(this.yaml, this.tags);
|
|
25
|
-
copy.
|
|
27
|
+
copy.docStart = this.docStart;
|
|
26
28
|
return copy;
|
|
27
29
|
}
|
|
28
30
|
/**
|
|
@@ -71,7 +73,7 @@ class Directives {
|
|
|
71
73
|
}
|
|
72
74
|
case '%YAML': {
|
|
73
75
|
this.yaml.explicit = true;
|
|
74
|
-
if (parts.length
|
|
76
|
+
if (parts.length !== 1) {
|
|
75
77
|
onError(0, '%YAML directive should contain exactly one part');
|
|
76
78
|
return false;
|
|
77
79
|
}
|
|
@@ -81,7 +83,8 @@ class Directives {
|
|
|
81
83
|
return true;
|
|
82
84
|
}
|
|
83
85
|
else {
|
|
84
|
-
|
|
86
|
+
const isValid = /^\d+\.\d+$/.test(version);
|
|
87
|
+
onError(6, `Unsupported YAML version ${version}`, isValid);
|
|
85
88
|
return false;
|
|
86
89
|
}
|
|
87
90
|
}
|
package/browser/dist/index.js
CHANGED
|
@@ -8,11 +8,10 @@ export { Pair } from './nodes/Pair.js';
|
|
|
8
8
|
export { Scalar } from './nodes/Scalar.js';
|
|
9
9
|
export { YAMLMap } from './nodes/YAMLMap.js';
|
|
10
10
|
export { YAMLSeq } from './nodes/YAMLSeq.js';
|
|
11
|
-
export { defaultOptions } from './options.js';
|
|
12
11
|
import * as cst from './parse/cst.js';
|
|
13
12
|
export { cst as CST };
|
|
14
13
|
export { Lexer } from './parse/lexer.js';
|
|
15
14
|
export { LineCounter } from './parse/line-counter.js';
|
|
16
15
|
export { Parser } from './parse/parser.js';
|
|
17
16
|
export { parse, parseAllDocuments, parseDocument, stringify } from './public-api.js';
|
|
18
|
-
export { visit } from './visit.js';
|
|
17
|
+
export { visit, visitAsync } from './visit.js';
|
|
@@ -23,11 +23,11 @@ class Pair {
|
|
|
23
23
|
return new Pair(key, value);
|
|
24
24
|
}
|
|
25
25
|
toJSON(_, ctx) {
|
|
26
|
-
const pair = ctx
|
|
26
|
+
const pair = (ctx === null || ctx === void 0 ? void 0 : ctx.mapAsMap) ? new Map() : {};
|
|
27
27
|
return addPairToJSMap(ctx, pair, this);
|
|
28
28
|
}
|
|
29
29
|
toString(ctx, onComment, onChompKeep) {
|
|
30
|
-
return ctx
|
|
30
|
+
return (ctx === null || ctx === void 0 ? void 0 : ctx.doc)
|
|
31
31
|
? stringifyPair(this, ctx, onComment, onChompKeep)
|
|
32
32
|
: JSON.stringify(this);
|
|
33
33
|
}
|