UNPKG

3.96 kBJavaScriptView Raw
1'use strict';
2
3var Alias = require('../nodes/Alias.js');
4var identity = require('../nodes/identity.js');
5var composeCollection = require('./compose-collection.js');
6var composeScalar = require('./compose-scalar.js');
7var resolveEnd = require('./resolve-end.js');
8var utilEmptyScalarPosition = require('./util-empty-scalar-position.js');
9
10const CN = { composeNode, composeEmptyNode };
11function composeNode(ctx, token, props, onError) {
12 const atKey = ctx.atKey;
13 const { spaceBefore, comment, anchor, tag } = props;
14 let node;
15 let isSrcToken = true;
16 switch (token.type) {
17 case 'alias':
18 node = composeAlias(ctx, token, onError);
19 if (anchor || tag)
20 onError(token, 'ALIAS_PROPS', 'An alias node must not specify any properties');
21 break;
22 case 'scalar':
23 case 'single-quoted-scalar':
24 case 'double-quoted-scalar':
25 case 'block-scalar':
26 node = composeScalar.composeScalar(ctx, token, tag, onError);
27 if (anchor)
28 node.anchor = anchor.source.substring(1);
29 break;
30 case 'block-map':
31 case 'block-seq':
32 case 'flow-collection':
33 node = composeCollection.composeCollection(CN, ctx, token, props, onError);
34 if (anchor)
35 node.anchor = anchor.source.substring(1);
36 break;
37 default: {
38 const message = token.type === 'error'
39 ? token.message
40 : `Unsupported token (type: ${token.type})`;
41 onError(token, 'UNEXPECTED_TOKEN', message);
42 node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError);
43 isSrcToken = false;
44 }
45 }
46 if (anchor && node.anchor === '')
47 onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');
48 if (atKey &&
49 ctx.options.stringKeys &&
50 (!identity.isScalar(node) ||
51 typeof node.value !== 'string' ||
52 (node.tag && node.tag !== 'tag:yaml.org,2002:str'))) {
53 const msg = 'With stringKeys, all keys must be strings';
54 onError(tag ?? token, 'NON_STRING_KEY', msg);
55 }
56 if (spaceBefore)
57 node.spaceBefore = true;
58 if (comment) {
59 if (token.type === 'scalar' && token.source === '')
60 node.comment = comment;
61 else
62 node.commentBefore = comment;
63 }
64 // @ts-expect-error Type checking misses meaning of isSrcToken
65 if (ctx.options.keepSourceTokens && isSrcToken)
66 node.srcToken = token;
67 return node;
68}
69function composeEmptyNode(ctx, offset, before, pos, { spaceBefore, comment, anchor, tag, end }, onError) {
70 const token = {
71 type: 'scalar',
72 offset: utilEmptyScalarPosition.emptyScalarPosition(offset, before, pos),
73 indent: -1,
74 source: ''
75 };
76 const node = composeScalar.composeScalar(ctx, token, tag, onError);
77 if (anchor) {
78 node.anchor = anchor.source.substring(1);
79 if (node.anchor === '')
80 onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');
81 }
82 if (spaceBefore)
83 node.spaceBefore = true;
84 if (comment) {
85 node.comment = comment;
86 node.range[2] = end;
87 }
88 return node;
89}
90function composeAlias({ options }, { offset, source, end }, onError) {
91 const alias = new Alias.Alias(source.substring(1));
92 if (alias.source === '')
93 onError(offset, 'BAD_ALIAS', 'Alias cannot be an empty string');
94 if (alias.source.endsWith(':'))
95 onError(offset + source.length - 1, 'BAD_ALIAS', 'Alias ending in : is ambiguous', true);
96 const valueEnd = offset + source.length;
97 const re = resolveEnd.resolveEnd(end, valueEnd, options.strict, onError);
98 alias.range = [offset, valueEnd, re.offset];
99 if (re.comment)
100 alias.comment = re.comment;
101 return alias;
102}
103
104exports.composeEmptyNode = composeEmptyNode;
105exports.composeNode = composeNode;