yaml 2.0.0-7 → 2.0.0-8
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-scalar.js +2 -1
- package/browser/dist/compose/resolve-flow-scalar.js +7 -1
- package/browser/dist/doc/Document.js +26 -2
- package/browser/dist/doc/createNode.js +5 -3
- package/browser/dist/doc/directives.js +5 -0
- package/browser/dist/nodes/Collection.js +20 -11
- package/browser/dist/nodes/Node.js +7 -0
- package/browser/dist/nodes/Pair.js +9 -1
- package/browser/dist/nodes/addPairToJSMap.js +1 -1
- package/browser/dist/parse/lexer.js +23 -11
- package/browser/dist/schema/Schema.js +5 -0
- package/dist/compose/compose-scalar.js +2 -1
- package/dist/compose/resolve-flow-scalar.js +7 -1
- package/dist/doc/Document.d.ts +6 -0
- package/dist/doc/Document.js +25 -1
- package/dist/doc/createNode.d.ts +2 -1
- package/dist/doc/createNode.js +4 -2
- package/dist/doc/directives.d.ts +1 -0
- package/dist/doc/directives.js +5 -0
- package/dist/nodes/Collection.d.ts +6 -0
- package/dist/nodes/Collection.js +19 -10
- package/dist/nodes/Node.d.ts +3 -1
- package/dist/nodes/Node.js +7 -0
- package/dist/nodes/Pair.d.ts +4 -2
- package/dist/nodes/Pair.js +8 -0
- package/dist/options.d.ts +7 -0
- package/dist/parse/lexer.d.ts +2 -0
- package/dist/parse/lexer.js +23 -11
- package/dist/schema/Schema.d.ts +1 -0
- package/dist/schema/Schema.js +5 -0
- package/package.json +3 -3
|
@@ -19,7 +19,8 @@ function composeScalar(ctx, token, tagToken, onError) {
|
|
|
19
19
|
scalar = isScalar(res) ? res : new Scalar(res);
|
|
20
20
|
}
|
|
21
21
|
catch (error) {
|
|
22
|
-
|
|
22
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
23
|
+
onError(tagToken || token, 'TAG_RESOLVE_FAILED', msg);
|
|
23
24
|
scalar = new Scalar(value);
|
|
24
25
|
}
|
|
25
26
|
scalar.range = range;
|
|
@@ -135,6 +135,12 @@ function doubleQuotedValue(source, onError) {
|
|
|
135
135
|
while (next === ' ' || next === '\t')
|
|
136
136
|
next = source[++i + 1];
|
|
137
137
|
}
|
|
138
|
+
else if (next === '\r' && source[i + 1] === '\n') {
|
|
139
|
+
// skip escaped CRLF newlines, but still trim the following line
|
|
140
|
+
next = source[++i + 1];
|
|
141
|
+
while (next === ' ' || next === '\t')
|
|
142
|
+
next = source[++i + 1];
|
|
143
|
+
}
|
|
138
144
|
else if (next === 'x' || next === 'u' || next === 'U') {
|
|
139
145
|
const length = { x: 2, u: 4, U: 8 }[next];
|
|
140
146
|
res += parseCharCode(source, i + 1, length, onError);
|
|
@@ -152,7 +158,7 @@ function doubleQuotedValue(source, onError) {
|
|
|
152
158
|
let next = source[i + 1];
|
|
153
159
|
while (next === ' ' || next === '\t')
|
|
154
160
|
next = source[++i + 1];
|
|
155
|
-
if (next !== '\n')
|
|
161
|
+
if (next !== '\n' && !(next === '\r' && source[i + 2] === '\n'))
|
|
156
162
|
res += i > wsStart ? source.slice(wsStart, i + 1) : ch;
|
|
157
163
|
}
|
|
158
164
|
else {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Alias } from '../nodes/Alias.js';
|
|
2
2
|
import { isEmptyPath, collectionFromPath } from '../nodes/Collection.js';
|
|
3
|
-
import { NODE_TYPE, DOC, isCollection, isScalar } from '../nodes/Node.js';
|
|
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
6
|
import { defaultOptions } from '../options.js';
|
|
@@ -48,6 +48,29 @@ class Document {
|
|
|
48
48
|
this.contents = this.createNode(value, _replacer, options);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Create a deep copy of this Document and its contents.
|
|
53
|
+
*
|
|
54
|
+
* Custom Node values that inherit from `Object` still refer to their original instances.
|
|
55
|
+
*/
|
|
56
|
+
clone() {
|
|
57
|
+
const copy = Object.create(Document.prototype, {
|
|
58
|
+
[NODE_TYPE]: { value: DOC }
|
|
59
|
+
});
|
|
60
|
+
copy.commentBefore = this.commentBefore;
|
|
61
|
+
copy.comment = this.comment;
|
|
62
|
+
copy.errors = this.errors.slice();
|
|
63
|
+
copy.warnings = this.warnings.slice();
|
|
64
|
+
copy.options = Object.assign({}, this.options);
|
|
65
|
+
copy.directives = this.directives.clone();
|
|
66
|
+
copy.schema = this.schema.clone();
|
|
67
|
+
copy.contents = isNode(this.contents)
|
|
68
|
+
? this.contents.clone(copy.schema)
|
|
69
|
+
: this.contents;
|
|
70
|
+
if (this.range)
|
|
71
|
+
copy.range = this.range.slice();
|
|
72
|
+
return copy;
|
|
73
|
+
}
|
|
51
74
|
/** Adds a value to the document. */
|
|
52
75
|
add(value) {
|
|
53
76
|
if (assertCollection(this.contents))
|
|
@@ -92,9 +115,10 @@ class Document {
|
|
|
92
115
|
options = replacer;
|
|
93
116
|
replacer = undefined;
|
|
94
117
|
}
|
|
95
|
-
const { anchorPrefix, flow, keepUndefined, onTagObj, tag } = options || {};
|
|
118
|
+
const { aliasDuplicateObjects, anchorPrefix, flow, keepUndefined, onTagObj, tag } = options || {};
|
|
96
119
|
const { onAnchor, setAnchors, sourceObjects } = createNodeAnchors(this, anchorPrefix || 'a');
|
|
97
120
|
const ctx = {
|
|
121
|
+
aliasDuplicateObjects: aliasDuplicateObjects !== null && aliasDuplicateObjects !== void 0 ? aliasDuplicateObjects : true,
|
|
98
122
|
keepUndefined: keepUndefined !== null && keepUndefined !== void 0 ? keepUndefined : false,
|
|
99
123
|
onAnchor,
|
|
100
124
|
onTagObj,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Alias } from '../nodes/Alias.js';
|
|
2
|
-
import { isNode, isPair, MAP, SEQ } from '../nodes/Node.js';
|
|
2
|
+
import { isNode, isPair, MAP, SEQ, isDocument } from '../nodes/Node.js';
|
|
3
3
|
import { Scalar } from '../nodes/Scalar.js';
|
|
4
4
|
|
|
5
5
|
const defaultTagPrefix = 'tag:yaml.org,2002:';
|
|
@@ -15,6 +15,8 @@ function findTagObject(value, tagName, tags) {
|
|
|
15
15
|
}
|
|
16
16
|
function createNode(value, tagName, ctx) {
|
|
17
17
|
var _a, _b;
|
|
18
|
+
if (isDocument(value))
|
|
19
|
+
value = value.contents;
|
|
18
20
|
if (isNode(value))
|
|
19
21
|
return value;
|
|
20
22
|
if (isPair(value)) {
|
|
@@ -30,11 +32,11 @@ function createNode(value, tagName, ctx) {
|
|
|
30
32
|
// https://tc39.es/ecma262/#sec-serializejsonproperty
|
|
31
33
|
value = value.valueOf();
|
|
32
34
|
}
|
|
33
|
-
const { onAnchor, onTagObj, schema, sourceObjects } = ctx;
|
|
35
|
+
const { aliasDuplicateObjects, onAnchor, onTagObj, schema, sourceObjects } = ctx;
|
|
34
36
|
// Detect duplicate references to the same object & use Alias nodes for all
|
|
35
37
|
// after first. The `ref` wrapper allows for circular references to resolve.
|
|
36
38
|
let ref = undefined;
|
|
37
|
-
if (value && typeof value === 'object') {
|
|
39
|
+
if (aliasDuplicateObjects && value && typeof value === 'object') {
|
|
38
40
|
ref = sourceObjects.get(value);
|
|
39
41
|
if (ref) {
|
|
40
42
|
if (!ref.anchor)
|
|
@@ -20,6 +20,11 @@ class Directives {
|
|
|
20
20
|
this.yaml = Object.assign({}, Directives.defaultYaml, yaml);
|
|
21
21
|
this.tags = Object.assign({}, Directives.defaultTags, tags);
|
|
22
22
|
}
|
|
23
|
+
clone() {
|
|
24
|
+
const copy = new Directives(this.yaml, this.tags);
|
|
25
|
+
copy.marker = this.marker;
|
|
26
|
+
return copy;
|
|
27
|
+
}
|
|
23
28
|
/**
|
|
24
29
|
* During parsing, get a Directives instance for the current document and
|
|
25
30
|
* update the stream state according to the current version's spec.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createNode } from '../doc/createNode.js';
|
|
2
|
-
import { NodeBase, isCollection, isScalar
|
|
2
|
+
import { NodeBase, isNode, isPair, isCollection, isScalar } from './Node.js';
|
|
3
3
|
|
|
4
4
|
function collectionFromPath(schema, path, value) {
|
|
5
5
|
let v = value;
|
|
@@ -11,19 +11,14 @@ function collectionFromPath(schema, path, value) {
|
|
|
11
11
|
v = a;
|
|
12
12
|
}
|
|
13
13
|
else {
|
|
14
|
-
|
|
15
|
-
Object.defineProperty(o, typeof k === 'symbol' ? k : String(k), {
|
|
16
|
-
value: v,
|
|
17
|
-
writable: true,
|
|
18
|
-
enumerable: true,
|
|
19
|
-
configurable: true
|
|
20
|
-
});
|
|
21
|
-
v = o;
|
|
14
|
+
v = new Map([[k, v]]);
|
|
22
15
|
}
|
|
23
16
|
}
|
|
24
17
|
return createNode(v, undefined, {
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
aliasDuplicateObjects: false,
|
|
19
|
+
keepUndefined: false,
|
|
20
|
+
onAnchor: () => {
|
|
21
|
+
throw new Error('This should not happen, please report a bug.');
|
|
27
22
|
},
|
|
28
23
|
schema,
|
|
29
24
|
sourceObjects: new Map()
|
|
@@ -42,6 +37,20 @@ class Collection extends NodeBase {
|
|
|
42
37
|
writable: true
|
|
43
38
|
});
|
|
44
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Create a copy of this collection.
|
|
42
|
+
*
|
|
43
|
+
* @param schema - If defined, overwrites the original's schema
|
|
44
|
+
*/
|
|
45
|
+
clone(schema) {
|
|
46
|
+
const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));
|
|
47
|
+
if (schema)
|
|
48
|
+
copy.schema = schema;
|
|
49
|
+
copy.items = copy.items.map(it => isNode(it) || isPair(it) ? it.clone(schema) : it);
|
|
50
|
+
if (this.range)
|
|
51
|
+
copy.range = this.range.slice();
|
|
52
|
+
return copy;
|
|
53
|
+
}
|
|
45
54
|
/**
|
|
46
55
|
* Adds a value to the collection. For `!!map` and `!!omap` the value must
|
|
47
56
|
* be a Pair instance or a `{ key, value }` object, which may not have a key
|
|
@@ -36,6 +36,13 @@ class NodeBase {
|
|
|
36
36
|
constructor(type) {
|
|
37
37
|
Object.defineProperty(this, NODE_TYPE, { value: type });
|
|
38
38
|
}
|
|
39
|
+
/** Create a copy of this node. */
|
|
40
|
+
clone() {
|
|
41
|
+
const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));
|
|
42
|
+
if (this.range)
|
|
43
|
+
copy.range = this.range.slice();
|
|
44
|
+
return copy;
|
|
45
|
+
}
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
export { ALIAS, DOC, MAP, NODE_TYPE, NodeBase, PAIR, SCALAR, SEQ, hasAnchor, isAlias, isCollection, isDocument, isMap, isNode, isPair, isScalar, isSeq };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createNode } from '../doc/createNode.js';
|
|
2
2
|
import { stringifyPair } from '../stringify/stringifyPair.js';
|
|
3
3
|
import { addPairToJSMap } from './addPairToJSMap.js';
|
|
4
|
-
import { NODE_TYPE, PAIR } from './Node.js';
|
|
4
|
+
import { NODE_TYPE, PAIR, isNode } from './Node.js';
|
|
5
5
|
|
|
6
6
|
function createPair(key, value, ctx) {
|
|
7
7
|
const k = createNode(key, undefined, ctx);
|
|
@@ -14,6 +14,14 @@ class Pair {
|
|
|
14
14
|
this.key = key;
|
|
15
15
|
this.value = value;
|
|
16
16
|
}
|
|
17
|
+
clone(schema) {
|
|
18
|
+
let { key, value } = this;
|
|
19
|
+
if (isNode(key))
|
|
20
|
+
key = key.clone(schema);
|
|
21
|
+
if (isNode(value))
|
|
22
|
+
value = value.clone(schema);
|
|
23
|
+
return new Pair(key, value);
|
|
24
|
+
}
|
|
17
25
|
toJSON(_, ctx) {
|
|
18
26
|
const pair = ctx && ctx.mapAsMap ? new Map() : {};
|
|
19
27
|
return addPairToJSMap(ctx, pair, this);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { warn } from '../log.js';
|
|
2
2
|
import { createStringifyContext } from '../stringify/stringify.js';
|
|
3
|
-
import {
|
|
3
|
+
import { isSeq, isScalar, isAlias, isMap, isNode } from './Node.js';
|
|
4
4
|
import { Scalar } from './Scalar.js';
|
|
5
5
|
import { toJS } from './toJS.js';
|
|
6
6
|
|
|
@@ -134,6 +134,8 @@ class Lexer {
|
|
|
134
134
|
this.indentNext = 0;
|
|
135
135
|
/** Indentation level of the current line. */
|
|
136
136
|
this.indentValue = 0;
|
|
137
|
+
/** Position of the next \n character. */
|
|
138
|
+
this.lineEndPos = null;
|
|
137
139
|
/** Stores the state of the lexer if reaching the end of incpomplete input */
|
|
138
140
|
this.next = null;
|
|
139
141
|
/** A pointer to `buffer`; the current position of the lexer. */
|
|
@@ -146,8 +148,10 @@ class Lexer {
|
|
|
146
148
|
* @returns A generator of lexical tokens
|
|
147
149
|
*/
|
|
148
150
|
*lex(source, incomplete = false) {
|
|
149
|
-
if (source)
|
|
151
|
+
if (source) {
|
|
150
152
|
this.buffer = this.buffer ? this.buffer + source : source;
|
|
153
|
+
this.lineEndPos = null;
|
|
154
|
+
}
|
|
151
155
|
this.atEnd = !incomplete;
|
|
152
156
|
let next = this.next || 'stream';
|
|
153
157
|
while (next && (incomplete || this.hasChars(1)))
|
|
@@ -190,7 +194,11 @@ class Lexer {
|
|
|
190
194
|
return offset;
|
|
191
195
|
}
|
|
192
196
|
getLine() {
|
|
193
|
-
let end = this.
|
|
197
|
+
let end = this.lineEndPos;
|
|
198
|
+
if (typeof end !== 'number' || (end !== -1 && end < this.pos)) {
|
|
199
|
+
end = this.buffer.indexOf('\n', this.pos);
|
|
200
|
+
this.lineEndPos = end;
|
|
201
|
+
}
|
|
194
202
|
if (end === -1)
|
|
195
203
|
return this.atEnd ? this.buffer.substring(this.pos) : null;
|
|
196
204
|
if (this.buffer[end - 1] === '\r')
|
|
@@ -203,6 +211,7 @@ class Lexer {
|
|
|
203
211
|
setNext(state) {
|
|
204
212
|
this.buffer = this.buffer.substring(this.pos);
|
|
205
213
|
this.pos = 0;
|
|
214
|
+
this.lineEndPos = null;
|
|
206
215
|
this.next = state;
|
|
207
216
|
return null;
|
|
208
217
|
}
|
|
@@ -433,17 +442,19 @@ class Lexer {
|
|
|
433
442
|
end = this.buffer.indexOf('"', end + 1);
|
|
434
443
|
}
|
|
435
444
|
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
445
|
+
// Only looking for newlines within the quotes
|
|
446
|
+
const qb = this.buffer.substring(0, end);
|
|
447
|
+
let nl = qb.indexOf('\n', this.pos);
|
|
448
|
+
if (nl !== -1) {
|
|
449
|
+
while (nl !== -1) {
|
|
439
450
|
const cs = this.continueScalar(nl + 1);
|
|
440
451
|
if (cs === -1)
|
|
441
452
|
break;
|
|
442
|
-
nl =
|
|
453
|
+
nl = qb.indexOf('\n', cs);
|
|
443
454
|
}
|
|
444
|
-
if (nl !== -1
|
|
455
|
+
if (nl !== -1) {
|
|
445
456
|
// this is an error caused by an unexpected unindent
|
|
446
|
-
end = nl - 1;
|
|
457
|
+
end = nl - (qb[nl - 1] === '\r' ? 2 : 1);
|
|
447
458
|
}
|
|
448
459
|
}
|
|
449
460
|
if (end === -1) {
|
|
@@ -543,17 +554,18 @@ class Lexer {
|
|
|
543
554
|
end = i;
|
|
544
555
|
}
|
|
545
556
|
else if (isEmpty(ch)) {
|
|
546
|
-
|
|
547
|
-
if (next === '#' || (inFlow && invalidFlowScalarChars.includes(next)))
|
|
548
|
-
break;
|
|
557
|
+
let next = this.buffer[i + 1];
|
|
549
558
|
if (ch === '\r') {
|
|
550
559
|
if (next === '\n') {
|
|
551
560
|
i += 1;
|
|
552
561
|
ch = '\n';
|
|
562
|
+
next = this.buffer[i + 1];
|
|
553
563
|
}
|
|
554
564
|
else
|
|
555
565
|
end = i;
|
|
556
566
|
}
|
|
567
|
+
if (next === '#' || (inFlow && invalidFlowScalarChars.includes(next)))
|
|
568
|
+
break;
|
|
557
569
|
if (ch === '\n') {
|
|
558
570
|
const cs = this.continueScalar(i + 1);
|
|
559
571
|
if (cs === -1)
|
|
@@ -18,6 +18,11 @@ class Schema {
|
|
|
18
18
|
this.sortMapEntries =
|
|
19
19
|
sortMapEntries === true ? sortMapEntriesByKey : sortMapEntries || null;
|
|
20
20
|
}
|
|
21
|
+
clone() {
|
|
22
|
+
const copy = Object.create(Schema.prototype, Object.getOwnPropertyDescriptors(this));
|
|
23
|
+
copy.tags = this.tags.slice();
|
|
24
|
+
return copy;
|
|
25
|
+
}
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
export { Schema };
|
|
@@ -21,7 +21,8 @@ function composeScalar(ctx, token, tagToken, onError) {
|
|
|
21
21
|
scalar = Node.isScalar(res) ? res : new Scalar.Scalar(res);
|
|
22
22
|
}
|
|
23
23
|
catch (error) {
|
|
24
|
-
|
|
24
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
25
|
+
onError(tagToken || token, 'TAG_RESOLVE_FAILED', msg);
|
|
25
26
|
scalar = new Scalar.Scalar(value);
|
|
26
27
|
}
|
|
27
28
|
scalar.range = range;
|
|
@@ -137,6 +137,12 @@ function doubleQuotedValue(source, onError) {
|
|
|
137
137
|
while (next === ' ' || next === '\t')
|
|
138
138
|
next = source[++i + 1];
|
|
139
139
|
}
|
|
140
|
+
else if (next === '\r' && source[i + 1] === '\n') {
|
|
141
|
+
// skip escaped CRLF newlines, but still trim the following line
|
|
142
|
+
next = source[++i + 1];
|
|
143
|
+
while (next === ' ' || next === '\t')
|
|
144
|
+
next = source[++i + 1];
|
|
145
|
+
}
|
|
140
146
|
else if (next === 'x' || next === 'u' || next === 'U') {
|
|
141
147
|
const length = { x: 2, u: 4, U: 8 }[next];
|
|
142
148
|
res += parseCharCode(source, i + 1, length, onError);
|
|
@@ -154,7 +160,7 @@ function doubleQuotedValue(source, onError) {
|
|
|
154
160
|
let next = source[i + 1];
|
|
155
161
|
while (next === ' ' || next === '\t')
|
|
156
162
|
next = source[++i + 1];
|
|
157
|
-
if (next !== '\n')
|
|
163
|
+
if (next !== '\n' && !(next === '\r' && source[i + 2] === '\n'))
|
|
158
164
|
res += i > wsStart ? source.slice(wsStart, i + 1) : ch;
|
|
159
165
|
}
|
|
160
166
|
else {
|
package/dist/doc/Document.d.ts
CHANGED
|
@@ -43,6 +43,12 @@ export declare class Document<T = unknown> {
|
|
|
43
43
|
*/
|
|
44
44
|
constructor(value?: any, options?: DocumentOptions & SchemaOptions & ParseOptions & CreateNodeOptions);
|
|
45
45
|
constructor(value: any, replacer: null | Replacer, options?: DocumentOptions & SchemaOptions & ParseOptions & CreateNodeOptions);
|
|
46
|
+
/**
|
|
47
|
+
* Create a deep copy of this Document and its contents.
|
|
48
|
+
*
|
|
49
|
+
* Custom Node values that inherit from `Object` still refer to their original instances.
|
|
50
|
+
*/
|
|
51
|
+
clone(): Document<T>;
|
|
46
52
|
/** Adds a value to the document. */
|
|
47
53
|
add(value: any): void;
|
|
48
54
|
/** Adds a value to the document. */
|
package/dist/doc/Document.js
CHANGED
|
@@ -50,6 +50,29 @@ class Document {
|
|
|
50
50
|
this.contents = this.createNode(value, _replacer, options$1);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Create a deep copy of this Document and its contents.
|
|
55
|
+
*
|
|
56
|
+
* Custom Node values that inherit from `Object` still refer to their original instances.
|
|
57
|
+
*/
|
|
58
|
+
clone() {
|
|
59
|
+
const copy = Object.create(Document.prototype, {
|
|
60
|
+
[Node.NODE_TYPE]: { value: Node.DOC }
|
|
61
|
+
});
|
|
62
|
+
copy.commentBefore = this.commentBefore;
|
|
63
|
+
copy.comment = this.comment;
|
|
64
|
+
copy.errors = this.errors.slice();
|
|
65
|
+
copy.warnings = this.warnings.slice();
|
|
66
|
+
copy.options = Object.assign({}, this.options);
|
|
67
|
+
copy.directives = this.directives.clone();
|
|
68
|
+
copy.schema = this.schema.clone();
|
|
69
|
+
copy.contents = Node.isNode(this.contents)
|
|
70
|
+
? this.contents.clone(copy.schema)
|
|
71
|
+
: this.contents;
|
|
72
|
+
if (this.range)
|
|
73
|
+
copy.range = this.range.slice();
|
|
74
|
+
return copy;
|
|
75
|
+
}
|
|
53
76
|
/** Adds a value to the document. */
|
|
54
77
|
add(value) {
|
|
55
78
|
if (assertCollection(this.contents))
|
|
@@ -94,9 +117,10 @@ class Document {
|
|
|
94
117
|
options = replacer;
|
|
95
118
|
replacer = undefined;
|
|
96
119
|
}
|
|
97
|
-
const { anchorPrefix, flow, keepUndefined, onTagObj, tag } = options || {};
|
|
120
|
+
const { aliasDuplicateObjects, anchorPrefix, flow, keepUndefined, onTagObj, tag } = options || {};
|
|
98
121
|
const { onAnchor, setAnchors, sourceObjects } = anchors.createNodeAnchors(this, anchorPrefix || 'a');
|
|
99
122
|
const ctx = {
|
|
123
|
+
aliasDuplicateObjects: aliasDuplicateObjects !== null && aliasDuplicateObjects !== void 0 ? aliasDuplicateObjects : true,
|
|
100
124
|
keepUndefined: keepUndefined !== null && keepUndefined !== void 0 ? keepUndefined : false,
|
|
101
125
|
onAnchor,
|
|
102
126
|
onTagObj,
|
package/dist/doc/createNode.d.ts
CHANGED
|
@@ -3,7 +3,8 @@ import type { Schema } from '../schema/Schema.js';
|
|
|
3
3
|
import type { CollectionTag, ScalarTag } from '../schema/types.js';
|
|
4
4
|
import type { Replacer } from './Document.js';
|
|
5
5
|
export interface CreateNodeContext {
|
|
6
|
-
|
|
6
|
+
aliasDuplicateObjects: boolean;
|
|
7
|
+
keepUndefined: boolean;
|
|
7
8
|
onAnchor(source: unknown): string;
|
|
8
9
|
onTagObj?: (tagObj: ScalarTag | CollectionTag) => void;
|
|
9
10
|
sourceObjects: Map<unknown, {
|
package/dist/doc/createNode.js
CHANGED
|
@@ -17,6 +17,8 @@ function findTagObject(value, tagName, tags) {
|
|
|
17
17
|
}
|
|
18
18
|
function createNode(value, tagName, ctx) {
|
|
19
19
|
var _a, _b;
|
|
20
|
+
if (Node.isDocument(value))
|
|
21
|
+
value = value.contents;
|
|
20
22
|
if (Node.isNode(value))
|
|
21
23
|
return value;
|
|
22
24
|
if (Node.isPair(value)) {
|
|
@@ -32,11 +34,11 @@ function createNode(value, tagName, ctx) {
|
|
|
32
34
|
// https://tc39.es/ecma262/#sec-serializejsonproperty
|
|
33
35
|
value = value.valueOf();
|
|
34
36
|
}
|
|
35
|
-
const { onAnchor, onTagObj, schema, sourceObjects } = ctx;
|
|
37
|
+
const { aliasDuplicateObjects, onAnchor, onTagObj, schema, sourceObjects } = ctx;
|
|
36
38
|
// Detect duplicate references to the same object & use Alias nodes for all
|
|
37
39
|
// after first. The `ref` wrapper allows for circular references to resolve.
|
|
38
40
|
let ref = undefined;
|
|
39
|
-
if (value && typeof value === 'object') {
|
|
41
|
+
if (aliasDuplicateObjects && value && typeof value === 'object') {
|
|
40
42
|
ref = sourceObjects.get(value);
|
|
41
43
|
if (ref) {
|
|
42
44
|
if (!ref.anchor)
|
package/dist/doc/directives.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export declare class Directives {
|
|
|
20
20
|
*/
|
|
21
21
|
private atNextDocument?;
|
|
22
22
|
constructor(yaml?: Directives['yaml'], tags?: Directives['tags']);
|
|
23
|
+
clone(): Directives;
|
|
23
24
|
/**
|
|
24
25
|
* During parsing, get a Directives instance for the current document and
|
|
25
26
|
* update the stream state according to the current version's spec.
|
package/dist/doc/directives.js
CHANGED
|
@@ -22,6 +22,11 @@ class Directives {
|
|
|
22
22
|
this.yaml = Object.assign({}, Directives.defaultYaml, yaml);
|
|
23
23
|
this.tags = Object.assign({}, Directives.defaultTags, tags);
|
|
24
24
|
}
|
|
25
|
+
clone() {
|
|
26
|
+
const copy = new Directives(this.yaml, this.tags);
|
|
27
|
+
copy.marker = this.marker;
|
|
28
|
+
return copy;
|
|
29
|
+
}
|
|
25
30
|
/**
|
|
26
31
|
* During parsing, get a Directives instance for the current document and
|
|
27
32
|
* update the stream state according to the current version's spec.
|
|
@@ -15,6 +15,12 @@ export declare abstract class Collection extends NodeBase {
|
|
|
15
15
|
*/
|
|
16
16
|
flow?: boolean;
|
|
17
17
|
constructor(type: symbol, schema?: Schema);
|
|
18
|
+
/**
|
|
19
|
+
* Create a copy of this collection.
|
|
20
|
+
*
|
|
21
|
+
* @param schema - If defined, overwrites the original's schema
|
|
22
|
+
*/
|
|
23
|
+
clone(schema?: Schema): Collection;
|
|
18
24
|
/** Adds a value to the collection. */
|
|
19
25
|
abstract add(value: unknown): void;
|
|
20
26
|
/**
|
package/dist/nodes/Collection.js
CHANGED
|
@@ -13,19 +13,14 @@ function collectionFromPath(schema, path, value) {
|
|
|
13
13
|
v = a;
|
|
14
14
|
}
|
|
15
15
|
else {
|
|
16
|
-
|
|
17
|
-
Object.defineProperty(o, typeof k === 'symbol' ? k : String(k), {
|
|
18
|
-
value: v,
|
|
19
|
-
writable: true,
|
|
20
|
-
enumerable: true,
|
|
21
|
-
configurable: true
|
|
22
|
-
});
|
|
23
|
-
v = o;
|
|
16
|
+
v = new Map([[k, v]]);
|
|
24
17
|
}
|
|
25
18
|
}
|
|
26
19
|
return createNode.createNode(v, undefined, {
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
aliasDuplicateObjects: false,
|
|
21
|
+
keepUndefined: false,
|
|
22
|
+
onAnchor: () => {
|
|
23
|
+
throw new Error('This should not happen, please report a bug.');
|
|
29
24
|
},
|
|
30
25
|
schema,
|
|
31
26
|
sourceObjects: new Map()
|
|
@@ -44,6 +39,20 @@ class Collection extends Node.NodeBase {
|
|
|
44
39
|
writable: true
|
|
45
40
|
});
|
|
46
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Create a copy of this collection.
|
|
44
|
+
*
|
|
45
|
+
* @param schema - If defined, overwrites the original's schema
|
|
46
|
+
*/
|
|
47
|
+
clone(schema) {
|
|
48
|
+
const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));
|
|
49
|
+
if (schema)
|
|
50
|
+
copy.schema = schema;
|
|
51
|
+
copy.items = copy.items.map(it => Node.isNode(it) || Node.isPair(it) ? it.clone(schema) : it);
|
|
52
|
+
if (this.range)
|
|
53
|
+
copy.range = this.range.slice();
|
|
54
|
+
return copy;
|
|
55
|
+
}
|
|
47
56
|
/**
|
|
48
57
|
* Adds a value to the collection. For `!!map` and `!!omap` the value must
|
|
49
58
|
* be a Pair instance or a `{ key, value }` object, which may not have a key
|
package/dist/nodes/Node.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export declare const isScalar: (node: any) => node is Scalar<unknown>;
|
|
|
23
23
|
export declare const isSeq: (node: any) => node is YAMLSeq<unknown>;
|
|
24
24
|
export declare function isCollection(node: any): node is YAMLMap | YAMLSeq;
|
|
25
25
|
export declare function isNode(node: any): node is Node;
|
|
26
|
-
export declare const hasAnchor: (node: unknown) => node is
|
|
26
|
+
export declare const hasAnchor: (node: unknown) => node is Scalar<unknown> | YAMLMap<unknown, unknown> | YAMLSeq<unknown>;
|
|
27
27
|
export declare abstract class NodeBase {
|
|
28
28
|
readonly [NODE_TYPE]: symbol;
|
|
29
29
|
/** A comment on or immediately after this */
|
|
@@ -45,4 +45,6 @@ export declare abstract class NodeBase {
|
|
|
45
45
|
abstract toJSON(): any;
|
|
46
46
|
abstract toString(ctx?: StringifyContext, onComment?: () => void, onChompKeep?: () => void): string;
|
|
47
47
|
constructor(type: symbol);
|
|
48
|
+
/** Create a copy of this node. */
|
|
49
|
+
clone(): NodeBase;
|
|
48
50
|
}
|
package/dist/nodes/Node.js
CHANGED
|
@@ -38,6 +38,13 @@ class NodeBase {
|
|
|
38
38
|
constructor(type) {
|
|
39
39
|
Object.defineProperty(this, NODE_TYPE, { value: type });
|
|
40
40
|
}
|
|
41
|
+
/** Create a copy of this node. */
|
|
42
|
+
clone() {
|
|
43
|
+
const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));
|
|
44
|
+
if (this.range)
|
|
45
|
+
copy.range = this.range.slice();
|
|
46
|
+
return copy;
|
|
47
|
+
}
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
exports.ALIAS = ALIAS;
|
package/dist/nodes/Pair.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { CreateNodeContext } from '../doc/createNode.js';
|
|
2
|
-
import {
|
|
2
|
+
import type { Schema } from '../schema/Schema.js';
|
|
3
|
+
import type { StringifyContext } from '../stringify/stringify.js';
|
|
3
4
|
import { addPairToJSMap } from './addPairToJSMap.js';
|
|
4
5
|
import { NODE_TYPE } from './Node.js';
|
|
5
|
-
import { ToJSContext } from './toJS.js';
|
|
6
|
+
import type { ToJSContext } from './toJS.js';
|
|
6
7
|
export declare function createPair(key: unknown, value: unknown, ctx: CreateNodeContext): Pair<import("./Node.js").Node, import("./Alias.js").Alias | import("./Scalar.js").Scalar<unknown> | import("./YAMLMap.js").YAMLMap<unknown, unknown> | import("./YAMLSeq.js").YAMLSeq<unknown>>;
|
|
7
8
|
export declare class Pair<K = unknown, V = unknown> {
|
|
8
9
|
readonly [NODE_TYPE]: symbol;
|
|
@@ -11,6 +12,7 @@ export declare class Pair<K = unknown, V = unknown> {
|
|
|
11
12
|
/** Always Node or null when parsed, but can be set to anything. */
|
|
12
13
|
value: V | null;
|
|
13
14
|
constructor(key: K, value?: V | null);
|
|
15
|
+
clone(schema?: Schema): Pair<K, V>;
|
|
14
16
|
toJSON(_?: unknown, ctx?: ToJSContext): ReturnType<typeof addPairToJSMap>;
|
|
15
17
|
toString(ctx?: StringifyContext, onComment?: () => void, onChompKeep?: () => void): string;
|
|
16
18
|
}
|
package/dist/nodes/Pair.js
CHANGED
|
@@ -16,6 +16,14 @@ class Pair {
|
|
|
16
16
|
this.key = key;
|
|
17
17
|
this.value = value;
|
|
18
18
|
}
|
|
19
|
+
clone(schema) {
|
|
20
|
+
let { key, value } = this;
|
|
21
|
+
if (Node.isNode(key))
|
|
22
|
+
key = key.clone(schema);
|
|
23
|
+
if (Node.isNode(value))
|
|
24
|
+
value = value.clone(schema);
|
|
25
|
+
return new Pair(key, value);
|
|
26
|
+
}
|
|
19
27
|
toJSON(_, ctx) {
|
|
20
28
|
const pair = ctx && ctx.mapAsMap ? new Map() : {};
|
|
21
29
|
return addPairToJSMap.addPairToJSMap(ctx, pair, this);
|
package/dist/options.d.ts
CHANGED
|
@@ -105,6 +105,13 @@ export declare type SchemaOptions = {
|
|
|
105
105
|
sortMapEntries?: boolean | ((a: Pair, b: Pair) => number);
|
|
106
106
|
};
|
|
107
107
|
export declare type CreateNodeOptions = {
|
|
108
|
+
/**
|
|
109
|
+
* During node construction, use anchors and aliases to keep strictly equal
|
|
110
|
+
* non-null objects as equivalent in YAML.
|
|
111
|
+
*
|
|
112
|
+
* Default: `true`
|
|
113
|
+
*/
|
|
114
|
+
aliasDuplicateObjects?: boolean;
|
|
108
115
|
/**
|
|
109
116
|
* Default prefix for anchors.
|
|
110
117
|
*
|
package/dist/parse/lexer.d.ts
CHANGED
|
@@ -47,6 +47,8 @@ export declare class Lexer {
|
|
|
47
47
|
private indentNext;
|
|
48
48
|
/** Indentation level of the current line. */
|
|
49
49
|
private indentValue;
|
|
50
|
+
/** Position of the next \n character. */
|
|
51
|
+
private lineEndPos;
|
|
50
52
|
/** Stores the state of the lexer if reaching the end of incpomplete input */
|
|
51
53
|
private next;
|
|
52
54
|
/** A pointer to `buffer`; the current position of the lexer. */
|
package/dist/parse/lexer.js
CHANGED
|
@@ -136,6 +136,8 @@ class Lexer {
|
|
|
136
136
|
this.indentNext = 0;
|
|
137
137
|
/** Indentation level of the current line. */
|
|
138
138
|
this.indentValue = 0;
|
|
139
|
+
/** Position of the next \n character. */
|
|
140
|
+
this.lineEndPos = null;
|
|
139
141
|
/** Stores the state of the lexer if reaching the end of incpomplete input */
|
|
140
142
|
this.next = null;
|
|
141
143
|
/** A pointer to `buffer`; the current position of the lexer. */
|
|
@@ -148,8 +150,10 @@ class Lexer {
|
|
|
148
150
|
* @returns A generator of lexical tokens
|
|
149
151
|
*/
|
|
150
152
|
*lex(source, incomplete = false) {
|
|
151
|
-
if (source)
|
|
153
|
+
if (source) {
|
|
152
154
|
this.buffer = this.buffer ? this.buffer + source : source;
|
|
155
|
+
this.lineEndPos = null;
|
|
156
|
+
}
|
|
153
157
|
this.atEnd = !incomplete;
|
|
154
158
|
let next = this.next || 'stream';
|
|
155
159
|
while (next && (incomplete || this.hasChars(1)))
|
|
@@ -192,7 +196,11 @@ class Lexer {
|
|
|
192
196
|
return offset;
|
|
193
197
|
}
|
|
194
198
|
getLine() {
|
|
195
|
-
let end = this.
|
|
199
|
+
let end = this.lineEndPos;
|
|
200
|
+
if (typeof end !== 'number' || (end !== -1 && end < this.pos)) {
|
|
201
|
+
end = this.buffer.indexOf('\n', this.pos);
|
|
202
|
+
this.lineEndPos = end;
|
|
203
|
+
}
|
|
196
204
|
if (end === -1)
|
|
197
205
|
return this.atEnd ? this.buffer.substring(this.pos) : null;
|
|
198
206
|
if (this.buffer[end - 1] === '\r')
|
|
@@ -205,6 +213,7 @@ class Lexer {
|
|
|
205
213
|
setNext(state) {
|
|
206
214
|
this.buffer = this.buffer.substring(this.pos);
|
|
207
215
|
this.pos = 0;
|
|
216
|
+
this.lineEndPos = null;
|
|
208
217
|
this.next = state;
|
|
209
218
|
return null;
|
|
210
219
|
}
|
|
@@ -435,17 +444,19 @@ class Lexer {
|
|
|
435
444
|
end = this.buffer.indexOf('"', end + 1);
|
|
436
445
|
}
|
|
437
446
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
447
|
+
// Only looking for newlines within the quotes
|
|
448
|
+
const qb = this.buffer.substring(0, end);
|
|
449
|
+
let nl = qb.indexOf('\n', this.pos);
|
|
450
|
+
if (nl !== -1) {
|
|
451
|
+
while (nl !== -1) {
|
|
441
452
|
const cs = this.continueScalar(nl + 1);
|
|
442
453
|
if (cs === -1)
|
|
443
454
|
break;
|
|
444
|
-
nl =
|
|
455
|
+
nl = qb.indexOf('\n', cs);
|
|
445
456
|
}
|
|
446
|
-
if (nl !== -1
|
|
457
|
+
if (nl !== -1) {
|
|
447
458
|
// this is an error caused by an unexpected unindent
|
|
448
|
-
end = nl - 1;
|
|
459
|
+
end = nl - (qb[nl - 1] === '\r' ? 2 : 1);
|
|
449
460
|
}
|
|
450
461
|
}
|
|
451
462
|
if (end === -1) {
|
|
@@ -545,17 +556,18 @@ class Lexer {
|
|
|
545
556
|
end = i;
|
|
546
557
|
}
|
|
547
558
|
else if (isEmpty(ch)) {
|
|
548
|
-
|
|
549
|
-
if (next === '#' || (inFlow && invalidFlowScalarChars.includes(next)))
|
|
550
|
-
break;
|
|
559
|
+
let next = this.buffer[i + 1];
|
|
551
560
|
if (ch === '\r') {
|
|
552
561
|
if (next === '\n') {
|
|
553
562
|
i += 1;
|
|
554
563
|
ch = '\n';
|
|
564
|
+
next = this.buffer[i + 1];
|
|
555
565
|
}
|
|
556
566
|
else
|
|
557
567
|
end = i;
|
|
558
568
|
}
|
|
569
|
+
if (next === '#' || (inFlow && invalidFlowScalarChars.includes(next)))
|
|
570
|
+
break;
|
|
559
571
|
if (ch === '\n') {
|
|
560
572
|
const cs = this.continueScalar(i + 1);
|
|
561
573
|
if (cs === -1)
|
package/dist/schema/Schema.d.ts
CHANGED
package/dist/schema/Schema.js
CHANGED
|
@@ -20,6 +20,11 @@ class Schema {
|
|
|
20
20
|
this.sortMapEntries =
|
|
21
21
|
sortMapEntries === true ? sortMapEntriesByKey : sortMapEntries || null;
|
|
22
22
|
}
|
|
23
|
+
clone() {
|
|
24
|
+
const copy = Object.create(Schema.prototype, Object.getOwnPropertyDescriptors(this));
|
|
25
|
+
copy.tags = this.tags.slice();
|
|
26
|
+
return copy;
|
|
27
|
+
}
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
exports.Schema = Schema;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yaml",
|
|
3
|
-
"version": "2.0.0-
|
|
3
|
+
"version": "2.0.0-8",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"author": "Eemeli Aro <eemeli@gmail.com>",
|
|
6
6
|
"repository": "github:eemeli/yaml",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"@rollup/plugin-babel": "^5.2.3",
|
|
71
71
|
"@rollup/plugin-replace": "^2.3.4",
|
|
72
72
|
"@rollup/plugin-typescript": "^8.1.1",
|
|
73
|
-
"@types/jest": "^
|
|
73
|
+
"@types/jest": "^27.0.1",
|
|
74
74
|
"@types/node": "^15.6.1",
|
|
75
75
|
"@typescript-eslint/eslint-plugin": "^4.15.2",
|
|
76
76
|
"@typescript-eslint/parser": "^4.15.2",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"prettier": "^2.2.1",
|
|
85
85
|
"rollup": "^2.38.2",
|
|
86
86
|
"tslib": "^2.1.0",
|
|
87
|
-
"typescript": "^4.
|
|
87
|
+
"typescript": "^4.3.5"
|
|
88
88
|
},
|
|
89
89
|
"engines": {
|
|
90
90
|
"node": ">= 12"
|