| ; | |
| var createNode = require('../doc/createNode.js'); | |
| var identity = require('./identity.js'); | |
| var Node = require('./Node.js'); | |
| function collectionFromPath(schema, path, value) { | |
| let v = value; | |
| for (let i = path.length - 1; i >= 0; --i) { | |
| const k = path[i]; | |
| if (typeof k === 'number' && Number.isInteger(k) && k >= 0) { | |
| const a = []; | |
| a[k] = v; | |
| v = a; | |
| } | |
| else { | |
| v = new Map([[k, v]]); | |
| } | |
| } | |
| return createNode.createNode(v, undefined, { | |
| aliasDuplicateObjects: false, | |
| keepUndefined: false, | |
| onAnchor: () => { | |
| throw new Error('This should not happen, please report a bug.'); | |
| }, | |
| schema, | |
| sourceObjects: new Map() | |
| }); | |
| } | |
| // Type guard is intentionally a little wrong so as to be more useful, | |
| // as it does not cover untypable empty non-string iterables (e.g. []). | |
| const isEmptyPath = (path) => path == null || | |
| (typeof path === 'object' && !!path[Symbol.iterator]().next().done); | |
| class Collection extends Node.NodeBase { | |
| constructor(type, schema) { | |
| super(type); | |
| Object.defineProperty(this, 'schema', { | |
| value: schema, | |
| configurable: true, | |
| enumerable: false, | |
| writable: true | |
| }); | |
| } | |
| /** | |
| * Create a copy of this collection. | |
| * | |
| * @param schema - If defined, overwrites the original's schema | |
| */ | |
| clone(schema) { | |
| const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this)); | |
| if (schema) | |
| copy.schema = schema; | |
| copy.items = copy.items.map(it => identity.isNode(it) || identity.isPair(it) ? it.clone(schema) : it); | |
| if (this.range) | |
| copy.range = this.range.slice(); | |
| return copy; | |
| } | |
| /** | |
| * Adds a value to the collection. For `!!map` and `!!omap` the value must | |
| * be a Pair instance or a `{ key, value }` object, which may not have a key | |
| * that already exists in the map. | |
| */ | |
| addIn(path, value) { | |
| if (isEmptyPath(path)) | |
| this.add(value); | |
| else { | |
| const [key, ...rest] = path; | |
| const node = this.get(key, true); | |
| if (identity.isCollection(node)) | |
| node.addIn(rest, value); | |
| else if (node === undefined && this.schema) | |
| this.set(key, collectionFromPath(this.schema, rest, value)); | |
| else | |
| throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`); | |
| } | |
| } | |
| /** | |
| * Removes a value from the collection. | |
| * @returns `true` if the item was found and removed. | |
| */ | |
| deleteIn(path) { | |
| const [key, ...rest] = path; | |
| if (rest.length === 0) | |
| return this.delete(key); | |
| const node = this.get(key, true); | |
| if (identity.isCollection(node)) | |
| return node.deleteIn(rest); | |
| else | |
| throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`); | |
| } | |
| /** | |
| * Returns item at `key`, or `undefined` if not found. By default unwraps | |
| * scalar values from their surrounding node; to disable set `keepScalar` to | |
| * `true` (collections are always returned intact). | |
| */ | |
| getIn(path, keepScalar) { | |
| const [key, ...rest] = path; | |
| const node = this.get(key, true); | |
| if (rest.length === 0) | |
| return !keepScalar && identity.isScalar(node) ? node.value : node; | |
| else | |
| return identity.isCollection(node) ? node.getIn(rest, keepScalar) : undefined; | |
| } | |
| hasAllNullValues(allowScalar) { | |
| return this.items.every(node => { | |
| if (!identity.isPair(node)) | |
| return false; | |
| const n = node.value; | |
| return (n == null || | |
| (allowScalar && | |
| identity.isScalar(n) && | |
| n.value == null && | |
| !n.commentBefore && | |
| !n.comment && | |
| !n.tag)); | |
| }); | |
| } | |
| /** | |
| * Checks if the collection includes a value with the key `key`. | |
| */ | |
| hasIn(path) { | |
| const [key, ...rest] = path; | |
| if (rest.length === 0) | |
| return this.has(key); | |
| const node = this.get(key, true); | |
| return identity.isCollection(node) ? node.hasIn(rest) : false; | |
| } | |
| /** | |
| * Sets a value in this collection. For `!!set`, `value` needs to be a | |
| * boolean to add/remove the item from the set. | |
| */ | |
| setIn(path, value) { | |
| const [key, ...rest] = path; | |
| if (rest.length === 0) { | |
| this.set(key, value); | |
| } | |
| else { | |
| const node = this.get(key, true); | |
| if (identity.isCollection(node)) | |
| node.setIn(rest, value); | |
| else if (node === undefined && this.schema) | |
| this.set(key, collectionFromPath(this.schema, rest, value)); | |
| else | |
| throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`); | |
| } | |
| } | |
| } | |
| exports.Collection = Collection; | |
| exports.collectionFromPath = collectionFromPath; | |
| exports.isEmptyPath = isEmptyPath; | |
Xet Storage Details
- Size:
- 5.22 kB
- Xet hash:
- 540e346d0bdfa0d9453481416398d2c2e64e16b6eb166dad5a0c2d27b01d7f97
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.