yaml 2.0.0-4 → 2.0.0-5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/browser/dist/compose/compose-collection.js +12 -9
- package/browser/dist/compose/compose-doc.js +23 -6
- package/browser/dist/compose/compose-node.js +20 -17
- package/browser/dist/compose/compose-scalar.js +20 -23
- package/browser/dist/compose/composer.js +105 -76
- package/browser/dist/compose/resolve-block-map.js +38 -29
- package/browser/dist/compose/resolve-block-scalar.js +14 -17
- package/browser/dist/compose/resolve-block-seq.js +21 -17
- package/browser/dist/compose/resolve-end.js +6 -7
- package/browser/dist/compose/resolve-flow-collection.js +153 -199
- package/browser/dist/compose/resolve-flow-scalar.js +49 -25
- package/browser/dist/compose/resolve-props.js +47 -35
- package/browser/dist/compose/util-contains-newline.js +15 -12
- package/browser/dist/doc/Document.js +50 -99
- package/browser/dist/doc/anchors.js +72 -0
- package/browser/dist/doc/createNode.js +27 -17
- package/browser/dist/errors.js +16 -12
- package/browser/dist/index.js +3 -3
- package/browser/dist/nodes/Alias.js +51 -28
- package/browser/dist/nodes/Collection.js +5 -83
- package/browser/dist/nodes/Node.js +2 -1
- package/browser/dist/nodes/Pair.js +9 -232
- package/browser/dist/nodes/YAMLMap.js +8 -4
- package/browser/dist/nodes/YAMLSeq.js +7 -4
- package/browser/dist/nodes/addPairToJSMap.js +103 -0
- package/browser/dist/nodes/toJS.js +12 -10
- package/browser/dist/options.js +0 -2
- package/browser/dist/parse/cst-scalar.js +219 -0
- package/browser/dist/parse/cst-stringify.js +61 -0
- package/browser/dist/parse/cst-visit.js +97 -0
- package/{dist/parse/tokens.js → browser/dist/parse/cst.js} +12 -7
- package/browser/dist/parse/lexer.js +99 -105
- package/browser/dist/parse/parser.js +219 -144
- package/browser/dist/public-api.js +11 -14
- package/browser/dist/schema/Schema.js +23 -0
- package/browser/dist/{tags/failsafe → schema/common}/map.js +0 -0
- package/browser/dist/schema/common/null.js +13 -0
- package/browser/dist/{tags/failsafe → schema/common}/seq.js +1 -1
- package/browser/dist/{tags/failsafe → schema/common}/string.js +0 -0
- package/browser/dist/schema/core/bool.js +19 -0
- package/browser/dist/schema/core/float.js +40 -0
- package/browser/dist/schema/core/int.js +38 -0
- package/browser/dist/schema/core/schema.js +23 -0
- package/browser/dist/{tags/json.js → schema/json/schema.js} +5 -6
- package/browser/dist/schema/tags.js +79 -0
- package/browser/dist/{tags → schema}/yaml-1.1/binary.js +0 -0
- package/browser/dist/schema/yaml-1.1/bool.js +26 -0
- package/browser/dist/schema/yaml-1.1/float.js +43 -0
- package/browser/dist/schema/yaml-1.1/int.js +71 -0
- package/browser/dist/{tags → schema}/yaml-1.1/omap.js +0 -0
- package/browser/dist/{tags → schema}/yaml-1.1/pairs.js +9 -6
- package/browser/dist/schema/yaml-1.1/schema.js +37 -0
- package/browser/dist/{tags → schema}/yaml-1.1/set.js +0 -0
- package/browser/dist/{tags → schema}/yaml-1.1/timestamp.js +0 -0
- package/browser/dist/stringify/addComment.js +1 -7
- package/browser/dist/stringify/stringify.js +8 -6
- package/browser/dist/stringify/stringifyCollection.js +108 -0
- package/browser/dist/stringify/stringifyDocument.js +61 -0
- package/browser/dist/stringify/stringifyPair.js +113 -0
- package/browser/dist/stringify/stringifyString.js +53 -52
- package/browser/dist/visit.js +20 -1
- package/dist/compose/compose-collection.d.ts +4 -4
- package/dist/compose/compose-collection.js +12 -9
- package/dist/compose/compose-doc.d.ts +4 -3
- package/dist/compose/compose-doc.js +23 -6
- package/dist/compose/compose-node.d.ts +15 -7
- package/dist/compose/compose-node.js +20 -17
- package/dist/compose/compose-scalar.d.ts +4 -3
- package/dist/compose/compose-scalar.js +19 -22
- package/dist/compose/composer.d.ts +28 -23
- package/dist/compose/composer.js +106 -77
- package/dist/compose/resolve-block-map.d.ts +4 -4
- package/dist/compose/resolve-block-map.js +38 -29
- package/dist/compose/resolve-block-scalar.d.ts +5 -3
- package/dist/compose/resolve-block-scalar.js +14 -17
- package/dist/compose/resolve-block-seq.d.ts +4 -4
- package/dist/compose/resolve-block-seq.js +21 -17
- package/dist/compose/resolve-end.d.ts +3 -2
- package/dist/compose/resolve-end.js +6 -7
- package/dist/compose/resolve-flow-collection.d.ts +4 -5
- package/dist/compose/resolve-flow-collection.js +152 -198
- package/dist/compose/resolve-flow-scalar.d.ts +5 -3
- package/dist/compose/resolve-flow-scalar.js +49 -25
- package/dist/compose/resolve-props.d.ts +17 -10
- package/dist/compose/resolve-props.js +47 -35
- package/dist/compose/util-contains-newline.d.ts +1 -1
- package/dist/compose/util-contains-newline.js +15 -12
- package/dist/compose/util-empty-scalar-position.d.ts +1 -1
- package/dist/doc/Document.d.ts +27 -15
- package/dist/doc/Document.js +48 -97
- package/dist/doc/anchors.d.ts +24 -0
- package/dist/doc/anchors.js +77 -0
- package/dist/doc/createNode.d.ts +8 -10
- package/dist/doc/createNode.js +26 -16
- package/dist/errors.d.ts +11 -8
- package/dist/errors.js +16 -12
- package/dist/index.d.ts +5 -3
- package/dist/index.js +3 -3
- package/dist/nodes/Alias.d.ts +19 -9
- package/dist/nodes/Alias.js +51 -28
- package/dist/nodes/Collection.d.ts +3 -17
- package/dist/nodes/Collection.js +4 -82
- package/dist/nodes/Node.d.ts +6 -4
- package/dist/nodes/Node.js +2 -0
- package/dist/nodes/Pair.d.ts +6 -11
- package/dist/nodes/Pair.js +8 -231
- package/dist/nodes/Scalar.d.ts +6 -3
- package/dist/nodes/YAMLMap.d.ts +3 -3
- package/dist/nodes/YAMLMap.js +8 -4
- package/dist/nodes/YAMLSeq.d.ts +3 -3
- package/dist/nodes/YAMLSeq.js +7 -4
- package/dist/nodes/addPairToJSMap.d.ts +3 -0
- package/dist/nodes/addPairToJSMap.js +105 -0
- package/dist/nodes/toJS.d.ts +4 -5
- package/dist/nodes/toJS.js +12 -10
- package/dist/options.d.ts +20 -26
- package/dist/options.js +0 -2
- package/dist/parse/cst-scalar.d.ts +58 -0
- package/dist/parse/cst-scalar.js +223 -0
- package/dist/parse/cst-stringify.d.ts +8 -0
- package/dist/parse/cst-stringify.js +63 -0
- package/dist/parse/cst-visit.d.ts +39 -0
- package/dist/parse/cst-visit.js +99 -0
- package/dist/parse/{tokens.d.ts → cst.d.ts} +23 -7
- package/{browser/dist/parse/tokens.js → dist/parse/cst.js} +27 -1
- package/dist/parse/lexer.d.ts +4 -13
- package/dist/parse/lexer.js +100 -106
- package/dist/parse/parser.d.ts +30 -24
- package/dist/parse/parser.js +221 -146
- package/dist/public-api.d.ts +7 -7
- package/dist/public-api.js +11 -14
- package/dist/{doc → schema}/Schema.d.ts +5 -3
- package/dist/schema/Schema.js +25 -0
- package/dist/{tags/failsafe → schema/common}/map.d.ts +0 -0
- package/dist/{tags/failsafe → schema/common}/map.js +0 -0
- package/dist/schema/common/null.d.ts +4 -0
- package/dist/schema/common/null.js +15 -0
- package/dist/{tags/failsafe → schema/common}/seq.d.ts +0 -0
- package/dist/{tags/failsafe → schema/common}/seq.js +1 -1
- package/dist/{tags/failsafe → schema/common}/string.d.ts +0 -0
- package/dist/{tags/failsafe → schema/common}/string.js +0 -0
- package/dist/schema/core/bool.d.ts +4 -0
- package/dist/schema/core/bool.js +21 -0
- package/dist/schema/core/float.d.ts +4 -0
- package/dist/schema/core/float.js +44 -0
- package/dist/schema/core/int.d.ts +4 -0
- package/dist/schema/core/int.js +42 -0
- package/dist/schema/core/schema.d.ts +1 -0
- package/dist/schema/core/schema.js +25 -0
- package/dist/schema/json/schema.d.ts +2 -0
- package/dist/{tags/json.js → schema/json/schema.js} +5 -6
- package/dist/schema/tags.d.ts +41 -0
- package/dist/schema/tags.js +82 -0
- package/dist/{tags → schema}/types.d.ts +3 -7
- package/dist/{tags → schema}/yaml-1.1/binary.d.ts +0 -0
- package/dist/{tags → schema}/yaml-1.1/binary.js +0 -0
- package/dist/schema/yaml-1.1/bool.d.ts +7 -0
- package/dist/schema/yaml-1.1/bool.js +29 -0
- package/dist/schema/yaml-1.1/float.d.ts +4 -0
- package/dist/schema/yaml-1.1/float.js +47 -0
- package/dist/schema/yaml-1.1/int.d.ts +5 -0
- package/dist/schema/yaml-1.1/int.js +76 -0
- package/dist/{tags → schema}/yaml-1.1/omap.d.ts +0 -0
- package/dist/{tags → schema}/yaml-1.1/omap.js +0 -0
- package/dist/{tags → schema}/yaml-1.1/pairs.d.ts +3 -2
- package/dist/{tags → schema}/yaml-1.1/pairs.js +9 -6
- package/dist/schema/yaml-1.1/schema.d.ts +1 -0
- package/dist/schema/yaml-1.1/schema.js +39 -0
- package/dist/{tags → schema}/yaml-1.1/set.d.ts +1 -1
- package/dist/{tags → schema}/yaml-1.1/set.js +0 -0
- package/dist/{tags → schema}/yaml-1.1/timestamp.d.ts +0 -0
- package/dist/{tags → schema}/yaml-1.1/timestamp.js +0 -0
- package/dist/stringify/addComment.js +0 -7
- package/dist/stringify/stringify.d.ts +1 -2
- package/dist/stringify/stringify.js +8 -6
- package/dist/stringify/stringifyCollection.d.ts +21 -0
- package/dist/stringify/stringifyCollection.js +110 -0
- package/dist/stringify/stringifyDocument.d.ts +3 -0
- package/dist/stringify/stringifyDocument.js +63 -0
- package/dist/stringify/stringifyPair.d.ts +3 -0
- package/dist/stringify/stringifyPair.js +115 -0
- package/dist/stringify/stringifyString.js +53 -52
- package/dist/test-events.d.ts +1 -2
- package/dist/test-events.js +25 -12
- package/dist/util.d.ts +1 -1
- package/dist/visit.d.ts +10 -1
- package/dist/visit.js +20 -1
- package/package.json +4 -3
- package/browser/dist/doc/Anchors.js +0 -102
- package/browser/dist/doc/Schema.js +0 -27
- package/browser/dist/doc/getSchemaTags.js +0 -30
- package/browser/dist/tags/core.js +0 -109
- package/browser/dist/tags/failsafe/index.js +0 -7
- package/browser/dist/tags/index.js +0 -34
- package/browser/dist/tags/yaml-1.1/index.js +0 -152
- package/dist/doc/Anchors.d.ts +0 -36
- package/dist/doc/Anchors.js +0 -104
- package/dist/doc/Schema.js +0 -29
- package/dist/doc/getSchemaTags.d.ts +0 -3
- package/dist/doc/getSchemaTags.js +0 -32
- package/dist/tags/core.d.ts +0 -14
- package/dist/tags/core.js +0 -119
- package/dist/tags/failsafe/index.d.ts +0 -1
- package/dist/tags/failsafe/index.js +0 -9
- package/dist/tags/index.d.ts +0 -31
- package/dist/tags/index.js +0 -37
- package/dist/tags/json.d.ts +0 -2
- package/dist/tags/yaml-1.1/index.d.ts +0 -2
- package/dist/tags/yaml-1.1/index.js +0 -154
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 yaml@next
|
|
22
|
+
npm install --save-exact yaml@next
|
|
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.
|
|
@@ -67,16 +67,16 @@ const YAML = require('yaml')
|
|
|
67
67
|
- [`new Scalar(value)`](https://eemeli.org/yaml/#scalar-values)
|
|
68
68
|
- [`new YAMLMap()`](https://eemeli.org/yaml/#collections)
|
|
69
69
|
- [`new YAMLSeq()`](https://eemeli.org/yaml/#collections)
|
|
70
|
-
- [`doc.
|
|
70
|
+
- [`doc.createAlias(node, name?): Alias`](https://eemeli.org/yaml/#working-with-anchors)
|
|
71
71
|
- [`doc.createNode(value, options?): Node`](https://eemeli.org/yaml/#creating-nodes)
|
|
72
72
|
- [`doc.createPair(key, value): Pair`](https://eemeli.org/yaml/#creating-nodes)
|
|
73
73
|
- [`visit(node, visitor)`](https://eemeli.org/yaml/#modifying-nodes)
|
|
74
74
|
|
|
75
75
|
### Parsing YAML
|
|
76
76
|
|
|
77
|
-
- [`new Lexer(
|
|
78
|
-
- [`new Parser(
|
|
79
|
-
- [`new Composer(
|
|
77
|
+
- [`new Lexer().lex(src)`](https://eemeli.org/yaml/#lexer)
|
|
78
|
+
- [`new Parser(onNewLine?).parse(src)`](https://eemeli.org/yaml/#parser)
|
|
79
|
+
- [`new Composer(options?).compose(tokens)`](https://eemeli.org/yaml/#composer)
|
|
80
80
|
|
|
81
81
|
## YAML.parse
|
|
82
82
|
|
|
@@ -4,22 +4,25 @@ import { resolveBlockMap } from './resolve-block-map.js';
|
|
|
4
4
|
import { resolveBlockSeq } from './resolve-block-seq.js';
|
|
5
5
|
import { resolveFlowCollection } from './resolve-flow-collection.js';
|
|
6
6
|
|
|
7
|
-
function composeCollection(CN,
|
|
7
|
+
function composeCollection(CN, ctx, token, tagToken, onError) {
|
|
8
8
|
let coll;
|
|
9
9
|
switch (token.type) {
|
|
10
10
|
case 'block-map': {
|
|
11
|
-
coll = resolveBlockMap(CN,
|
|
11
|
+
coll = resolveBlockMap(CN, ctx, token, onError);
|
|
12
12
|
break;
|
|
13
13
|
}
|
|
14
14
|
case 'block-seq': {
|
|
15
|
-
coll = resolveBlockSeq(CN,
|
|
15
|
+
coll = resolveBlockSeq(CN, ctx, token, onError);
|
|
16
16
|
break;
|
|
17
17
|
}
|
|
18
18
|
case 'flow-collection': {
|
|
19
|
-
coll = resolveFlowCollection(CN,
|
|
19
|
+
coll = resolveFlowCollection(CN, ctx, token, onError);
|
|
20
20
|
break;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
+
if (!tagToken)
|
|
24
|
+
return coll;
|
|
25
|
+
const tagName = ctx.directives.tagName(tagToken.source, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg));
|
|
23
26
|
if (!tagName)
|
|
24
27
|
return coll;
|
|
25
28
|
// Cast needed due to: https://github.com/Microsoft/TypeScript/issues/3841
|
|
@@ -29,20 +32,20 @@ function composeCollection(CN, doc, token, anchor, tagName, onError) {
|
|
|
29
32
|
return coll;
|
|
30
33
|
}
|
|
31
34
|
const expType = isMap(coll) ? 'map' : 'seq';
|
|
32
|
-
let tag =
|
|
35
|
+
let tag = ctx.schema.tags.find(t => t.collection === expType && t.tag === tagName);
|
|
33
36
|
if (!tag) {
|
|
34
|
-
const kt =
|
|
37
|
+
const kt = ctx.schema.knownTags[tagName];
|
|
35
38
|
if (kt && kt.collection === expType) {
|
|
36
|
-
|
|
39
|
+
ctx.schema.tags.push(Object.assign({}, kt, { default: false }));
|
|
37
40
|
tag = kt;
|
|
38
41
|
}
|
|
39
42
|
else {
|
|
40
|
-
onError(
|
|
43
|
+
onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, true);
|
|
41
44
|
coll.tag = tagName;
|
|
42
45
|
return coll;
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
|
-
const res = tag.resolve(coll, msg => onError(
|
|
48
|
+
const res = tag.resolve(coll, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg), ctx.options);
|
|
46
49
|
const node = isNode(res)
|
|
47
50
|
? res
|
|
48
51
|
: new Scalar(res);
|
|
@@ -6,16 +6,33 @@ import { resolveProps } from './resolve-props.js';
|
|
|
6
6
|
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
|
-
const
|
|
10
|
-
|
|
9
|
+
const ctx = {
|
|
10
|
+
directives: doc.directives,
|
|
11
|
+
options: doc.options,
|
|
12
|
+
schema: doc.schema
|
|
13
|
+
};
|
|
14
|
+
const props = resolveProps(start, {
|
|
15
|
+
ctx,
|
|
16
|
+
indicator: 'doc-start',
|
|
17
|
+
offset,
|
|
18
|
+
onError,
|
|
19
|
+
startOnNewline: true
|
|
20
|
+
});
|
|
21
|
+
if (props.found) {
|
|
11
22
|
doc.directives.marker = true;
|
|
23
|
+
if (value &&
|
|
24
|
+
(value.type === 'block-map' || value.type === 'block-seq') &&
|
|
25
|
+
!props.hasNewline)
|
|
26
|
+
onError(props.end, 'MISSING_CHAR', 'Block collection cannot start on same line with directives-end marker');
|
|
27
|
+
}
|
|
12
28
|
doc.contents = value
|
|
13
|
-
? composeNode(
|
|
14
|
-
: composeEmptyNode(
|
|
15
|
-
const
|
|
29
|
+
? composeNode(ctx, value, props, onError)
|
|
30
|
+
: composeEmptyNode(ctx, props.end, start, null, props, onError);
|
|
31
|
+
const contentEnd = doc.contents.range[2];
|
|
32
|
+
const re = resolveEnd(end, contentEnd, false, onError);
|
|
16
33
|
if (re.comment)
|
|
17
34
|
doc.comment = re.comment;
|
|
18
|
-
doc.range = [offset, re.offset];
|
|
35
|
+
doc.range = [offset, contentEnd, re.offset];
|
|
19
36
|
return doc;
|
|
20
37
|
}
|
|
21
38
|
|
|
@@ -5,25 +5,29 @@ import { resolveEnd } from './resolve-end.js';
|
|
|
5
5
|
import { emptyScalarPosition } from './util-empty-scalar-position.js';
|
|
6
6
|
|
|
7
7
|
const CN = { composeNode, composeEmptyNode };
|
|
8
|
-
function composeNode(
|
|
9
|
-
const { spaceBefore, comment, anchor,
|
|
8
|
+
function composeNode(ctx, token, props, onError) {
|
|
9
|
+
const { spaceBefore, comment, anchor, tag } = props;
|
|
10
10
|
let node;
|
|
11
11
|
switch (token.type) {
|
|
12
12
|
case 'alias':
|
|
13
|
-
node = composeAlias(
|
|
14
|
-
if (anchor ||
|
|
15
|
-
onError(token
|
|
13
|
+
node = composeAlias(ctx, token, onError);
|
|
14
|
+
if (anchor || tag)
|
|
15
|
+
onError(token, 'ALIAS_PROPS', 'An alias node must not specify any properties');
|
|
16
16
|
break;
|
|
17
17
|
case 'scalar':
|
|
18
18
|
case 'single-quoted-scalar':
|
|
19
19
|
case 'double-quoted-scalar':
|
|
20
20
|
case 'block-scalar':
|
|
21
|
-
node = composeScalar(
|
|
21
|
+
node = composeScalar(ctx, token, tag, onError);
|
|
22
|
+
if (anchor)
|
|
23
|
+
node.anchor = anchor.source.substring(1);
|
|
22
24
|
break;
|
|
23
25
|
case 'block-map':
|
|
24
26
|
case 'block-seq':
|
|
25
27
|
case 'flow-collection':
|
|
26
|
-
node = composeCollection(CN,
|
|
28
|
+
node = composeCollection(CN, ctx, token, tag, onError);
|
|
29
|
+
if (anchor)
|
|
30
|
+
node.anchor = anchor.source.substring(1);
|
|
27
31
|
break;
|
|
28
32
|
default:
|
|
29
33
|
console.log(token);
|
|
@@ -39,28 +43,27 @@ function composeNode(doc, token, props, onError) {
|
|
|
39
43
|
}
|
|
40
44
|
return node;
|
|
41
45
|
}
|
|
42
|
-
function composeEmptyNode(
|
|
46
|
+
function composeEmptyNode(ctx, offset, before, pos, { spaceBefore, comment, anchor, tag }, onError) {
|
|
43
47
|
const token = {
|
|
44
48
|
type: 'scalar',
|
|
45
49
|
offset: emptyScalarPosition(offset, before, pos),
|
|
46
50
|
indent: -1,
|
|
47
51
|
source: ''
|
|
48
52
|
};
|
|
49
|
-
const node = composeScalar(
|
|
53
|
+
const node = composeScalar(ctx, token, tag, onError);
|
|
54
|
+
if (anchor)
|
|
55
|
+
node.anchor = anchor.source.substring(1);
|
|
50
56
|
if (spaceBefore)
|
|
51
57
|
node.spaceBefore = true;
|
|
52
58
|
if (comment)
|
|
53
59
|
node.comment = comment;
|
|
54
60
|
return node;
|
|
55
61
|
}
|
|
56
|
-
function composeAlias(
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const alias = new Alias(src);
|
|
62
|
-
const re = resolveEnd(end, offset + source.length, doc.options.strict, onError);
|
|
63
|
-
alias.range = [offset, re.offset];
|
|
62
|
+
function composeAlias({ options }, { offset, source, end }, onError) {
|
|
63
|
+
const alias = new Alias(source.substring(1));
|
|
64
|
+
const valueEnd = offset + source.length;
|
|
65
|
+
const re = resolveEnd(end, valueEnd, options.strict, onError);
|
|
66
|
+
alias.range = [offset, valueEnd, re.offset];
|
|
64
67
|
if (re.comment)
|
|
65
68
|
alias.comment = re.comment;
|
|
66
69
|
return alias;
|
|
@@ -1,46 +1,43 @@
|
|
|
1
|
-
import { isScalar } from '../nodes/Node.js';
|
|
1
|
+
import { isScalar, SCALAR } 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';
|
|
5
5
|
|
|
6
|
-
function composeScalar(
|
|
7
|
-
const {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
function composeScalar(ctx, token, tagToken, onError) {
|
|
7
|
+
const { value, type, comment, range } = token.type === 'block-scalar'
|
|
8
|
+
? resolveBlockScalar(token, ctx.options.strict, onError)
|
|
9
|
+
: resolveFlowScalar(token, ctx.options.strict, onError);
|
|
10
|
+
const tagName = tagToken
|
|
11
|
+
? ctx.directives.tagName(tagToken.source, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg))
|
|
12
|
+
: null;
|
|
13
|
+
const tag = tagToken && tagName
|
|
14
|
+
? findScalarTagByName(ctx.schema, value, tagName, tagToken, onError)
|
|
15
|
+
: findScalarTagByTest(ctx.schema, value, token.type === 'scalar');
|
|
14
16
|
let scalar;
|
|
15
17
|
try {
|
|
16
|
-
const res = tag
|
|
17
|
-
? tag.resolve(value, msg => onError(offset, msg), doc.options)
|
|
18
|
-
: value;
|
|
18
|
+
const res = tag.resolve(value, msg => onError(tagToken || token, 'TAG_RESOLVE_FAILED', msg), ctx.options);
|
|
19
19
|
scalar = isScalar(res) ? res : new Scalar(res);
|
|
20
20
|
}
|
|
21
21
|
catch (error) {
|
|
22
|
-
onError(
|
|
22
|
+
onError(tagToken || token, 'TAG_RESOLVE_FAILED', error.message);
|
|
23
23
|
scalar = new Scalar(value);
|
|
24
24
|
}
|
|
25
|
-
scalar.range =
|
|
25
|
+
scalar.range = range;
|
|
26
26
|
scalar.source = value;
|
|
27
27
|
if (type)
|
|
28
28
|
scalar.type = type;
|
|
29
29
|
if (tagName)
|
|
30
30
|
scalar.tag = tagName;
|
|
31
|
-
if (tag
|
|
31
|
+
if (tag.format)
|
|
32
32
|
scalar.format = tag.format;
|
|
33
33
|
if (comment)
|
|
34
34
|
scalar.comment = comment;
|
|
35
|
-
if (anchor)
|
|
36
|
-
doc.anchors.setAnchor(scalar, anchor);
|
|
37
35
|
return scalar;
|
|
38
36
|
}
|
|
39
|
-
|
|
40
|
-
function findScalarTagByName(schema, value, tagName, onError) {
|
|
37
|
+
function findScalarTagByName(schema, value, tagName, tagToken, onError) {
|
|
41
38
|
var _a;
|
|
42
39
|
if (tagName === '!')
|
|
43
|
-
return
|
|
40
|
+
return schema[SCALAR]; // non-specific tag
|
|
44
41
|
const matchWithTest = [];
|
|
45
42
|
for (const tag of schema.tags) {
|
|
46
43
|
if (!tag.collection && tag.tag === tagName) {
|
|
@@ -60,8 +57,8 @@ function findScalarTagByName(schema, value, tagName, onError) {
|
|
|
60
57
|
schema.tags.push(Object.assign({}, kt, { default: false, test: undefined }));
|
|
61
58
|
return kt;
|
|
62
59
|
}
|
|
63
|
-
onError(
|
|
64
|
-
return
|
|
60
|
+
onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, tagName !== 'tag:yaml.org,2002:str');
|
|
61
|
+
return schema[SCALAR];
|
|
65
62
|
}
|
|
66
63
|
function findScalarTagByTest(schema, value, apply) {
|
|
67
64
|
var _a;
|
|
@@ -71,7 +68,7 @@ function findScalarTagByTest(schema, value, apply) {
|
|
|
71
68
|
return tag;
|
|
72
69
|
}
|
|
73
70
|
}
|
|
74
|
-
return
|
|
71
|
+
return schema[SCALAR];
|
|
75
72
|
}
|
|
76
73
|
|
|
77
74
|
export { composeScalar };
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { Directives } from '../doc/directives.js';
|
|
2
2
|
import { Document } from '../doc/Document.js';
|
|
3
3
|
import { YAMLWarning, YAMLParseError } from '../errors.js';
|
|
4
|
-
import { isCollection } from '../nodes/Node.js';
|
|
4
|
+
import { isCollection, isPair } from '../nodes/Node.js';
|
|
5
5
|
import { defaultOptions } from '../options.js';
|
|
6
6
|
import { composeDoc } from './compose-doc.js';
|
|
7
7
|
import { resolveEnd } from './resolve-end.js';
|
|
8
8
|
|
|
9
|
+
function getErrorPos(src) {
|
|
10
|
+
if (typeof src === 'number')
|
|
11
|
+
return [src, src + 1];
|
|
12
|
+
if (Array.isArray(src))
|
|
13
|
+
return src.length === 2 ? src : [src[0], src[1]];
|
|
14
|
+
const { offset, source } = src;
|
|
15
|
+
return [offset, offset + (typeof source === 'string' ? source.length : 1)];
|
|
16
|
+
}
|
|
9
17
|
function parsePrelude(prelude) {
|
|
10
18
|
let comment = '';
|
|
11
19
|
let atComment = false;
|
|
@@ -38,88 +46,30 @@ function parsePrelude(prelude) {
|
|
|
38
46
|
* Compose a stream of CST nodes into a stream of YAML Documents.
|
|
39
47
|
*
|
|
40
48
|
* ```ts
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* const
|
|
44
|
-
* const
|
|
45
|
-
*
|
|
46
|
-
* composer.end()
|
|
49
|
+
* import { Composer, Parser } from 'yaml'
|
|
50
|
+
*
|
|
51
|
+
* const src: string = ...
|
|
52
|
+
* const tokens = new Parser().parse(src)
|
|
53
|
+
* const docs = new Composer().compose(tokens)
|
|
47
54
|
* ```
|
|
48
55
|
*/
|
|
49
56
|
class Composer {
|
|
50
|
-
constructor(
|
|
57
|
+
constructor(options = {}) {
|
|
51
58
|
this.doc = null;
|
|
52
59
|
this.atDirectives = false;
|
|
53
60
|
this.prelude = [];
|
|
54
61
|
this.errors = [];
|
|
55
62
|
this.warnings = [];
|
|
56
|
-
this.onError = (
|
|
63
|
+
this.onError = (source, code, message, warning) => {
|
|
64
|
+
const pos = getErrorPos(source);
|
|
57
65
|
if (warning)
|
|
58
|
-
this.warnings.push(new YAMLWarning(
|
|
66
|
+
this.warnings.push(new YAMLWarning(pos, code, message));
|
|
59
67
|
else
|
|
60
|
-
this.errors.push(new YAMLParseError(
|
|
61
|
-
};
|
|
62
|
-
/**
|
|
63
|
-
* Advance the composed by one CST token. Bound to the Composer
|
|
64
|
-
* instance, so may be used directly as a callback function.
|
|
65
|
-
*/
|
|
66
|
-
this.next = (token) => {
|
|
67
|
-
switch (token.type) {
|
|
68
|
-
case 'directive':
|
|
69
|
-
this.directives.add(token.source, this.onError);
|
|
70
|
-
this.prelude.push(token.source);
|
|
71
|
-
this.atDirectives = true;
|
|
72
|
-
break;
|
|
73
|
-
case 'document': {
|
|
74
|
-
const doc = composeDoc(this.options, this.directives, token, this.onError);
|
|
75
|
-
this.decorate(doc, false);
|
|
76
|
-
if (this.doc)
|
|
77
|
-
this.onDocument(this.doc);
|
|
78
|
-
this.doc = doc;
|
|
79
|
-
this.atDirectives = false;
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
case 'byte-order-mark':
|
|
83
|
-
case 'space':
|
|
84
|
-
break;
|
|
85
|
-
case 'comment':
|
|
86
|
-
case 'newline':
|
|
87
|
-
this.prelude.push(token.source);
|
|
88
|
-
break;
|
|
89
|
-
case 'error': {
|
|
90
|
-
const msg = token.source
|
|
91
|
-
? `${token.message}: ${JSON.stringify(token.source)}`
|
|
92
|
-
: token.message;
|
|
93
|
-
const error = new YAMLParseError(-1, msg);
|
|
94
|
-
if (this.atDirectives || !this.doc)
|
|
95
|
-
this.errors.push(error);
|
|
96
|
-
else
|
|
97
|
-
this.doc.errors.push(error);
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
case 'doc-end': {
|
|
101
|
-
if (!this.doc) {
|
|
102
|
-
const msg = 'Unexpected doc-end without preceding document';
|
|
103
|
-
this.errors.push(new YAMLParseError(token.offset, msg));
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
const end = resolveEnd(token.end, token.offset + token.source.length, this.doc.options.strict, this.onError);
|
|
107
|
-
this.decorate(this.doc, true);
|
|
108
|
-
if (end.comment) {
|
|
109
|
-
const dc = this.doc.comment;
|
|
110
|
-
this.doc.comment = dc ? `${dc}\n${end.comment}` : end.comment;
|
|
111
|
-
}
|
|
112
|
-
this.doc.range[1] = end.offset;
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
default:
|
|
116
|
-
this.errors.push(new YAMLParseError(-1, `Unsupported token ${token.type}`));
|
|
117
|
-
}
|
|
68
|
+
this.errors.push(new YAMLParseError(pos, code, message));
|
|
118
69
|
};
|
|
119
70
|
this.directives = new Directives({
|
|
120
|
-
version:
|
|
71
|
+
version: options.version || defaultOptions.version
|
|
121
72
|
});
|
|
122
|
-
this.onDocument = onDocument;
|
|
123
73
|
this.options = options;
|
|
124
74
|
}
|
|
125
75
|
decorate(doc, afterDoc) {
|
|
@@ -134,7 +84,9 @@ class Composer {
|
|
|
134
84
|
doc.commentBefore = comment;
|
|
135
85
|
}
|
|
136
86
|
else if (isCollection(dc) && !dc.flow && dc.items.length > 0) {
|
|
137
|
-
|
|
87
|
+
let it = dc.items[0];
|
|
88
|
+
if (isPair(it))
|
|
89
|
+
it = it.key;
|
|
138
90
|
const cb = it.commentBefore;
|
|
139
91
|
it.commentBefore = cb ? `${comment}\n${cb}` : comment;
|
|
140
92
|
}
|
|
@@ -168,20 +120,97 @@ class Composer {
|
|
|
168
120
|
warnings: this.warnings
|
|
169
121
|
};
|
|
170
122
|
}
|
|
171
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Compose tokens into documents.
|
|
125
|
+
*
|
|
126
|
+
* @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document.
|
|
127
|
+
* @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly.
|
|
128
|
+
*/
|
|
129
|
+
*compose(tokens, forceDoc = false, endOffset = -1) {
|
|
130
|
+
for (const token of tokens)
|
|
131
|
+
yield* this.next(token);
|
|
132
|
+
yield* this.end(forceDoc, endOffset);
|
|
133
|
+
}
|
|
134
|
+
/** Advance the composer by one CST token. */
|
|
135
|
+
*next(token) {
|
|
136
|
+
switch (token.type) {
|
|
137
|
+
case 'directive':
|
|
138
|
+
this.directives.add(token.source, (offset, message, warning) => {
|
|
139
|
+
const pos = getErrorPos(token);
|
|
140
|
+
pos[0] += offset;
|
|
141
|
+
this.onError(pos, 'BAD_DIRECTIVE', message, warning);
|
|
142
|
+
});
|
|
143
|
+
this.prelude.push(token.source);
|
|
144
|
+
this.atDirectives = true;
|
|
145
|
+
break;
|
|
146
|
+
case 'document': {
|
|
147
|
+
const doc = composeDoc(this.options, this.directives, token, this.onError);
|
|
148
|
+
if (this.atDirectives && !doc.directives.marker)
|
|
149
|
+
this.onError(token, 'MISSING_CHAR', 'Missing directives-end indicator line');
|
|
150
|
+
this.decorate(doc, false);
|
|
151
|
+
if (this.doc)
|
|
152
|
+
yield this.doc;
|
|
153
|
+
this.doc = doc;
|
|
154
|
+
this.atDirectives = false;
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
case 'byte-order-mark':
|
|
158
|
+
case 'space':
|
|
159
|
+
break;
|
|
160
|
+
case 'comment':
|
|
161
|
+
case 'newline':
|
|
162
|
+
this.prelude.push(token.source);
|
|
163
|
+
break;
|
|
164
|
+
case 'error': {
|
|
165
|
+
const msg = token.source
|
|
166
|
+
? `${token.message}: ${JSON.stringify(token.source)}`
|
|
167
|
+
: token.message;
|
|
168
|
+
const error = new YAMLParseError(getErrorPos(token), 'UNEXPECTED_TOKEN', msg);
|
|
169
|
+
if (this.atDirectives || !this.doc)
|
|
170
|
+
this.errors.push(error);
|
|
171
|
+
else
|
|
172
|
+
this.doc.errors.push(error);
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
case 'doc-end': {
|
|
176
|
+
if (!this.doc) {
|
|
177
|
+
const msg = 'Unexpected doc-end without preceding document';
|
|
178
|
+
this.errors.push(new YAMLParseError(getErrorPos(token), 'UNEXPECTED_TOKEN', msg));
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
const end = resolveEnd(token.end, token.offset + token.source.length, this.doc.options.strict, this.onError);
|
|
182
|
+
this.decorate(this.doc, true);
|
|
183
|
+
if (end.comment) {
|
|
184
|
+
const dc = this.doc.comment;
|
|
185
|
+
this.doc.comment = dc ? `${dc}\n${end.comment}` : end.comment;
|
|
186
|
+
}
|
|
187
|
+
this.doc.range[2] = end.offset;
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
default:
|
|
191
|
+
this.errors.push(new YAMLParseError(getErrorPos(token), 'UNEXPECTED_TOKEN', `Unsupported token ${token.type}`));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Call at end of input to yield any remaining document.
|
|
196
|
+
*
|
|
197
|
+
* @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document.
|
|
198
|
+
* @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly.
|
|
199
|
+
*/
|
|
200
|
+
*end(forceDoc = false, endOffset = -1) {
|
|
172
201
|
if (this.doc) {
|
|
173
202
|
this.decorate(this.doc, true);
|
|
174
|
-
this.
|
|
203
|
+
yield this.doc;
|
|
175
204
|
this.doc = null;
|
|
176
205
|
}
|
|
177
206
|
else if (forceDoc) {
|
|
178
207
|
const opts = Object.assign({ directives: this.directives }, this.options);
|
|
179
208
|
const doc = new Document(undefined, opts);
|
|
180
209
|
if (this.atDirectives)
|
|
181
|
-
this.onError(
|
|
182
|
-
doc.range = [0,
|
|
210
|
+
this.onError(endOffset, 'MISSING_CHAR', 'Missing directives-end indicator line');
|
|
211
|
+
doc.range = [0, endOffset, endOffset];
|
|
183
212
|
this.decorate(doc, false);
|
|
184
|
-
|
|
213
|
+
yield doc;
|
|
185
214
|
}
|
|
186
215
|
}
|
|
187
216
|
}
|
|
@@ -4,24 +4,28 @@ import { resolveProps } from './resolve-props.js';
|
|
|
4
4
|
import { containsNewline } from './util-contains-newline.js';
|
|
5
5
|
|
|
6
6
|
const startColMsg = 'All mapping items must start at the same column';
|
|
7
|
-
function resolveBlockMap({ composeNode, composeEmptyNode },
|
|
7
|
+
function resolveBlockMap({ composeNode, composeEmptyNode }, ctx, bm, onError) {
|
|
8
8
|
var _a;
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
doc.anchors.setAnchor(map, anchor);
|
|
13
|
-
for (const { start, key, sep, value } of items) {
|
|
9
|
+
const map = new YAMLMap(ctx.schema);
|
|
10
|
+
let offset = bm.offset;
|
|
11
|
+
for (const { start, key, sep, value } of bm.items) {
|
|
14
12
|
// key properties
|
|
15
|
-
const keyProps = resolveProps(
|
|
13
|
+
const keyProps = resolveProps(start, {
|
|
14
|
+
ctx,
|
|
15
|
+
indicator: 'explicit-key-ind',
|
|
16
|
+
offset,
|
|
17
|
+
onError,
|
|
18
|
+
startOnNewline: true
|
|
19
|
+
});
|
|
16
20
|
const implicitKey = !keyProps.found;
|
|
17
21
|
if (implicitKey) {
|
|
18
22
|
if (key) {
|
|
19
23
|
if (key.type === 'block-seq')
|
|
20
|
-
onError(offset, 'A block sequence may not be used as an implicit map key');
|
|
21
|
-
else if ('indent' in key && key.indent !== indent)
|
|
22
|
-
onError(offset, startColMsg);
|
|
24
|
+
onError(offset, 'BLOCK_AS_IMPLICIT_KEY', 'A block sequence may not be used as an implicit map key');
|
|
25
|
+
else if ('indent' in key && key.indent !== bm.indent)
|
|
26
|
+
onError(offset, 'BAD_INDENT', startColMsg);
|
|
23
27
|
}
|
|
24
|
-
if (!keyProps.anchor && !keyProps.
|
|
28
|
+
if (!keyProps.anchor && !keyProps.tag && !sep) {
|
|
25
29
|
// TODO: assert being at last item?
|
|
26
30
|
if (keyProps.comment) {
|
|
27
31
|
if (map.comment)
|
|
@@ -32,39 +36,44 @@ function resolveBlockMap({ composeNode, composeEmptyNode }, doc, { indent, items
|
|
|
32
36
|
continue;
|
|
33
37
|
}
|
|
34
38
|
}
|
|
35
|
-
else if (((_a = keyProps.found) === null || _a === void 0 ? void 0 : _a.indent) !== indent)
|
|
36
|
-
onError(offset, startColMsg);
|
|
37
|
-
offset += keyProps.length;
|
|
39
|
+
else if (((_a = keyProps.found) === null || _a === void 0 ? void 0 : _a.indent) !== bm.indent)
|
|
40
|
+
onError(offset, 'BAD_INDENT', startColMsg);
|
|
38
41
|
if (implicitKey && containsNewline(key))
|
|
39
|
-
onError(
|
|
42
|
+
onError(key, // checked by containsNewline()
|
|
43
|
+
'MULTILINE_IMPLICIT_KEY', 'Implicit keys need to be on a single line');
|
|
40
44
|
// key value
|
|
41
|
-
const keyStart =
|
|
45
|
+
const keyStart = keyProps.end;
|
|
42
46
|
const keyNode = key
|
|
43
|
-
? composeNode(
|
|
44
|
-
: composeEmptyNode(
|
|
45
|
-
offset = keyNode.range[1];
|
|
47
|
+
? composeNode(ctx, key, keyProps, onError)
|
|
48
|
+
: composeEmptyNode(ctx, keyStart, start, null, keyProps, onError);
|
|
46
49
|
// value properties
|
|
47
|
-
const valueProps = resolveProps(
|
|
48
|
-
|
|
50
|
+
const valueProps = resolveProps(sep || [], {
|
|
51
|
+
ctx,
|
|
52
|
+
indicator: 'map-value-ind',
|
|
53
|
+
offset: keyNode.range[2],
|
|
54
|
+
onError,
|
|
55
|
+
startOnNewline: !key || key.type === 'block-scalar'
|
|
56
|
+
});
|
|
57
|
+
offset = valueProps.end;
|
|
49
58
|
if (valueProps.found) {
|
|
50
59
|
if (implicitKey) {
|
|
51
60
|
if ((value === null || value === void 0 ? void 0 : value.type) === 'block-map' && !valueProps.hasNewline)
|
|
52
|
-
onError(offset, 'Nested mappings are not allowed in compact mappings');
|
|
53
|
-
if (
|
|
61
|
+
onError(offset, 'BLOCK_AS_IMPLICIT_KEY', 'Nested mappings are not allowed in compact mappings');
|
|
62
|
+
if (ctx.options.strict &&
|
|
54
63
|
keyProps.start < valueProps.found.offset - 1024)
|
|
55
|
-
onError(
|
|
64
|
+
onError(keyNode.range, 'KEY_OVER_1024_CHARS', 'The : indicator must be at most 1024 chars after the start of an implicit block mapping key');
|
|
56
65
|
}
|
|
57
66
|
// value value
|
|
58
67
|
const valueNode = value
|
|
59
|
-
? composeNode(
|
|
60
|
-
: composeEmptyNode(
|
|
61
|
-
offset = valueNode.range[
|
|
68
|
+
? composeNode(ctx, value, valueProps, onError)
|
|
69
|
+
: composeEmptyNode(ctx, offset, sep, null, valueProps, onError);
|
|
70
|
+
offset = valueNode.range[2];
|
|
62
71
|
map.items.push(new Pair(keyNode, valueNode));
|
|
63
72
|
}
|
|
64
73
|
else {
|
|
65
74
|
// key with no value
|
|
66
75
|
if (implicitKey)
|
|
67
|
-
onError(
|
|
76
|
+
onError(keyNode.range, 'MISSING_CHAR', 'Implicit map keys need to be followed by map values');
|
|
68
77
|
if (valueProps.comment) {
|
|
69
78
|
if (keyNode.comment)
|
|
70
79
|
keyNode.comment += '\n' + valueProps.comment;
|
|
@@ -74,7 +83,7 @@ function resolveBlockMap({ composeNode, composeEmptyNode }, doc, { indent, items
|
|
|
74
83
|
map.items.push(new Pair(keyNode));
|
|
75
84
|
}
|
|
76
85
|
}
|
|
77
|
-
map.range = [
|
|
86
|
+
map.range = [bm.offset, offset, offset];
|
|
78
87
|
return map;
|
|
79
88
|
}
|
|
80
89
|
|