UNPKG

@controlplane/cli

Version:

Control Plane Corporation CLI

143 lines 4.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.makePatch = void 0; const UrlPattern = require("url-pattern"); const _ = require("lodash"); /* { path: 'spec.containers.<name>.memory', }, { path: 'spec.containers.<name>.env.<key>', }, */ function makePatch(paths, expr, ctx) { const patch = {}; const matchers = paths.map((p) => { const url = p.path .replace(/\./g, '/') .replace(/<name>/g, ':name') .replace(/<key>/g, ':key'); return { orig: p, asUrl: url, pattern: new UrlPattern(url), }; }); for (let e of expr) { let op = ''; let selector = ''; let value = ''; let parsed = false; let i = e.indexOf('+='); if (!parsed && i >= 0) { parsed = true; op = '+='; selector = e.substring(0, i); value = e.substring(i + 2); } i = e.indexOf('-='); if (!parsed && i >= 0) { parsed = true; op = '-='; selector = e.substring(0, i); value = e.substring(i + 2); } i = e.indexOf('='); if (!parsed && i >= 0) { parsed = true; op = '='; selector = e.substring(0, i); value = e.substring(i + 1); if (value === 'null') { value = null; } } if (!parsed) { throw new Error(`Cannot parse <${e}>: missing operator =, -= or +=`); } const asUrl = selector.replace(/\./g, '/'); let matched = false; for (let m of matchers) { if (!m.pattern.match(asUrl)) { continue; } // resolve link if (m.orig.itemLinkResolver) { value = m.orig.itemLinkResolver.resourceLink(value, ctx); } if (!m.orig.array && op != '=') { throw new Error(`Cannot parse <${e}>. ${op} is supported only for arrays and <${m.orig.path}> is not`); } accumulatePatch(patch, m.orig, selector, op, value); matched = true; // first match is ok as the paths are assumed unique break; } if (!matched) { throw new Error(`Cannot parse <${e}>. <${selector}> is not valid updatable path`); } } return patch; } exports.makePatch = makePatch; function accumulatePatch(res, p, selector, op, value) { var _a, _b; let current = res; const templateSegments = p.path.split('.'); const selectorSegments = selector.split('.'); for (let i = 0; i < templateSegments.length; i++) { const seg = templateSegments[i]; const isLast = i == templateSegments.length - 1; const nextSeg = templateSegments[i + 1]; const nextSel = selectorSegments[i + 1]; if (nextSeg == '<name>') { const key = '$patch/' + selectorSegments[i]; // navigate current[key] = (_a = current[key]) !== null && _a !== void 0 ? _a : []; let found = _.find(current[key], (x) => x.name === nextSel); if (!found) { found = { name: nextSel, }; current[key].push(found); } current = found; } else if (seg == '<key>') { const key = selectorSegments[i]; // TODO key only at terminal position?? current[key] = value; } else if (seg == '<name>') { if (isLast) { throw new Error(`Bad updateble path detected: ${p.path}`); } continue; } else { if (isLast) { if (op == '+=') { current['$append/' + seg] = [value]; } else if (op == '-=') { current['$drop/' + seg] = [value]; } else { if (p.array) { current[seg] = value.split(','); } else { current[seg] = value; } } } else { // navigate current[seg] = (_b = current[seg]) !== null && _b !== void 0 ? _b : {}; current = current[seg]; } } } } //# sourceMappingURL=update.js.map