yaml 2.8.2 → 2.8.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/compose-node.js +11 -4
- package/browser/dist/compose/resolve-flow-scalar.js +5 -3
- package/browser/dist/nodes/Alias.js +2 -0
- package/browser/dist/schema/yaml-1.1/merge.js +11 -8
- package/browser/dist/stringify/stringify.js +1 -0
- package/browser/dist/stringify/stringifyCollection.js +13 -3
- package/browser/dist/stringify/stringifyNumber.js +2 -1
- package/dist/compose/compose-node.js +11 -4
- package/dist/compose/resolve-flow-scalar.js +5 -3
- package/dist/errors.d.ts +1 -1
- package/dist/nodes/Alias.js +2 -0
- package/dist/nodes/Scalar.d.ts +5 -1
- package/dist/options.d.ts +6 -0
- package/dist/schema/yaml-1.1/merge.js +10 -7
- package/dist/stringify/stringify.js +1 -0
- package/dist/stringify/stringifyCollection.js +13 -3
- package/dist/stringify/stringifyNumber.js +2 -1
- package/package.json +1 -1
|
@@ -28,19 +28,26 @@ function composeNode(ctx, token, props, onError) {
|
|
|
28
28
|
case 'block-map':
|
|
29
29
|
case 'block-seq':
|
|
30
30
|
case 'flow-collection':
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
try {
|
|
32
|
+
node = composeCollection(CN, ctx, token, props, onError);
|
|
33
|
+
if (anchor)
|
|
34
|
+
node.anchor = anchor.source.substring(1);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
// Almost certainly here due to a stack overflow
|
|
38
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
39
|
+
onError(token, 'RESOURCE_EXHAUSTION', message);
|
|
40
|
+
}
|
|
34
41
|
break;
|
|
35
42
|
default: {
|
|
36
43
|
const message = token.type === 'error'
|
|
37
44
|
? token.message
|
|
38
45
|
: `Unsupported token (type: ${token.type})`;
|
|
39
46
|
onError(token, 'UNEXPECTED_TOKEN', message);
|
|
40
|
-
node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError);
|
|
41
47
|
isSrcToken = false;
|
|
42
48
|
}
|
|
43
49
|
}
|
|
50
|
+
node ?? (node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError));
|
|
44
51
|
if (anchor && node.anchor === '')
|
|
45
52
|
onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');
|
|
46
53
|
if (atKey &&
|
|
@@ -142,7 +142,7 @@ function doubleQuotedValue(source, onError) {
|
|
|
142
142
|
next = source[++i + 1];
|
|
143
143
|
}
|
|
144
144
|
else if (next === 'x' || next === 'u' || next === 'U') {
|
|
145
|
-
const length =
|
|
145
|
+
const length = next === 'x' ? 2 : next === 'u' ? 4 : 8;
|
|
146
146
|
res += parseCharCode(source, i + 1, length, onError);
|
|
147
147
|
i += length;
|
|
148
148
|
}
|
|
@@ -212,12 +212,14 @@ function parseCharCode(source, offset, length, onError) {
|
|
|
212
212
|
const cc = source.substr(offset, length);
|
|
213
213
|
const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
|
|
214
214
|
const code = ok ? parseInt(cc, 16) : NaN;
|
|
215
|
-
|
|
215
|
+
try {
|
|
216
|
+
return String.fromCodePoint(code);
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
216
219
|
const raw = source.substr(offset - 2, length + 2);
|
|
217
220
|
onError(offset - 2, 'BAD_DQ_ESCAPE', `Invalid escape sequence ${raw}`);
|
|
218
221
|
return raw;
|
|
219
222
|
}
|
|
220
|
-
return String.fromCodePoint(code);
|
|
221
223
|
}
|
|
222
224
|
|
|
223
225
|
export { resolveFlowScalar };
|
|
@@ -19,6 +19,8 @@ class Alias extends NodeBase {
|
|
|
19
19
|
* instance of the `source` anchor before this node.
|
|
20
20
|
*/
|
|
21
21
|
resolve(doc, ctx) {
|
|
22
|
+
if (ctx?.maxAliasCount === 0)
|
|
23
|
+
throw new ReferenceError('Alias resolution is disabled');
|
|
22
24
|
let nodes;
|
|
23
25
|
if (ctx?.aliasResolveCache) {
|
|
24
26
|
nodes = ctx.aliasResolveCache;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isScalar,
|
|
1
|
+
import { isScalar, isSeq, isAlias, isMap } from '../../nodes/identity.js';
|
|
2
2
|
import { Scalar } from '../../nodes/Scalar.js';
|
|
3
3
|
|
|
4
4
|
// If the value associated with a merge key is a single mapping node, each of
|
|
@@ -26,18 +26,18 @@ const isMergeKey = (ctx, key) => (merge.identify(key) ||
|
|
|
26
26
|
merge.identify(key.value))) &&
|
|
27
27
|
ctx?.doc.schema.tags.some(tag => tag.tag === merge.tag && tag.default);
|
|
28
28
|
function addMergeToJSMap(ctx, map, value) {
|
|
29
|
-
|
|
30
|
-
if (isSeq(
|
|
31
|
-
for (const it of
|
|
29
|
+
const source = resolveAliasValue(ctx, value);
|
|
30
|
+
if (isSeq(source))
|
|
31
|
+
for (const it of source.items)
|
|
32
32
|
mergeValue(ctx, map, it);
|
|
33
|
-
else if (Array.isArray(
|
|
34
|
-
for (const it of
|
|
33
|
+
else if (Array.isArray(source))
|
|
34
|
+
for (const it of source)
|
|
35
35
|
mergeValue(ctx, map, it);
|
|
36
36
|
else
|
|
37
|
-
mergeValue(ctx, map,
|
|
37
|
+
mergeValue(ctx, map, source);
|
|
38
38
|
}
|
|
39
39
|
function mergeValue(ctx, map, value) {
|
|
40
|
-
const source = ctx
|
|
40
|
+
const source = resolveAliasValue(ctx, value);
|
|
41
41
|
if (!isMap(source))
|
|
42
42
|
throw new Error('Merge sources must be maps or map aliases');
|
|
43
43
|
const srcMap = source.toJSON(null, ctx, Map);
|
|
@@ -60,5 +60,8 @@ function mergeValue(ctx, map, value) {
|
|
|
60
60
|
}
|
|
61
61
|
return map;
|
|
62
62
|
}
|
|
63
|
+
function resolveAliasValue(ctx, value) {
|
|
64
|
+
return ctx && isAlias(value) ? value.resolve(ctx.doc, ctx) : value;
|
|
65
|
+
}
|
|
63
66
|
|
|
64
67
|
export { addMergeToJSMap, isMergeKey, merge };
|
|
@@ -102,12 +102,22 @@ function stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) {
|
|
|
102
102
|
if (comment)
|
|
103
103
|
reqNewline = true;
|
|
104
104
|
let str = stringify(item, itemCtx, () => (comment = null));
|
|
105
|
-
|
|
105
|
+
reqNewline || (reqNewline = lines.length > linesAtValue || str.includes('\n'));
|
|
106
|
+
if (i < items.length - 1) {
|
|
106
107
|
str += ',';
|
|
108
|
+
}
|
|
109
|
+
else if (ctx.options.trailingComma) {
|
|
110
|
+
if (ctx.options.lineWidth > 0) {
|
|
111
|
+
reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) +
|
|
112
|
+
(str.length + 2) >
|
|
113
|
+
ctx.options.lineWidth);
|
|
114
|
+
}
|
|
115
|
+
if (reqNewline) {
|
|
116
|
+
str += ',';
|
|
117
|
+
}
|
|
118
|
+
}
|
|
107
119
|
if (comment)
|
|
108
120
|
str += lineComment(str, itemIndent, commentString(comment));
|
|
109
|
-
if (!reqNewline && (lines.length > linesAtValue || str.includes('\n')))
|
|
110
|
-
reqNewline = true;
|
|
111
121
|
lines.push(str);
|
|
112
122
|
linesAtValue = lines.length;
|
|
113
123
|
}
|
|
@@ -8,7 +8,8 @@ function stringifyNumber({ format, minFractionDigits, tag, value }) {
|
|
|
8
8
|
if (!format &&
|
|
9
9
|
minFractionDigits &&
|
|
10
10
|
(!tag || tag === 'tag:yaml.org,2002:float') &&
|
|
11
|
-
|
|
11
|
+
/^-?\d/.test(n) &&
|
|
12
|
+
!n.includes('e')) {
|
|
12
13
|
let i = n.indexOf('.');
|
|
13
14
|
if (i < 0) {
|
|
14
15
|
i = n.length;
|
|
@@ -30,19 +30,26 @@ function composeNode(ctx, token, props, onError) {
|
|
|
30
30
|
case 'block-map':
|
|
31
31
|
case 'block-seq':
|
|
32
32
|
case 'flow-collection':
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
try {
|
|
34
|
+
node = composeCollection.composeCollection(CN, ctx, token, props, onError);
|
|
35
|
+
if (anchor)
|
|
36
|
+
node.anchor = anchor.source.substring(1);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
// Almost certainly here due to a stack overflow
|
|
40
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
41
|
+
onError(token, 'RESOURCE_EXHAUSTION', message);
|
|
42
|
+
}
|
|
36
43
|
break;
|
|
37
44
|
default: {
|
|
38
45
|
const message = token.type === 'error'
|
|
39
46
|
? token.message
|
|
40
47
|
: `Unsupported token (type: ${token.type})`;
|
|
41
48
|
onError(token, 'UNEXPECTED_TOKEN', message);
|
|
42
|
-
node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError);
|
|
43
49
|
isSrcToken = false;
|
|
44
50
|
}
|
|
45
51
|
}
|
|
52
|
+
node ?? (node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError));
|
|
46
53
|
if (anchor && node.anchor === '')
|
|
47
54
|
onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');
|
|
48
55
|
if (atKey &&
|
|
@@ -144,7 +144,7 @@ function doubleQuotedValue(source, onError) {
|
|
|
144
144
|
next = source[++i + 1];
|
|
145
145
|
}
|
|
146
146
|
else if (next === 'x' || next === 'u' || next === 'U') {
|
|
147
|
-
const length =
|
|
147
|
+
const length = next === 'x' ? 2 : next === 'u' ? 4 : 8;
|
|
148
148
|
res += parseCharCode(source, i + 1, length, onError);
|
|
149
149
|
i += length;
|
|
150
150
|
}
|
|
@@ -214,12 +214,14 @@ function parseCharCode(source, offset, length, onError) {
|
|
|
214
214
|
const cc = source.substr(offset, length);
|
|
215
215
|
const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
|
|
216
216
|
const code = ok ? parseInt(cc, 16) : NaN;
|
|
217
|
-
|
|
217
|
+
try {
|
|
218
|
+
return String.fromCodePoint(code);
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
218
221
|
const raw = source.substr(offset - 2, length + 2);
|
|
219
222
|
onError(offset - 2, 'BAD_DQ_ESCAPE', `Invalid escape sequence ${raw}`);
|
|
220
223
|
return raw;
|
|
221
224
|
}
|
|
222
|
-
return String.fromCodePoint(code);
|
|
223
225
|
}
|
|
224
226
|
|
|
225
227
|
exports.resolveFlowScalar = resolveFlowScalar;
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { LineCounter } from './parse/line-counter';
|
|
2
|
-
export type ErrorCode = 'ALIAS_PROPS' | 'BAD_ALIAS' | 'BAD_DIRECTIVE' | 'BAD_DQ_ESCAPE' | 'BAD_INDENT' | 'BAD_PROP_ORDER' | 'BAD_SCALAR_START' | 'BLOCK_AS_IMPLICIT_KEY' | 'BLOCK_IN_FLOW' | 'DUPLICATE_KEY' | 'IMPOSSIBLE' | 'KEY_OVER_1024_CHARS' | 'MISSING_CHAR' | 'MULTILINE_IMPLICIT_KEY' | 'MULTIPLE_ANCHORS' | 'MULTIPLE_DOCS' | 'MULTIPLE_TAGS' | 'NON_STRING_KEY' | 'TAB_AS_INDENT' | 'TAG_RESOLVE_FAILED' | 'UNEXPECTED_TOKEN' | 'BAD_COLLECTION_TYPE';
|
|
2
|
+
export type ErrorCode = 'ALIAS_PROPS' | 'BAD_ALIAS' | 'BAD_DIRECTIVE' | 'BAD_DQ_ESCAPE' | 'BAD_INDENT' | 'BAD_PROP_ORDER' | 'BAD_SCALAR_START' | 'BLOCK_AS_IMPLICIT_KEY' | 'BLOCK_IN_FLOW' | 'DUPLICATE_KEY' | 'IMPOSSIBLE' | 'KEY_OVER_1024_CHARS' | 'MISSING_CHAR' | 'MULTILINE_IMPLICIT_KEY' | 'MULTIPLE_ANCHORS' | 'MULTIPLE_DOCS' | 'MULTIPLE_TAGS' | 'NON_STRING_KEY' | 'RESOURCE_EXHAUSTION' | 'TAB_AS_INDENT' | 'TAG_RESOLVE_FAILED' | 'UNEXPECTED_TOKEN' | 'BAD_COLLECTION_TYPE';
|
|
3
3
|
export type LinePos = {
|
|
4
4
|
line: number;
|
|
5
5
|
col: number;
|
package/dist/nodes/Alias.js
CHANGED
|
@@ -21,6 +21,8 @@ class Alias extends Node.NodeBase {
|
|
|
21
21
|
* instance of the `source` anchor before this node.
|
|
22
22
|
*/
|
|
23
23
|
resolve(doc, ctx) {
|
|
24
|
+
if (ctx?.maxAliasCount === 0)
|
|
25
|
+
throw new ReferenceError('Alias resolution is disabled');
|
|
24
26
|
let nodes;
|
|
25
27
|
if (ctx?.aliasResolveCache) {
|
|
26
28
|
nodes = ctx.aliasResolveCache;
|
package/dist/nodes/Scalar.d.ts
CHANGED
|
@@ -31,7 +31,11 @@ export declare class Scalar<T = unknown> extends NodeBase {
|
|
|
31
31
|
* The YAML 1.1 schema also supports 'BIN' and 'TIME'
|
|
32
32
|
*/
|
|
33
33
|
format?: string;
|
|
34
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* If `value` is a number that is serialized as a decimal string
|
|
36
|
+
* (i.e. not using exponential notation),
|
|
37
|
+
* use this value when stringifying this node.
|
|
38
|
+
*/
|
|
35
39
|
minFractionDigits?: number;
|
|
36
40
|
/** Set during parsing to the source string value */
|
|
37
41
|
source?: string;
|
package/dist/options.d.ts
CHANGED
|
@@ -326,6 +326,12 @@ export type ToStringOptions = {
|
|
|
326
326
|
* Default: `null`
|
|
327
327
|
*/
|
|
328
328
|
singleQuote?: boolean | null;
|
|
329
|
+
/**
|
|
330
|
+
* Add a trailing comma after the last entry in a flow map or flow sequence that's split across multiple lines.
|
|
331
|
+
*
|
|
332
|
+
* Default: `'false'`
|
|
333
|
+
*/
|
|
334
|
+
trailingComma?: boolean;
|
|
329
335
|
/**
|
|
330
336
|
* String representation for `true`.
|
|
331
337
|
* With the core schema, use `'true'`, `'True'`, or `'TRUE'`.
|
|
@@ -28,18 +28,18 @@ const isMergeKey = (ctx, key) => (merge.identify(key) ||
|
|
|
28
28
|
merge.identify(key.value))) &&
|
|
29
29
|
ctx?.doc.schema.tags.some(tag => tag.tag === merge.tag && tag.default);
|
|
30
30
|
function addMergeToJSMap(ctx, map, value) {
|
|
31
|
-
|
|
32
|
-
if (identity.isSeq(
|
|
33
|
-
for (const it of
|
|
31
|
+
const source = resolveAliasValue(ctx, value);
|
|
32
|
+
if (identity.isSeq(source))
|
|
33
|
+
for (const it of source.items)
|
|
34
34
|
mergeValue(ctx, map, it);
|
|
35
|
-
else if (Array.isArray(
|
|
36
|
-
for (const it of
|
|
35
|
+
else if (Array.isArray(source))
|
|
36
|
+
for (const it of source)
|
|
37
37
|
mergeValue(ctx, map, it);
|
|
38
38
|
else
|
|
39
|
-
mergeValue(ctx, map,
|
|
39
|
+
mergeValue(ctx, map, source);
|
|
40
40
|
}
|
|
41
41
|
function mergeValue(ctx, map, value) {
|
|
42
|
-
const source = ctx
|
|
42
|
+
const source = resolveAliasValue(ctx, value);
|
|
43
43
|
if (!identity.isMap(source))
|
|
44
44
|
throw new Error('Merge sources must be maps or map aliases');
|
|
45
45
|
const srcMap = source.toJSON(null, ctx, Map);
|
|
@@ -62,6 +62,9 @@ function mergeValue(ctx, map, value) {
|
|
|
62
62
|
}
|
|
63
63
|
return map;
|
|
64
64
|
}
|
|
65
|
+
function resolveAliasValue(ctx, value) {
|
|
66
|
+
return ctx && identity.isAlias(value) ? value.resolve(ctx.doc, ctx) : value;
|
|
67
|
+
}
|
|
65
68
|
|
|
66
69
|
exports.addMergeToJSMap = addMergeToJSMap;
|
|
67
70
|
exports.isMergeKey = isMergeKey;
|
|
@@ -104,12 +104,22 @@ function stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) {
|
|
|
104
104
|
if (comment)
|
|
105
105
|
reqNewline = true;
|
|
106
106
|
let str = stringify.stringify(item, itemCtx, () => (comment = null));
|
|
107
|
-
|
|
107
|
+
reqNewline || (reqNewline = lines.length > linesAtValue || str.includes('\n'));
|
|
108
|
+
if (i < items.length - 1) {
|
|
108
109
|
str += ',';
|
|
110
|
+
}
|
|
111
|
+
else if (ctx.options.trailingComma) {
|
|
112
|
+
if (ctx.options.lineWidth > 0) {
|
|
113
|
+
reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) +
|
|
114
|
+
(str.length + 2) >
|
|
115
|
+
ctx.options.lineWidth);
|
|
116
|
+
}
|
|
117
|
+
if (reqNewline) {
|
|
118
|
+
str += ',';
|
|
119
|
+
}
|
|
120
|
+
}
|
|
109
121
|
if (comment)
|
|
110
122
|
str += stringifyComment.lineComment(str, itemIndent, commentString(comment));
|
|
111
|
-
if (!reqNewline && (lines.length > linesAtValue || str.includes('\n')))
|
|
112
|
-
reqNewline = true;
|
|
113
123
|
lines.push(str);
|
|
114
124
|
linesAtValue = lines.length;
|
|
115
125
|
}
|
|
@@ -10,7 +10,8 @@ function stringifyNumber({ format, minFractionDigits, tag, value }) {
|
|
|
10
10
|
if (!format &&
|
|
11
11
|
minFractionDigits &&
|
|
12
12
|
(!tag || tag === 'tag:yaml.org,2002:float') &&
|
|
13
|
-
|
|
13
|
+
/^-?\d/.test(n) &&
|
|
14
|
+
!n.includes('e')) {
|
|
14
15
|
let i = n.indexOf('.');
|
|
15
16
|
if (i < 0) {
|
|
16
17
|
i = n.length;
|