@pipeline-builder/pipeline-core 3.1.4 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ // Copyright 2026 Pipeline Builder Contributors
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.allowedScopeRoots = allowedScopeRoots;
6
+ exports.validateTemplates = validateTemplates;
7
+ exports.detectCycles = detectCycles;
8
+ const api_core_1 = require("@pipeline-builder/api-core");
9
+ const evaluator_1 = require("./evaluator");
10
+ const tokenizer_1 = require("./tokenizer");
11
+ const topo_sort_1 = require("./topo-sort");
12
+ const walker_1 = require("./walker");
13
+ /**
14
+ * Build a predicate that accepts a template path when its root is in the
15
+ * given allow-list. Used by the validator to check that every `{{ path }}`
16
+ * resolves to a known scope root (`pipeline`, `plugin`, `env`, …).
17
+ *
18
+ * Only the root segment is checked — we don't enforce exact nested-key
19
+ * existence here because metadata / vars keys are user-provided per pipeline
20
+ * and not known at plugin upload time.
21
+ */
22
+ function allowedScopeRoots(roots) {
23
+ const allowed = new Set(roots);
24
+ return (path) => {
25
+ const root = path[0];
26
+ return !!root && allowed.has(root);
27
+ };
28
+ }
29
+ /**
30
+ * Validate all template tokens in a document have well-formed paths and
31
+ * point at allowed scope roots. Returns all errors found — does NOT stop
32
+ * on first.
33
+ *
34
+ * Caller supplies `isTemplatable` (the schema allow-list) and
35
+ * `isKnownPath` (the scope-shape predicate). Template text is parsed
36
+ * fresh; use a TokenCache externally if repeated parsing is a concern.
37
+ */
38
+ function validateTemplates(doc, isTemplatable, isKnownPath) {
39
+ const errors = [];
40
+ const entries = [];
41
+ // Pass 1: parse every templatable field, collecting parse errors instead
42
+ // of throwing on the first one.
43
+ (0, walker_1.visitStrings)(doc, isTemplatable, (field, source) => {
44
+ try {
45
+ entries.push({ field, tokens: (0, tokenizer_1.tokenize)(source) });
46
+ }
47
+ catch (err) {
48
+ if (err instanceof tokenizer_1.TokenizerError) {
49
+ errors.push({ field, line: err.pos.line, col: err.pos.col, code: api_core_1.ErrorCode.TEMPLATE_PARSE_ERROR, message: err.message });
50
+ }
51
+ else {
52
+ errors.push({ field, code: api_core_1.ErrorCode.TEMPLATE_PARSE_ERROR, message: String(err) });
53
+ }
54
+ }
55
+ });
56
+ // Pass 2: validate each expr's path is shape-allowed and not reserved
57
+ for (const { field, tokens } of entries) {
58
+ for (const tok of tokens) {
59
+ if (tok.kind !== 'expr')
60
+ continue;
61
+ if (tok.path[0] === 'secrets') {
62
+ errors.push(mkErr(field, tok.pos, api_core_1.ErrorCode.TEMPLATE_SECRETS_RESERVED, '\'secrets\' is a reserved scope — use the plugin\'s \'secrets:\' field instead', tok.path.join('.')));
63
+ continue;
64
+ }
65
+ if (!isKnownPath(tok.path)) {
66
+ errors.push(mkErr(field, tok.pos, api_core_1.ErrorCode.TEMPLATE_UNKNOWN_PATH, `Template references unknown scope root '${tok.path[0]}'`, tok.path.join('.')));
67
+ }
68
+ }
69
+ }
70
+ return { valid: errors.length === 0, errors };
71
+ }
72
+ /**
73
+ * Detect cycles in a self-referencing document. Caller supplies the
74
+ * templatable predicate and a function to extract the scope-path that
75
+ * each template field writes to (same value used as a key in deps).
76
+ *
77
+ * Example for pipeline.json: the field `metadata.env` writes to scope
78
+ * path `metadata.env`; a template `{{ metadata.region }}` in that field
79
+ * declares a dependency on `metadata.region`.
80
+ */
81
+ function detectCycles(doc, isTemplatable, fieldToScopePath) {
82
+ const nodes = [];
83
+ for (const entry of (0, walker_1.walkAndBind)(doc, isTemplatable)) {
84
+ const key = fieldToScopePath(entry.field);
85
+ if (!key)
86
+ continue;
87
+ nodes.push({ key, deps: (0, evaluator_1.dependencies)(entry.tokens) });
88
+ }
89
+ const { cycles } = (0, topo_sort_1.topoSort)(nodes);
90
+ return cycles.map(c => ({
91
+ field: c[0],
92
+ code: api_core_1.ErrorCode.TEMPLATE_CYCLE,
93
+ message: `Template cycle detected: ${c.join(' -> ')}`,
94
+ cycle: c,
95
+ }));
96
+ }
97
+ // -- helpers -----------------------------------------------------------------
98
+ function mkErr(field, pos, code, message, path) {
99
+ return { field, line: pos.line, col: pos.col, code, message, ...(path && { path }) };
100
+ }
101
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVtcGxhdGUvdmFsaWRhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7O0FBZ0N0Qyw4Q0FNQztBQVdELDhDQXlDQztBQVdELG9DQWtCQztBQXJIRCx5REFBdUQ7QUFDdkQsMkNBQTJDO0FBQzNDLDJDQUE4RTtBQUM5RSwyQ0FBdUM7QUFDdkMscUNBQXFFO0FBaUJyRTs7Ozs7Ozs7R0FRRztBQUNILFNBQWdCLGlCQUFpQixDQUFDLEtBQWU7SUFDL0MsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFO1FBQ2QsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLE9BQU8sQ0FBQyxDQUFDLElBQUksSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3JDLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQWdCLGlCQUFpQixDQUMvQixHQUFNLEVBQ04sYUFBNkIsRUFDN0IsV0FBd0M7SUFFeEMsTUFBTSxNQUFNLEdBQW9CLEVBQUUsQ0FBQztJQUNuQyxNQUFNLE9BQU8sR0FBeUMsRUFBRSxDQUFDO0lBRXpELHlFQUF5RTtJQUN6RSxnQ0FBZ0M7SUFDaEMsSUFBQSxxQkFBWSxFQUFDLEdBQUcsRUFBRSxhQUFhLEVBQUUsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDakQsSUFBSSxDQUFDO1lBQ0gsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBQSxvQkFBUSxFQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwRCxDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNiLElBQUksR0FBRyxZQUFZLDBCQUFjLEVBQUUsQ0FBQztnQkFDbEMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxvQkFBUyxDQUFDLG9CQUFvQixFQUFFLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUMzSCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsb0JBQVMsQ0FBQyxvQkFBb0IsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNyRixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUgsc0VBQXNFO0lBQ3RFLEtBQUssTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUN4QyxLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ3pCLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxNQUFNO2dCQUFFLFNBQVM7WUFDbEMsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUM5QixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxvQkFBUyxDQUFDLHlCQUF5QixFQUNuRSxnRkFBZ0YsRUFDaEYsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN2QixTQUFTO1lBQ1gsQ0FBQztZQUNELElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQzNCLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLG9CQUFTLENBQUMscUJBQXFCLEVBQy9ELDJDQUEyQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQ3pELEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN6QixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDO0FBQ2hELENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQWdCLFlBQVksQ0FDMUIsR0FBTSxFQUNOLGFBQTZCLEVBQzdCLGdCQUFrRDtJQUVsRCxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7SUFDakIsS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFBLG9CQUFXLEVBQUMsR0FBRyxFQUFFLGFBQWEsQ0FBQyxFQUFFLENBQUM7UUFDcEQsTUFBTSxHQUFHLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxHQUFHO1lBQUUsU0FBUztRQUNuQixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFBLHdCQUFZLEVBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBQ0QsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLElBQUEsb0JBQVEsRUFBQyxLQUFLLENBQUMsQ0FBQztJQUNuQyxPQUFPLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3RCLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFFO1FBQ1osSUFBSSxFQUFFLG9CQUFTLENBQUMsY0FBYztRQUM5QixPQUFPLEVBQUUsNEJBQTRCLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUU7UUFDckQsS0FBSyxFQUFFLENBQUM7S0FDVCxDQUFDLENBQUMsQ0FBQztBQUNOLENBQUM7QUFFRCwrRUFBK0U7QUFFL0UsU0FBUyxLQUFLLENBQ1osS0FBYSxFQUNiLEdBQW1CLEVBQ25CLElBQWUsRUFDZixPQUFlLEVBQ2YsSUFBYTtJQUViLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO0FBQ3ZGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgRXJyb3JDb2RlIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgZGVwZW5kZW5jaWVzIH0gZnJvbSAnLi9ldmFsdWF0b3InO1xuaW1wb3J0IHsgU291cmNlUG9zaXRpb24sIFRva2VuLCBUb2tlbml6ZXJFcnJvciwgdG9rZW5pemUgfSBmcm9tICcuL3Rva2VuaXplcic7XG5pbXBvcnQgeyB0b3BvU29ydCB9IGZyb20gJy4vdG9wby1zb3J0JztcbmltcG9ydCB7IEZpZWxkUHJlZGljYXRlLCB2aXNpdFN0cmluZ3MsIHdhbGtBbmRCaW5kIH0gZnJvbSAnLi93YWxrZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRlbXBsYXRlRXJyb3Ige1xuICBmaWVsZDogc3RyaW5nO1xuICBsaW5lPzogbnVtYmVyO1xuICBjb2w/OiBudW1iZXI7XG4gIGNvZGU6IEVycm9yQ29kZTtcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBwYXRoPzogc3RyaW5nO1xuICBjeWNsZT86IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZhbGlkYXRpb25SZXN1bHQge1xuICB2YWxpZDogYm9vbGVhbjtcbiAgZXJyb3JzOiBUZW1wbGF0ZUVycm9yW107XG59XG5cbi8qKlxuICogQnVpbGQgYSBwcmVkaWNhdGUgdGhhdCBhY2NlcHRzIGEgdGVtcGxhdGUgcGF0aCB3aGVuIGl0cyByb290IGlzIGluIHRoZVxuICogZ2l2ZW4gYWxsb3ctbGlzdC4gVXNlZCBieSB0aGUgdmFsaWRhdG9yIHRvIGNoZWNrIHRoYXQgZXZlcnkgYHt7IHBhdGggfX1gXG4gKiByZXNvbHZlcyB0byBhIGtub3duIHNjb3BlIHJvb3QgKGBwaXBlbGluZWAsIGBwbHVnaW5gLCBgZW52YCwg4oCmKS5cbiAqXG4gKiBPbmx5IHRoZSByb290IHNlZ21lbnQgaXMgY2hlY2tlZCDigJQgd2UgZG9uJ3QgZW5mb3JjZSBleGFjdCBuZXN0ZWQta2V5XG4gKiBleGlzdGVuY2UgaGVyZSBiZWNhdXNlIG1ldGFkYXRhIC8gdmFycyBrZXlzIGFyZSB1c2VyLXByb3ZpZGVkIHBlciBwaXBlbGluZVxuICogYW5kIG5vdCBrbm93biBhdCBwbHVnaW4gdXBsb2FkIHRpbWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbGxvd2VkU2NvcGVSb290cyhyb290czogc3RyaW5nW10pOiAocGF0aDogc3RyaW5nW10pID0+IGJvb2xlYW4ge1xuICBjb25zdCBhbGxvd2VkID0gbmV3IFNldChyb290cyk7XG4gIHJldHVybiAocGF0aCkgPT4ge1xuICAgIGNvbnN0IHJvb3QgPSBwYXRoWzBdO1xuICAgIHJldHVybiAhIXJvb3QgJiYgYWxsb3dlZC5oYXMocm9vdCk7XG4gIH07XG59XG5cbi8qKlxuICogVmFsaWRhdGUgYWxsIHRlbXBsYXRlIHRva2VucyBpbiBhIGRvY3VtZW50IGhhdmUgd2VsbC1mb3JtZWQgcGF0aHMgYW5kXG4gKiBwb2ludCBhdCBhbGxvd2VkIHNjb3BlIHJvb3RzLiBSZXR1cm5zIGFsbCBlcnJvcnMgZm91bmQg4oCUIGRvZXMgTk9UIHN0b3BcbiAqIG9uIGZpcnN0LlxuICpcbiAqIENhbGxlciBzdXBwbGllcyBgaXNUZW1wbGF0YWJsZWAgKHRoZSBzY2hlbWEgYWxsb3ctbGlzdCkgYW5kXG4gKiBgaXNLbm93blBhdGhgICh0aGUgc2NvcGUtc2hhcGUgcHJlZGljYXRlKS4gVGVtcGxhdGUgdGV4dCBpcyBwYXJzZWRcbiAqIGZyZXNoOyB1c2UgYSBUb2tlbkNhY2hlIGV4dGVybmFsbHkgaWYgcmVwZWF0ZWQgcGFyc2luZyBpcyBhIGNvbmNlcm4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVRlbXBsYXRlczxUIGV4dGVuZHMgb2JqZWN0PihcbiAgZG9jOiBULFxuICBpc1RlbXBsYXRhYmxlOiBGaWVsZFByZWRpY2F0ZSxcbiAgaXNLbm93blBhdGg6IChwYXRoOiBzdHJpbmdbXSkgPT4gYm9vbGVhbixcbik6IFZhbGlkYXRpb25SZXN1bHQge1xuICBjb25zdCBlcnJvcnM6IFRlbXBsYXRlRXJyb3JbXSA9IFtdO1xuICBjb25zdCBlbnRyaWVzOiB7IGZpZWxkOiBzdHJpbmc7IHRva2VuczogVG9rZW5bXSB9W10gPSBbXTtcblxuICAvLyBQYXNzIDE6IHBhcnNlIGV2ZXJ5IHRlbXBsYXRhYmxlIGZpZWxkLCBjb2xsZWN0aW5nIHBhcnNlIGVycm9ycyBpbnN0ZWFkXG4gIC8vIG9mIHRocm93aW5nIG9uIHRoZSBmaXJzdCBvbmUuXG4gIHZpc2l0U3RyaW5ncyhkb2MsIGlzVGVtcGxhdGFibGUsIChmaWVsZCwgc291cmNlKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGVudHJpZXMucHVzaCh7IGZpZWxkLCB0b2tlbnM6IHRva2VuaXplKHNvdXJjZSkgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoZXJyIGluc3RhbmNlb2YgVG9rZW5pemVyRXJyb3IpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goeyBmaWVsZCwgbGluZTogZXJyLnBvcy5saW5lLCBjb2w6IGVyci5wb3MuY29sLCBjb2RlOiBFcnJvckNvZGUuVEVNUExBVEVfUEFSU0VfRVJST1IsIG1lc3NhZ2U6IGVyci5tZXNzYWdlIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXJyb3JzLnB1c2goeyBmaWVsZCwgY29kZTogRXJyb3JDb2RlLlRFTVBMQVRFX1BBUlNFX0VSUk9SLCBtZXNzYWdlOiBTdHJpbmcoZXJyKSB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8vIFBhc3MgMjogdmFsaWRhdGUgZWFjaCBleHByJ3MgcGF0aCBpcyBzaGFwZS1hbGxvd2VkIGFuZCBub3QgcmVzZXJ2ZWRcbiAgZm9yIChjb25zdCB7IGZpZWxkLCB0b2tlbnMgfSBvZiBlbnRyaWVzKSB7XG4gICAgZm9yIChjb25zdCB0b2sgb2YgdG9rZW5zKSB7XG4gICAgICBpZiAodG9rLmtpbmQgIT09ICdleHByJykgY29udGludWU7XG4gICAgICBpZiAodG9rLnBhdGhbMF0gPT09ICdzZWNyZXRzJykge1xuICAgICAgICBlcnJvcnMucHVzaChta0VycihmaWVsZCwgdG9rLnBvcywgRXJyb3JDb2RlLlRFTVBMQVRFX1NFQ1JFVFNfUkVTRVJWRUQsXG4gICAgICAgICAgJ1xcJ3NlY3JldHNcXCcgaXMgYSByZXNlcnZlZCBzY29wZSDigJQgdXNlIHRoZSBwbHVnaW5cXCdzIFxcJ3NlY3JldHM6XFwnIGZpZWxkIGluc3RlYWQnLFxuICAgICAgICAgIHRvay5wYXRoLmpvaW4oJy4nKSkpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICghaXNLbm93blBhdGgodG9rLnBhdGgpKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKG1rRXJyKGZpZWxkLCB0b2sucG9zLCBFcnJvckNvZGUuVEVNUExBVEVfVU5LTk9XTl9QQVRILFxuICAgICAgICAgIGBUZW1wbGF0ZSByZWZlcmVuY2VzIHVua25vd24gc2NvcGUgcm9vdCAnJHt0b2sucGF0aFswXX0nYCxcbiAgICAgICAgICB0b2sucGF0aC5qb2luKCcuJykpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4geyB2YWxpZDogZXJyb3JzLmxlbmd0aCA9PT0gMCwgZXJyb3JzIH07XG59XG5cbi8qKlxuICogRGV0ZWN0IGN5Y2xlcyBpbiBhIHNlbGYtcmVmZXJlbmNpbmcgZG9jdW1lbnQuIENhbGxlciBzdXBwbGllcyB0aGVcbiAqIHRlbXBsYXRhYmxlIHByZWRpY2F0ZSBhbmQgYSBmdW5jdGlvbiB0byBleHRyYWN0IHRoZSBzY29wZS1wYXRoIHRoYXRcbiAqIGVhY2ggdGVtcGxhdGUgZmllbGQgd3JpdGVzIHRvIChzYW1lIHZhbHVlIHVzZWQgYXMgYSBrZXkgaW4gZGVwcykuXG4gKlxuICogRXhhbXBsZSBmb3IgcGlwZWxpbmUuanNvbjogdGhlIGZpZWxkIGBtZXRhZGF0YS5lbnZgIHdyaXRlcyB0byBzY29wZVxuICogcGF0aCBgbWV0YWRhdGEuZW52YDsgYSB0ZW1wbGF0ZSBge3sgbWV0YWRhdGEucmVnaW9uIH19YCBpbiB0aGF0IGZpZWxkXG4gKiBkZWNsYXJlcyBhIGRlcGVuZGVuY3kgb24gYG1ldGFkYXRhLnJlZ2lvbmAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXRlY3RDeWNsZXM8VCBleHRlbmRzIG9iamVjdD4oXG4gIGRvYzogVCxcbiAgaXNUZW1wbGF0YWJsZTogRmllbGRQcmVkaWNhdGUsXG4gIGZpZWxkVG9TY29wZVBhdGg6IChmaWVsZDogc3RyaW5nKSA9PiBzdHJpbmcgfCBudWxsLFxuKTogVGVtcGxhdGVFcnJvcltdIHtcbiAgY29uc3Qgbm9kZXMgPSBbXTtcbiAgZm9yIChjb25zdCBlbnRyeSBvZiB3YWxrQW5kQmluZChkb2MsIGlzVGVtcGxhdGFibGUpKSB7XG4gICAgY29uc3Qga2V5ID0gZmllbGRUb1Njb3BlUGF0aChlbnRyeS5maWVsZCk7XG4gICAgaWYgKCFrZXkpIGNvbnRpbnVlO1xuICAgIG5vZGVzLnB1c2goeyBrZXksIGRlcHM6IGRlcGVuZGVuY2llcyhlbnRyeS50b2tlbnMpIH0pO1xuICB9XG4gIGNvbnN0IHsgY3ljbGVzIH0gPSB0b3BvU29ydChub2Rlcyk7XG4gIHJldHVybiBjeWNsZXMubWFwKGMgPT4gKHtcbiAgICBmaWVsZDogY1swXSEsXG4gICAgY29kZTogRXJyb3JDb2RlLlRFTVBMQVRFX0NZQ0xFLFxuICAgIG1lc3NhZ2U6IGBUZW1wbGF0ZSBjeWNsZSBkZXRlY3RlZDogJHtjLmpvaW4oJyAtPiAnKX1gLFxuICAgIGN5Y2xlOiBjLFxuICB9KSk7XG59XG5cbi8vIC0tIGhlbHBlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuZnVuY3Rpb24gbWtFcnIoXG4gIGZpZWxkOiBzdHJpbmcsXG4gIHBvczogU291cmNlUG9zaXRpb24sXG4gIGNvZGU6IEVycm9yQ29kZSxcbiAgbWVzc2FnZTogc3RyaW5nLFxuICBwYXRoPzogc3RyaW5nLFxuKTogVGVtcGxhdGVFcnJvciB7XG4gIHJldHVybiB7IGZpZWxkLCBsaW5lOiBwb3MubGluZSwgY29sOiBwb3MuY29sLCBjb2RlLCBtZXNzYWdlLCAuLi4ocGF0aCAmJiB7IHBhdGggfSkgfTtcbn1cblxuIl19
@@ -0,0 +1,24 @@
1
+ import { Token } from './tokenizer';
2
+ export interface WalkEntry {
3
+ /** Dotted path to the field inside the document, e.g. 'commands[3]' or 'env.STAGE' */
4
+ field: string;
5
+ /** Raw source string containing template tokens */
6
+ source: string;
7
+ /** Parsed token stream */
8
+ tokens: Token[];
9
+ /** Setter to write back a resolved value into the original `root` object */
10
+ set: (value: unknown) => void;
11
+ }
12
+ export type FieldPredicate = (field: string) => boolean;
13
+ /**
14
+ * Visit every templatable string leaf under `root`. Calls `handler(field, source)`
15
+ * for each string whose field path satisfies `isTemplatable` and contains `{{`.
16
+ * Does NOT tokenize — callers decide whether to throw or collect errors.
17
+ */
18
+ export declare function visitStrings(root: unknown, isTemplatable: FieldPredicate, handler: (field: string, source: string) => void): void;
19
+ /**
20
+ * Walk all templatable string fields under `root`, returning one entry per
21
+ * templated field with a bound `set()` that mutates `root` in place.
22
+ * Tokenization happens eagerly here — parse errors throw.
23
+ */
24
+ export declare function walkAndBind<T extends object>(root: T, isTemplatable: FieldPredicate): WalkEntry[];
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ // Copyright 2026 Pipeline Builder Contributors
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.visitStrings = visitStrings;
6
+ exports.walkAndBind = walkAndBind;
7
+ const tokenizer_1 = require("./tokenizer");
8
+ /**
9
+ * Visit every templatable string leaf under `root`. Calls `handler(field, source)`
10
+ * for each string whose field path satisfies `isTemplatable` and contains `{{`.
11
+ * Does NOT tokenize — callers decide whether to throw or collect errors.
12
+ */
13
+ function visitStrings(root, isTemplatable, handler) {
14
+ step(root, '', isTemplatable, handler);
15
+ }
16
+ function step(node, field, isTemplatable, handler) {
17
+ if (Array.isArray(node)) {
18
+ node.forEach((child, idx) => step(child, `${field}[${idx}]`, isTemplatable, handler));
19
+ return;
20
+ }
21
+ if (node !== null && typeof node === 'object') {
22
+ for (const [key, child] of Object.entries(node)) {
23
+ step(child, field ? `${field}.${key}` : key, isTemplatable, handler);
24
+ }
25
+ return;
26
+ }
27
+ if (typeof node === 'string' && isTemplatable(field) && (0, tokenizer_1.hasTemplate)(node)) {
28
+ handler(field, node);
29
+ }
30
+ }
31
+ /**
32
+ * Walk all templatable string fields under `root`, returning one entry per
33
+ * templated field with a bound `set()` that mutates `root` in place.
34
+ * Tokenization happens eagerly here — parse errors throw.
35
+ */
36
+ function walkAndBind(root, isTemplatable) {
37
+ const entries = [];
38
+ visitStrings(root, isTemplatable, (field, source) => {
39
+ const tokens = (0, tokenizer_1.tokenize)(source);
40
+ if (!tokens.some(t => t.kind === 'expr'))
41
+ return;
42
+ entries.push({
43
+ field,
44
+ source,
45
+ tokens,
46
+ set: (value) => writeField(root, parseFieldPath(field), value),
47
+ });
48
+ });
49
+ return entries;
50
+ }
51
+ function parseFieldPath(field) {
52
+ const parts = [];
53
+ const re = /([^.\[\]]+)|\[(\d+)\]/g;
54
+ let m;
55
+ while ((m = re.exec(field)) !== null) {
56
+ if (m[1] !== undefined)
57
+ parts.push(m[1]);
58
+ else if (m[2] !== undefined)
59
+ parts.push(Number(m[2]));
60
+ }
61
+ return parts;
62
+ }
63
+ function writeField(root, parts, value) {
64
+ if (parts.length === 0)
65
+ return;
66
+ let cur = root;
67
+ for (let i = 0; i < parts.length - 1; i++) {
68
+ if (cur == null || typeof cur !== 'object')
69
+ return;
70
+ cur = cur[parts[i]];
71
+ }
72
+ if (cur == null || typeof cur !== 'object')
73
+ return;
74
+ cur[parts[parts.length - 1]] = value;
75
+ }
76
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Fsa2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RlbXBsYXRlL3dhbGtlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsK0NBQStDO0FBQy9DLHNDQUFzQzs7QUFzQnRDLG9DQU1DO0FBNEJELGtDQWdCQztBQXRFRCwyQ0FBMkQ7QUFlM0Q7Ozs7R0FJRztBQUNILFNBQWdCLFlBQVksQ0FDMUIsSUFBYSxFQUNiLGFBQTZCLEVBQzdCLE9BQWdEO0lBRWhELElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLGFBQWEsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUN6QyxDQUFDO0FBRUQsU0FBUyxJQUFJLENBQ1gsSUFBYSxFQUNiLEtBQWEsRUFDYixhQUE2QixFQUM3QixPQUFnRDtJQUVoRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxHQUFHLEtBQUssSUFBSSxHQUFHLEdBQUcsRUFBRSxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUN0RixPQUFPO0lBQ1QsQ0FBQztJQUNELElBQUksSUFBSSxLQUFLLElBQUksSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUM5QyxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUErQixDQUFDLEVBQUUsQ0FBQztZQUMzRSxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDdkUsQ0FBQztRQUNELE9BQU87SUFDVCxDQUFDO0lBQ0QsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLElBQUksYUFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUEsdUJBQVcsRUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzFFLE9BQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDdkIsQ0FBQztBQUNILENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBZ0IsV0FBVyxDQUN6QixJQUFPLEVBQ1AsYUFBNkI7SUFFN0IsTUFBTSxPQUFPLEdBQWdCLEVBQUUsQ0FBQztJQUNoQyxZQUFZLENBQUMsSUFBSSxFQUFFLGFBQWEsRUFBRSxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNsRCxNQUFNLE1BQU0sR0FBRyxJQUFBLG9CQUFRLEVBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FBQztZQUFFLE9BQU87UUFDakQsT0FBTyxDQUFDLElBQUksQ0FBQztZQUNYLEtBQUs7WUFDTCxNQUFNO1lBQ04sTUFBTTtZQUNOLEdBQUcsRUFBRSxDQUFDLEtBQWMsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDO1NBQ3hFLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQztBQUVELFNBQVMsY0FBYyxDQUFDLEtBQWE7SUFDbkMsTUFBTSxLQUFLLEdBQTJCLEVBQUUsQ0FBQztJQUN6QyxNQUFNLEVBQUUsR0FBRyx3QkFBd0IsQ0FBQztJQUNwQyxJQUFJLENBQXlCLENBQUM7SUFDOUIsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDckMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssU0FBUztZQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDcEMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssU0FBUztZQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLElBQWEsRUFBRSxLQUE2QixFQUFFLEtBQWM7SUFDOUUsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxPQUFPO0lBQy9CLElBQUksR0FBRyxHQUFZLElBQUksQ0FBQztJQUN4QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUMxQyxJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUTtZQUFFLE9BQU87UUFDbkQsR0FBRyxHQUFJLEdBQXdDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBRSxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUNELElBQUksR0FBRyxJQUFJLElBQUksSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRO1FBQUUsT0FBTztJQUNsRCxHQUF3QyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBRSxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQzlFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgaGFzVGVtcGxhdGUsIHRva2VuaXplLCBUb2tlbiB9IGZyb20gJy4vdG9rZW5pemVyJztcblxuZXhwb3J0IGludGVyZmFjZSBXYWxrRW50cnkge1xuICAvKiogRG90dGVkIHBhdGggdG8gdGhlIGZpZWxkIGluc2lkZSB0aGUgZG9jdW1lbnQsIGUuZy4gJ2NvbW1hbmRzWzNdJyBvciAnZW52LlNUQUdFJyAqL1xuICBmaWVsZDogc3RyaW5nO1xuICAvKiogUmF3IHNvdXJjZSBzdHJpbmcgY29udGFpbmluZyB0ZW1wbGF0ZSB0b2tlbnMgKi9cbiAgc291cmNlOiBzdHJpbmc7XG4gIC8qKiBQYXJzZWQgdG9rZW4gc3RyZWFtICovXG4gIHRva2VuczogVG9rZW5bXTtcbiAgLyoqIFNldHRlciB0byB3cml0ZSBiYWNrIGEgcmVzb2x2ZWQgdmFsdWUgaW50byB0aGUgb3JpZ2luYWwgYHJvb3RgIG9iamVjdCAqL1xuICBzZXQ6ICh2YWx1ZTogdW5rbm93bikgPT4gdm9pZDtcbn1cblxuZXhwb3J0IHR5cGUgRmllbGRQcmVkaWNhdGUgPSAoZmllbGQ6IHN0cmluZykgPT4gYm9vbGVhbjtcblxuLyoqXG4gKiBWaXNpdCBldmVyeSB0ZW1wbGF0YWJsZSBzdHJpbmcgbGVhZiB1bmRlciBgcm9vdGAuIENhbGxzIGBoYW5kbGVyKGZpZWxkLCBzb3VyY2UpYFxuICogZm9yIGVhY2ggc3RyaW5nIHdob3NlIGZpZWxkIHBhdGggc2F0aXNmaWVzIGBpc1RlbXBsYXRhYmxlYCBhbmQgY29udGFpbnMgYHt7YC5cbiAqIERvZXMgTk9UIHRva2VuaXplIOKAlCBjYWxsZXJzIGRlY2lkZSB3aGV0aGVyIHRvIHRocm93IG9yIGNvbGxlY3QgZXJyb3JzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmlzaXRTdHJpbmdzKFxuICByb290OiB1bmtub3duLFxuICBpc1RlbXBsYXRhYmxlOiBGaWVsZFByZWRpY2F0ZSxcbiAgaGFuZGxlcjogKGZpZWxkOiBzdHJpbmcsIHNvdXJjZTogc3RyaW5nKSA9PiB2b2lkLFxuKTogdm9pZCB7XG4gIHN0ZXAocm9vdCwgJycsIGlzVGVtcGxhdGFibGUsIGhhbmRsZXIpO1xufVxuXG5mdW5jdGlvbiBzdGVwKFxuICBub2RlOiB1bmtub3duLFxuICBmaWVsZDogc3RyaW5nLFxuICBpc1RlbXBsYXRhYmxlOiBGaWVsZFByZWRpY2F0ZSxcbiAgaGFuZGxlcjogKGZpZWxkOiBzdHJpbmcsIHNvdXJjZTogc3RyaW5nKSA9PiB2b2lkLFxuKTogdm9pZCB7XG4gIGlmIChBcnJheS5pc0FycmF5KG5vZGUpKSB7XG4gICAgbm9kZS5mb3JFYWNoKChjaGlsZCwgaWR4KSA9PiBzdGVwKGNoaWxkLCBgJHtmaWVsZH1bJHtpZHh9XWAsIGlzVGVtcGxhdGFibGUsIGhhbmRsZXIpKTtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKG5vZGUgIT09IG51bGwgJiYgdHlwZW9mIG5vZGUgPT09ICdvYmplY3QnKSB7XG4gICAgZm9yIChjb25zdCBba2V5LCBjaGlsZF0gb2YgT2JqZWN0LmVudHJpZXMobm9kZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikpIHtcbiAgICAgIHN0ZXAoY2hpbGQsIGZpZWxkID8gYCR7ZmllbGR9LiR7a2V5fWAgOiBrZXksIGlzVGVtcGxhdGFibGUsIGhhbmRsZXIpO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHR5cGVvZiBub2RlID09PSAnc3RyaW5nJyAmJiBpc1RlbXBsYXRhYmxlKGZpZWxkKSAmJiBoYXNUZW1wbGF0ZShub2RlKSkge1xuICAgIGhhbmRsZXIoZmllbGQsIG5vZGUpO1xuICB9XG59XG5cbi8qKlxuICogV2FsayBhbGwgdGVtcGxhdGFibGUgc3RyaW5nIGZpZWxkcyB1bmRlciBgcm9vdGAsIHJldHVybmluZyBvbmUgZW50cnkgcGVyXG4gKiB0ZW1wbGF0ZWQgZmllbGQgd2l0aCBhIGJvdW5kIGBzZXQoKWAgdGhhdCBtdXRhdGVzIGByb290YCBpbiBwbGFjZS5cbiAqIFRva2VuaXphdGlvbiBoYXBwZW5zIGVhZ2VybHkgaGVyZSDigJQgcGFyc2UgZXJyb3JzIHRocm93LlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2Fsa0FuZEJpbmQ8VCBleHRlbmRzIG9iamVjdD4oXG4gIHJvb3Q6IFQsXG4gIGlzVGVtcGxhdGFibGU6IEZpZWxkUHJlZGljYXRlLFxuKTogV2Fsa0VudHJ5W10ge1xuICBjb25zdCBlbnRyaWVzOiBXYWxrRW50cnlbXSA9IFtdO1xuICB2aXNpdFN0cmluZ3Mocm9vdCwgaXNUZW1wbGF0YWJsZSwgKGZpZWxkLCBzb3VyY2UpID0+IHtcbiAgICBjb25zdCB0b2tlbnMgPSB0b2tlbml6ZShzb3VyY2UpO1xuICAgIGlmICghdG9rZW5zLnNvbWUodCA9PiB0LmtpbmQgPT09ICdleHByJykpIHJldHVybjtcbiAgICBlbnRyaWVzLnB1c2goe1xuICAgICAgZmllbGQsXG4gICAgICBzb3VyY2UsXG4gICAgICB0b2tlbnMsXG4gICAgICBzZXQ6ICh2YWx1ZTogdW5rbm93bikgPT4gd3JpdGVGaWVsZChyb290LCBwYXJzZUZpZWxkUGF0aChmaWVsZCksIHZhbHVlKSxcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBlbnRyaWVzO1xufVxuXG5mdW5jdGlvbiBwYXJzZUZpZWxkUGF0aChmaWVsZDogc3RyaW5nKTogQXJyYXk8c3RyaW5nIHwgbnVtYmVyPiB7XG4gIGNvbnN0IHBhcnRzOiBBcnJheTxzdHJpbmcgfCBudW1iZXI+ID0gW107XG4gIGNvbnN0IHJlID0gLyhbXi5cXFtcXF1dKyl8XFxbKFxcZCspXFxdL2c7XG4gIGxldCBtOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsO1xuICB3aGlsZSAoKG0gPSByZS5leGVjKGZpZWxkKSkgIT09IG51bGwpIHtcbiAgICBpZiAobVsxXSAhPT0gdW5kZWZpbmVkKSBwYXJ0cy5wdXNoKG1bMV0pO1xuICAgIGVsc2UgaWYgKG1bMl0gIT09IHVuZGVmaW5lZCkgcGFydHMucHVzaChOdW1iZXIobVsyXSkpO1xuICB9XG4gIHJldHVybiBwYXJ0cztcbn1cblxuZnVuY3Rpb24gd3JpdGVGaWVsZChyb290OiB1bmtub3duLCBwYXJ0czogQXJyYXk8c3RyaW5nIHwgbnVtYmVyPiwgdmFsdWU6IHVua25vd24pOiB2b2lkIHtcbiAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICBsZXQgY3VyOiB1bmtub3duID0gcm9vdDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICBpZiAoY3VyID09IG51bGwgfHwgdHlwZW9mIGN1ciAhPT0gJ29iamVjdCcpIHJldHVybjtcbiAgICBjdXIgPSAoY3VyIGFzIFJlY29yZDxzdHJpbmcgfCBudW1iZXIsIHVua25vd24+KVtwYXJ0c1tpXSFdO1xuICB9XG4gIGlmIChjdXIgPT0gbnVsbCB8fCB0eXBlb2YgY3VyICE9PSAnb2JqZWN0JykgcmV0dXJuO1xuICAoY3VyIGFzIFJlY29yZDxzdHJpbmcgfCBudW1iZXIsIHVua25vd24+KVtwYXJ0c1twYXJ0cy5sZW5ndGggLSAxXSFdID0gdmFsdWU7XG59XG4iXX0=
package/package.json CHANGED
@@ -25,13 +25,13 @@
25
25
  "typescript": "5.9.3"
26
26
  },
27
27
  "dependencies": {
28
- "@pipeline-builder/api-core": "3.1.3",
29
- "@pipeline-builder/pipeline-data": "3.1.3",
30
28
  "aws-cdk-lib": "2.240.0",
31
29
  "axios": "1.13.5",
32
30
  "constructs": "10.5.1",
33
31
  "jsonwebtoken": "9.0.3",
34
- "uuid": "13.0.0"
32
+ "uuid": "13.0.0",
33
+ "@pipeline-builder/pipeline-data": "3.2.0",
34
+ "@pipeline-builder/api-core": "3.2.0"
35
35
  },
36
36
  "keywords": [
37
37
  "aws",
@@ -68,7 +68,7 @@
68
68
  "access": "public",
69
69
  "registry": "https://registry.npmjs.org/"
70
70
  },
71
- "version": "3.1.4",
71
+ "version": "3.2.0",
72
72
  "bugs": {
73
73
  "url": "https://github.com/mwashburn160/pipeline-builder/issues"
74
74
  },