UNPKG

aws-ddk-core

Version:

The AWS DataOps Development Kit is an open source development framework for customers that build data workflows and modern data architecture on AWS.

148 lines (144 loc) 5.11 kB
'use strict'; var stringifyCollection = require('../stringify/stringifyCollection.js'); var addPairToJSMap = require('./addPairToJSMap.js'); var Collection = require('./Collection.js'); var identity = require('./identity.js'); var Pair = require('./Pair.js'); var Scalar = require('./Scalar.js'); function findPair(items, key) { const k = identity.isScalar(key) ? key.value : key; for (const it of items) { if (identity.isPair(it)) { if (it.key === key || it.key === k) return it; if (identity.isScalar(it.key) && it.key.value === k) return it; } } return undefined; } class YAMLMap extends Collection.Collection { static get tagName() { return 'tag:yaml.org,2002:map'; } constructor(schema) { super(identity.MAP, schema); this.items = []; } /** * A generic collection parsing method that can be extended * to other node classes that inherit from YAMLMap */ static from(schema, obj, ctx) { const { keepUndefined, replacer } = ctx; const map = new this(schema); const add = (key, value) => { if (typeof replacer === 'function') value = replacer.call(obj, key, value); else if (Array.isArray(replacer) && !replacer.includes(key)) return; if (value !== undefined || keepUndefined) map.items.push(Pair.createPair(key, value, ctx)); }; if (obj instanceof Map) { for (const [key, value] of obj) add(key, value); } else if (obj && typeof obj === 'object') { for (const key of Object.keys(obj)) add(key, obj[key]); } if (typeof schema.sortMapEntries === 'function') { map.items.sort(schema.sortMapEntries); } return map; } /** * Adds a value to the collection. * * @param overwrite - If not set `true`, using a key that is already in the * collection will throw. Otherwise, overwrites the previous value. */ add(pair, overwrite) { let _pair; if (identity.isPair(pair)) _pair = pair; else if (!pair || typeof pair !== 'object' || !('key' in pair)) { // In TypeScript, this never happens. _pair = new Pair.Pair(pair, pair?.value); } else _pair = new Pair.Pair(pair.key, pair.value); const prev = findPair(this.items, _pair.key); const sortEntries = this.schema?.sortMapEntries; if (prev) { if (!overwrite) throw new Error(`Key ${_pair.key} already set`); // For scalars, keep the old node & its comments and anchors if (identity.isScalar(prev.value) && Scalar.isScalarValue(_pair.value)) prev.value.value = _pair.value; else prev.value = _pair.value; } else if (sortEntries) { const i = this.items.findIndex(item => sortEntries(_pair, item) < 0); if (i === -1) this.items.push(_pair); else this.items.splice(i, 0, _pair); } else { this.items.push(_pair); } } delete(key) { const it = findPair(this.items, key); if (!it) return false; const del = this.items.splice(this.items.indexOf(it), 1); return del.length > 0; } get(key, keepScalar) { const it = findPair(this.items, key); const node = it?.value; return (!keepScalar && identity.isScalar(node) ? node.value : node) ?? undefined; } has(key) { return !!findPair(this.items, key); } set(key, value) { this.add(new Pair.Pair(key, value), true); } /** * @param ctx - Conversion context, originally set in Document#toJS() * @param {Class} Type - If set, forces the returned collection type * @returns Instance of Type, Map, or Object */ toJSON(_, ctx, Type) { const map = Type ? new Type() : ctx?.mapAsMap ? new Map() : {}; if (ctx?.onCreate) ctx.onCreate(map); for (const item of this.items) addPairToJSMap.addPairToJSMap(ctx, map, item); return map; } toString(ctx, onComment, onChompKeep) { if (!ctx) return JSON.stringify(this); for (const item of this.items) { if (!identity.isPair(item)) throw new Error(`Map items must all be pairs; found ${JSON.stringify(item)} instead`); } if (!ctx.allNullValues && this.hasAllNullValues(false)) ctx = Object.assign({}, ctx, { allNullValues: true }); return stringifyCollection.stringifyCollection(this, ctx, { blockItemPrefix: '', flowChars: { start: '{', end: '}' }, itemIndent: ctx.indent || '', onChompKeep, onComment }); } } exports.YAMLMap = YAMLMap; exports.findPair = findPair;