UNPKG

ut-tools

Version:

Build and Release management automation package.

147 lines (111 loc) 2.88 kB
import isObject from '../../runtime/codegen-functions/is-object.mjs'; import { variableDeclaration, variableDeclarator, identifier } from '../ast/builders.mjs'; import buildJson from '../templates/build-json.mjs'; class TraversalZones { #isDestroyed = false; #zones = []; get root() { if (this.#isDestroyed || this.#zones.length === 0) { return null; } const zonesIdentifier = identifier('zones'); return variableDeclaration('const', [variableDeclarator(zonesIdentifier, buildJson(mergeZones(this.#zones)))]); } destroy() { this.#isDestroyed = true; } attach(zone) { this.#zones.push(zone); } create() { if (this.#isDestroyed) { return null; } return new Zone(this); } } class Zone { #zones; #localZones; #relationships; constructor(zones) { this.#zones = zones; this.root = {}; this.#localZones = [this.root]; this.#relationships = new Map(); } attach() { this.#zones.attach(this.root); this.#relationships.clear(); } expand(property) { let i = 0; for (const value of this.#localZones) { if (value === null) continue; if (property === '**') { const parent = this.#relationships.get(value); if (parent !== void 0 && '*' in parent) { delete parent['*']; parent['**'] = null; continue; } value[property] = null; } else { value[property] = {}; this.#relationships.set(value[property], value); } this.#localZones[i++] = value[property]; } return this; } expandMultiple(properties) { const root = this.#localZones[0]; if (root === null) { return this; } let i = 0; for (const property of properties) { root[property] = property === '**' ? null : {}; if (this.#localZones.length < i) { this.#localZones.push(root[property]); } else { this.#localZones[i++] = root[property]; } } return this; } resize() { return this.expand('*'); } allIn() { return this.expand('**'); } } function pullAll(target) { return Object.keys(target).reduce((obj, key) => Object.assign(obj, target[key]), {}); } function _mergeZones(target, source) { if ('*' in source) { const pulled = pullAll(target); _mergeZones(pulled, pullAll(source)); target['*'] = '*' in pulled ? { '*': pulled['*'] } : pulled; } else { for (const key of Object.keys(source)) { if (!(key in target)) { target[key] = source[key]; } else if (isObject(source[key])) { _mergeZones(target[key], source[key]); } } } } function mergeZones(zones) { const target = zones[0]; for (let i = 1; i < zones.length; i++) { _mergeZones(target, zones[i]); } return target; } export { TraversalZones as default };