1 | 'use strict';
|
2 |
|
3 | var createNode = require('../doc/createNode.js');
|
4 | var identity = require('./identity.js');
|
5 | var Node = require('./Node.js');
|
6 |
|
7 | function collectionFromPath(schema, path, value) {
|
8 | let v = value;
|
9 | for (let i = path.length - 1; i >= 0; --i) {
|
10 | const k = path[i];
|
11 | if (typeof k === 'number' && Number.isInteger(k) && k >= 0) {
|
12 | const a = [];
|
13 | a[k] = v;
|
14 | v = a;
|
15 | }
|
16 | else {
|
17 | v = new Map([[k, v]]);
|
18 | }
|
19 | }
|
20 | return createNode.createNode(v, undefined, {
|
21 | aliasDuplicateObjects: false,
|
22 | keepUndefined: false,
|
23 | onAnchor: () => {
|
24 | throw new Error('This should not happen, please report a bug.');
|
25 | },
|
26 | schema,
|
27 | sourceObjects: new Map()
|
28 | });
|
29 | }
|
30 |
|
31 |
|
32 | const isEmptyPath = (path) => path == null ||
|
33 | (typeof path === 'object' && !!path[Symbol.iterator]().next().done);
|
34 | class Collection extends Node.NodeBase {
|
35 | constructor(type, schema) {
|
36 | super(type);
|
37 | Object.defineProperty(this, 'schema', {
|
38 | value: schema,
|
39 | configurable: true,
|
40 | enumerable: false,
|
41 | writable: true
|
42 | });
|
43 | }
|
44 | |
45 |
|
46 |
|
47 |
|
48 |
|
49 | clone(schema) {
|
50 | const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));
|
51 | if (schema)
|
52 | copy.schema = schema;
|
53 | copy.items = copy.items.map(it => identity.isNode(it) || identity.isPair(it) ? it.clone(schema) : it);
|
54 | if (this.range)
|
55 | copy.range = this.range.slice();
|
56 | return copy;
|
57 | }
|
58 | |
59 |
|
60 |
|
61 |
|
62 |
|
63 | addIn(path, value) {
|
64 | if (isEmptyPath(path))
|
65 | this.add(value);
|
66 | else {
|
67 | const [key, ...rest] = path;
|
68 | const node = this.get(key, true);
|
69 | if (identity.isCollection(node))
|
70 | node.addIn(rest, value);
|
71 | else if (node === undefined && this.schema)
|
72 | this.set(key, collectionFromPath(this.schema, rest, value));
|
73 | else
|
74 | throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
|
75 | }
|
76 | }
|
77 | |
78 |
|
79 |
|
80 |
|
81 | deleteIn(path) {
|
82 | const [key, ...rest] = path;
|
83 | if (rest.length === 0)
|
84 | return this.delete(key);
|
85 | const node = this.get(key, true);
|
86 | if (identity.isCollection(node))
|
87 | return node.deleteIn(rest);
|
88 | else
|
89 | throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
|
90 | }
|
91 | |
92 |
|
93 |
|
94 |
|
95 |
|
96 | getIn(path, keepScalar) {
|
97 | const [key, ...rest] = path;
|
98 | const node = this.get(key, true);
|
99 | if (rest.length === 0)
|
100 | return !keepScalar && identity.isScalar(node) ? node.value : node;
|
101 | else
|
102 | return identity.isCollection(node) ? node.getIn(rest, keepScalar) : undefined;
|
103 | }
|
104 | hasAllNullValues(allowScalar) {
|
105 | return this.items.every(node => {
|
106 | if (!identity.isPair(node))
|
107 | return false;
|
108 | const n = node.value;
|
109 | return (n == null ||
|
110 | (allowScalar &&
|
111 | identity.isScalar(n) &&
|
112 | n.value == null &&
|
113 | !n.commentBefore &&
|
114 | !n.comment &&
|
115 | !n.tag));
|
116 | });
|
117 | }
|
118 | |
119 |
|
120 |
|
121 | hasIn(path) {
|
122 | const [key, ...rest] = path;
|
123 | if (rest.length === 0)
|
124 | return this.has(key);
|
125 | const node = this.get(key, true);
|
126 | return identity.isCollection(node) ? node.hasIn(rest) : false;
|
127 | }
|
128 | |
129 |
|
130 |
|
131 |
|
132 | setIn(path, value) {
|
133 | const [key, ...rest] = path;
|
134 | if (rest.length === 0) {
|
135 | this.set(key, value);
|
136 | }
|
137 | else {
|
138 | const node = this.get(key, true);
|
139 | if (identity.isCollection(node))
|
140 | node.setIn(rest, value);
|
141 | else if (node === undefined && this.schema)
|
142 | this.set(key, collectionFromPath(this.schema, rest, value));
|
143 | else
|
144 | throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
|
145 | }
|
146 | }
|
147 | }
|
148 |
|
149 | exports.Collection = Collection;
|
150 | exports.collectionFromPath = collectionFromPath;
|
151 | exports.isEmptyPath = isEmptyPath;
|