@shipfox/expression 1.2.1 → 2.1.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.
Files changed (53) hide show
  1. package/README.md +25 -12
  2. package/dist/evaluator/errors.d.ts.map +1 -1
  3. package/dist/evaluator/index.d.ts +1 -0
  4. package/dist/evaluator/index.d.ts.map +1 -1
  5. package/dist/evaluator/index.js +1 -0
  6. package/dist/evaluator/index.js.map +1 -1
  7. package/dist/evaluator/rehydrate-json-expression.d.ts +4 -0
  8. package/dist/evaluator/rehydrate-json-expression.d.ts.map +1 -0
  9. package/dist/evaluator/rehydrate-json-expression.js +44 -0
  10. package/dist/evaluator/rehydrate-json-expression.js.map +1 -0
  11. package/dist/expression/create-workflow-expression.d.ts.map +1 -1
  12. package/dist/expression/create-workflow-expression.js +23 -1
  13. package/dist/expression/create-workflow-expression.js.map +1 -1
  14. package/dist/expression/errors.d.ts.map +1 -1
  15. package/dist/index.d.ts +5 -3
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +4 -2
  18. package/dist/index.js.map +1 -1
  19. package/dist/plan/context-key-access.d.ts +2 -0
  20. package/dist/plan/context-key-access.d.ts.map +1 -1
  21. package/dist/plan/context-key-access.js +10 -4
  22. package/dist/plan/context-key-access.js.map +1 -1
  23. package/dist/plan/evaluate-planned-predicate.d.ts.map +1 -1
  24. package/dist/plan/evaluate-planned-predicate.js +2 -2
  25. package/dist/plan/evaluate-planned-predicate.js.map +1 -1
  26. package/dist/resolver/errors.d.ts.map +1 -1
  27. package/dist/run/hoist-run-command.d.ts +8 -0
  28. package/dist/run/hoist-run-command.d.ts.map +1 -1
  29. package/dist/run/hoist-run-command.js +28 -3
  30. package/dist/run/hoist-run-command.js.map +1 -1
  31. package/dist/run/shell-code-position.d.ts +21 -0
  32. package/dist/run/shell-code-position.d.ts.map +1 -0
  33. package/dist/run/shell-code-position.js +623 -0
  34. package/dist/run/shell-code-position.js.map +1 -0
  35. package/dist/run/shell-quoting.d.ts +5 -1
  36. package/dist/run/shell-quoting.d.ts.map +1 -1
  37. package/dist/run/shell-quoting.js +37 -6
  38. package/dist/run/shell-quoting.js.map +1 -1
  39. package/dist/template/errors.d.ts.map +1 -1
  40. package/dist/tsconfig.test.tsbuildinfo +1 -1
  41. package/dist/workflow-context/workflow-context-docs.d.ts +185 -0
  42. package/dist/workflow-context/workflow-context-docs.d.ts.map +1 -0
  43. package/dist/workflow-context/workflow-context-docs.js +168 -0
  44. package/dist/workflow-context/workflow-context-docs.js.map +1 -0
  45. package/dist/workflow-context/workflow-context.d.ts +234 -249
  46. package/dist/workflow-context/workflow-context.d.ts.map +1 -1
  47. package/dist/workflow-context/workflow-context.js +201 -85
  48. package/dist/workflow-context/workflow-context.js.map +1 -1
  49. package/package.json +2 -2
  50. package/dist/template/extract-cel-untrusted-path-accesses.d.ts +0 -5
  51. package/dist/template/extract-cel-untrusted-path-accesses.d.ts.map +0 -1
  52. package/dist/template/extract-cel-untrusted-path-accesses.js +0 -140
  53. package/dist/template/extract-cel-untrusted-path-accesses.js.map +0 -1
package/README.md CHANGED
@@ -18,19 +18,25 @@ CEL checks and run-time evaluation for Shipfox workflow expressions.
18
18
  - **`MAX_RANGE_ELEMENTS`**: The per-evaluation range materialization limit,
19
19
  currently 1,000 values.
20
20
  - **`evaluateWorkflowPredicate`**: Returns `true` only for the boolean `true`.
21
+ - **`classifyShellCodePosition`**: Finds named workflow bindings passed directly
22
+ to shell positions that re-evaluate their arguments.
21
23
  - **`parseWorkflowTemplate`**: Splits strings with `${{ ... }}` spans into
22
24
  ordered literal and expression segments.
23
25
  - **`extractCelContextRoots`**: Returns the sorted top-level CEL identifiers mentioned
24
- by an expression for downstream context and trust checks.
26
+ by an expression for downstream context and agent-selection checks.
25
27
  - **Typed errors**: Reports bad text and run failures with stable error classes.
26
28
  - **`workflowContextDefinitions`**: Names the workflow contexts (`run`,
27
29
  `trigger`, `event`, `inputs`, `job`, `executions`, `execution`, `jobs`, `step`) and
28
- gives each a shape, trust tier, availability site, sensitivity, and host.
30
+ gives each a shape, availability site, sensitivity, and host.
29
31
  Known-shape contexts ship a typed environment; open ones use `syntax`.
30
- - **`workflowInterpolationFieldPolicies`**: Says which trust tier each
31
- interpolatable field accepts, and whether its value needs sanitizing before
32
- display. Use `workflowInterpolationFieldAcceptsContext` and
33
- `workflowInterpolationFieldAcceptsTrustTier` to run those checks.
32
+ - **`workflowInterpolationFieldPolicies`**: Defines the host, fill-site, and
33
+ failure constraints for each interpolatable field. Use
34
+ `workflowInterpolationFieldAcceptsHost` for host checks.
35
+ - **`workflowPredicateContextRoots`**: Defines the exact context roots each
36
+ predicate field receives. Read it with `getWorkflowPredicateContextRoots`,
37
+ narrow runtime context with `projectWorkflowPredicateContext`, and read
38
+ predicate-specific property shapes with
39
+ `getWorkflowPredicateFieldTypeEnvironment`.
34
40
 
35
41
  Use this package where workflow code accepts or runs expression text. It keeps
36
42
  the CEL parser behind a Shipfox API. Other packages do not need to depend on the
@@ -41,7 +47,7 @@ is wrong, stop there and show the error near that field. If the text is good,
41
47
  save the small value this package returns. Later, pass that value and plain data
42
48
  back to this package to get the result for one run.
43
49
 
44
- ## Installation / Setup
50
+ ## Installation and setup
45
51
 
46
52
  ```sh
47
53
  pnpm add @shipfox/expression
@@ -70,12 +76,15 @@ const passed = evaluateWorkflowPredicate(expression, {
70
76
  });
71
77
  ```
72
78
 
73
- ## Behavior Notes
79
+ ## Behavior notes
74
80
 
75
81
  - Use `syntax` when fields are not known yet.
76
82
  - Use `typed` when the caller knows the names and field types in scope.
77
- - Treat the `event`, `inputs`, and open `jobs` contexts as untrusted.
78
- Interpolation field policies decide what untrusted data may reach each field.
83
+ - Predicate evaluation narrows the supplied context to the roots
84
+ `workflowPredicateContextRoots` declares for that field, so a reference
85
+ outside the policy fails closed rather than reading an incidental value.
86
+ - Context values can include external data. Interpolatable fields rely on their
87
+ structural sink guarantees, while host and availability checks remain enforced.
79
88
  - Evaluation is deterministic and has no side effects.
80
89
  - Workflow evaluation does not include config-templating functions. Use a
81
90
  caller-owned environment when a custom function is intentionally needed.
@@ -103,7 +112,7 @@ const passed = evaluateWorkflowPredicate(expression, {
103
112
  - Template closing scans are string-aware, line-comment-aware, and brace-aware,
104
113
  so `}}` inside CEL strings, `//` comments, or map literals does not close the
105
114
  expression span.
106
- - Context root extraction fails closed for trust decisions. It skips only identifiers
115
+ - Context root extraction fails closed for context checks. It skips only identifiers
107
116
  that are provably not context roots and may over-include comprehension variables or
108
117
  struct keys; downstream code maps context roots to the known workflow contexts.
109
118
  - Run command interpolation hoists expression values into generated environment
@@ -111,7 +120,11 @@ const passed = evaluateWorkflowPredicate(expression, {
111
120
  interpolated values from being parsed as shell syntax, but it does not make
112
121
  commands and shell positions that deliberately re-evaluate their arguments
113
122
  safe, such as `eval`, `sh -c "$value"`, `let`, `declare -i`, arithmetic
114
- expressions, or array subscripts like `array[$value]`.
123
+ expressions, or array subscripts like `array[$value]`. Use
124
+ `classifyShellCodePosition` with the generated binding names and workflow env
125
+ names to detect these direct code-position references. The analysis is pure,
126
+ intentionally shallow, and may miss indirect shell data flow; it is designed
127
+ to avoid false-positive warnings.
115
128
  Trigger filters can use `syntax` while integration event payloads are still open.
116
129
  Gate expressions can use `typed` because their local fields are known.
117
130
 
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/evaluator/errors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,qCAAqC,0CAA0C,CAAC;AAE7F,MAAM,MAAM,yCAAyC,GAAG,cAAc,GAAG,kBAAkB,CAAC;AAE5F,qBAAa,iCAAkC,SAAQ,KAAK;IAC1D,QAAQ,CAAC,IAAI,2CAAyC;IACtD,QAAQ,CAAC,MAAM,EAAE,yCAAyC,CAAC;gBAE/C,KAAK,EAAE,OAAO;CAS3B"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/evaluator/errors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,qCAAqC,0CAA0C,CAAC;AAE7F,MAAM,MAAM,yCAAyC,GAAG,cAAc,GAAG,kBAAkB,CAAC;AAE5F,qBAAa,iCAAkC,SAAQ,KAAK;IAC1D,QAAQ,CAAC,IAAI,2CAAyC;IACtD,QAAQ,CAAC,MAAM,EAAE,yCAAyC,CAAC;IAE3D,YAAY,KAAK,EAAE,OAAO,EAQzB;CACF"}
@@ -1,4 +1,5 @@
1
1
  export { WorkflowExpressionEvaluationError, type WorkflowExpressionEvaluationFailureReason, workflowExpressionEvaluationErrorCode, } from './errors.js';
2
2
  export { evaluateWorkflowExpression, evaluateWorkflowExpressionWithEnvironment, evaluateWorkflowPredicate, evaluateWorkflowPredicateFailClosed, type FailClosedPredicateOutcome, type WorkflowExpressionEnvironment, type WorkflowExpressionEvaluationContext, type WorkflowExpressionEvaluationValue, } from './evaluate-workflow-expression.js';
3
3
  export { createRangeEnvironment, MAX_RANGE_ELEMENTS } from './range.js';
4
+ export { rehydrateJsonExpressionRecord, rehydrateJsonExpressionValue, } from './rehydrate-json-expression.js';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/evaluator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,KAAK,yCAAyC,EAC9C,qCAAqC,GACtC,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,0BAA0B,EAC1B,yCAAyC,EACzC,yBAAyB,EACzB,mCAAmC,EACnC,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EAClC,KAAK,mCAAmC,EACxC,KAAK,iCAAiC,GACvC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAC,sBAAsB,EAAE,kBAAkB,EAAC,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/evaluator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,KAAK,yCAAyC,EAC9C,qCAAqC,GACtC,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,0BAA0B,EAC1B,yCAAyC,EACzC,yBAAyB,EACzB,mCAAmC,EACnC,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EAClC,KAAK,mCAAmC,EACxC,KAAK,iCAAiC,GACvC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAC,sBAAsB,EAAE,kBAAkB,EAAC,MAAM,YAAY,CAAC;AACtE,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,GAC7B,MAAM,gCAAgC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export { WorkflowExpressionEvaluationError, workflowExpressionEvaluationErrorCode } from './errors.js';
2
2
  export { evaluateWorkflowExpression, evaluateWorkflowExpressionWithEnvironment, evaluateWorkflowPredicate, evaluateWorkflowPredicateFailClosed } from './evaluate-workflow-expression.js';
3
3
  export { createRangeEnvironment, MAX_RANGE_ELEMENTS } from './range.js';
4
+ export { rehydrateJsonExpressionRecord, rehydrateJsonExpressionValue } from './rehydrate-json-expression.js';
4
5
 
5
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/evaluator/index.ts"],"sourcesContent":["export {\n WorkflowExpressionEvaluationError,\n type WorkflowExpressionEvaluationFailureReason,\n workflowExpressionEvaluationErrorCode,\n} from './errors.js';\nexport {\n evaluateWorkflowExpression,\n evaluateWorkflowExpressionWithEnvironment,\n evaluateWorkflowPredicate,\n evaluateWorkflowPredicateFailClosed,\n type FailClosedPredicateOutcome,\n type WorkflowExpressionEnvironment,\n type WorkflowExpressionEvaluationContext,\n type WorkflowExpressionEvaluationValue,\n} from './evaluate-workflow-expression.js';\nexport {createRangeEnvironment, MAX_RANGE_ELEMENTS} from './range.js';\n"],"names":["WorkflowExpressionEvaluationError","workflowExpressionEvaluationErrorCode","evaluateWorkflowExpression","evaluateWorkflowExpressionWithEnvironment","evaluateWorkflowPredicate","evaluateWorkflowPredicateFailClosed","createRangeEnvironment","MAX_RANGE_ELEMENTS"],"mappings":"AAAA,SACEA,iCAAiC,EAEjCC,qCAAqC,QAChC,cAAc;AACrB,SACEC,0BAA0B,EAC1BC,yCAAyC,EACzCC,yBAAyB,EACzBC,mCAAmC,QAK9B,oCAAoC;AAC3C,SAAQC,sBAAsB,EAAEC,kBAAkB,QAAO,aAAa"}
1
+ {"version":3,"sources":["../../src/evaluator/index.ts"],"sourcesContent":["export {\n WorkflowExpressionEvaluationError,\n type WorkflowExpressionEvaluationFailureReason,\n workflowExpressionEvaluationErrorCode,\n} from './errors.js';\nexport {\n evaluateWorkflowExpression,\n evaluateWorkflowExpressionWithEnvironment,\n evaluateWorkflowPredicate,\n evaluateWorkflowPredicateFailClosed,\n type FailClosedPredicateOutcome,\n type WorkflowExpressionEnvironment,\n type WorkflowExpressionEvaluationContext,\n type WorkflowExpressionEvaluationValue,\n} from './evaluate-workflow-expression.js';\nexport {createRangeEnvironment, MAX_RANGE_ELEMENTS} from './range.js';\nexport {\n rehydrateJsonExpressionRecord,\n rehydrateJsonExpressionValue,\n} from './rehydrate-json-expression.js';\n"],"names":["WorkflowExpressionEvaluationError","workflowExpressionEvaluationErrorCode","evaluateWorkflowExpression","evaluateWorkflowExpressionWithEnvironment","evaluateWorkflowPredicate","evaluateWorkflowPredicateFailClosed","createRangeEnvironment","MAX_RANGE_ELEMENTS","rehydrateJsonExpressionRecord","rehydrateJsonExpressionValue"],"mappings":"AAAA,SACEA,iCAAiC,EAEjCC,qCAAqC,QAChC,cAAc;AACrB,SACEC,0BAA0B,EAC1BC,yCAAyC,EACzCC,yBAAyB,EACzBC,mCAAmC,QAK9B,oCAAoC;AAC3C,SAAQC,sBAAsB,EAAEC,kBAAkB,QAAO,aAAa;AACtE,SACEC,6BAA6B,EAC7BC,4BAA4B,QACvB,iCAAiC"}
@@ -0,0 +1,4 @@
1
+ import type { ExpressionType } from '../expression/workflow-expression.js';
2
+ export declare function rehydrateJsonExpressionRecord(values: Readonly<Record<string, unknown>> | null | undefined, types: Readonly<Record<string, ExpressionType>> | undefined): Record<string, unknown>;
3
+ export declare function rehydrateJsonExpressionValue(value: unknown, type: ExpressionType | undefined): unknown;
4
+ //# sourceMappingURL=rehydrate-json-expression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rehydrate-json-expression.d.ts","sourceRoot":"","sources":["../../src/evaluator/rehydrate-json-expression.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,sCAAsC,CAAC;AAIzE,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EAC5D,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,GAAG,SAAS,GAC1D,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB;AAGD,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,cAAc,GAAG,SAAS,GAC/B,OAAO,CAuBT"}
@@ -0,0 +1,44 @@
1
+ const decimalIntegerPattern = /^-?(?:0|[1-9]\d*)$/;
2
+ export function rehydrateJsonExpressionRecord(values, types) {
3
+ if (values === null || values === undefined) return {};
4
+ if (types === undefined) return {
5
+ ...values
6
+ };
7
+ return Object.fromEntries(Object.entries(values).map(([key, value])=>[
8
+ key,
9
+ rehydrateJsonExpressionValue(value, types[key])
10
+ ]));
11
+ }
12
+ // JSON persistence stores CEL ints and timestamps as numbers/strings, but CEL evaluates them as BigInt/Date.
13
+ export function rehydrateJsonExpressionValue(value, type) {
14
+ if (value === null || type === undefined) return value;
15
+ if (type === 'int') return rehydrateInteger(value);
16
+ if (type === 'timestamp') return rehydrateTimestamp(value);
17
+ if (typeof type !== 'object') return value;
18
+ if (type.kind === 'list') {
19
+ return Array.isArray(value) ? value.map((item)=>rehydrateJsonExpressionValue(item, type.element)) : value;
20
+ }
21
+ if (type.kind === 'object' && isRecord(value)) {
22
+ return Object.fromEntries(Object.entries(value).map(([key, item])=>[
23
+ key,
24
+ rehydrateJsonExpressionValue(item, type.fields[key])
25
+ ]));
26
+ }
27
+ return value;
28
+ }
29
+ function rehydrateInteger(value) {
30
+ if (typeof value === 'bigint') return value;
31
+ if (typeof value === 'number') return Number.isSafeInteger(value) ? BigInt(value) : value;
32
+ if (typeof value !== 'string' || !decimalIntegerPattern.test(value)) return value;
33
+ return BigInt(value);
34
+ }
35
+ function rehydrateTimestamp(value) {
36
+ if (value instanceof Date || typeof value !== 'string' || !value.endsWith('Z')) return value;
37
+ const timestamp = new Date(value);
38
+ return Number.isNaN(timestamp.getTime()) ? value : timestamp;
39
+ }
40
+ function isRecord(value) {
41
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
42
+ }
43
+
44
+ //# sourceMappingURL=rehydrate-json-expression.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/evaluator/rehydrate-json-expression.ts"],"sourcesContent":["import type {ExpressionType} from '../expression/workflow-expression.js';\n\nconst decimalIntegerPattern = /^-?(?:0|[1-9]\\d*)$/;\n\nexport function rehydrateJsonExpressionRecord(\n values: Readonly<Record<string, unknown>> | null | undefined,\n types: Readonly<Record<string, ExpressionType>> | undefined,\n): Record<string, unknown> {\n if (values === null || values === undefined) return {};\n if (types === undefined) return {...values};\n\n return Object.fromEntries(\n Object.entries(values).map(([key, value]) => [\n key,\n rehydrateJsonExpressionValue(value, types[key]),\n ]),\n );\n}\n\n// JSON persistence stores CEL ints and timestamps as numbers/strings, but CEL evaluates them as BigInt/Date.\nexport function rehydrateJsonExpressionValue(\n value: unknown,\n type: ExpressionType | undefined,\n): unknown {\n if (value === null || type === undefined) return value;\n\n if (type === 'int') return rehydrateInteger(value);\n if (type === 'timestamp') return rehydrateTimestamp(value);\n if (typeof type !== 'object') return value;\n\n if (type.kind === 'list') {\n return Array.isArray(value)\n ? value.map((item) => rehydrateJsonExpressionValue(item, type.element))\n : value;\n }\n\n if (type.kind === 'object' && isRecord(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, item]) => [\n key,\n rehydrateJsonExpressionValue(item, type.fields[key]),\n ]),\n );\n }\n\n return value;\n}\n\nfunction rehydrateInteger(value: unknown): unknown {\n if (typeof value === 'bigint') return value;\n if (typeof value === 'number') return Number.isSafeInteger(value) ? BigInt(value) : value;\n if (typeof value !== 'string' || !decimalIntegerPattern.test(value)) return value;\n return BigInt(value);\n}\n\nfunction rehydrateTimestamp(value: unknown): unknown {\n if (value instanceof Date || typeof value !== 'string' || !value.endsWith('Z')) return value;\n const timestamp = new Date(value);\n return Number.isNaN(timestamp.getTime()) ? value : timestamp;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n"],"names":["decimalIntegerPattern","rehydrateJsonExpressionRecord","values","types","undefined","Object","fromEntries","entries","map","key","value","rehydrateJsonExpressionValue","type","rehydrateInteger","rehydrateTimestamp","kind","Array","isArray","item","element","isRecord","fields","Number","isSafeInteger","BigInt","test","Date","endsWith","timestamp","isNaN","getTime"],"mappings":"AAEA,MAAMA,wBAAwB;AAE9B,OAAO,SAASC,8BACdC,MAA4D,EAC5DC,KAA2D;IAE3D,IAAID,WAAW,QAAQA,WAAWE,WAAW,OAAO,CAAC;IACrD,IAAID,UAAUC,WAAW,OAAO;QAAC,GAAGF,MAAM;IAAA;IAE1C,OAAOG,OAAOC,WAAW,CACvBD,OAAOE,OAAO,CAACL,QAAQM,GAAG,CAAC,CAAC,CAACC,KAAKC,MAAM,GAAK;YAC3CD;YACAE,6BAA6BD,OAAOP,KAAK,CAACM,IAAI;SAC/C;AAEL;AAEA,6GAA6G;AAC7G,OAAO,SAASE,6BACdD,KAAc,EACdE,IAAgC;IAEhC,IAAIF,UAAU,QAAQE,SAASR,WAAW,OAAOM;IAEjD,IAAIE,SAAS,OAAO,OAAOC,iBAAiBH;IAC5C,IAAIE,SAAS,aAAa,OAAOE,mBAAmBJ;IACpD,IAAI,OAAOE,SAAS,UAAU,OAAOF;IAErC,IAAIE,KAAKG,IAAI,KAAK,QAAQ;QACxB,OAAOC,MAAMC,OAAO,CAACP,SACjBA,MAAMF,GAAG,CAAC,CAACU,OAASP,6BAA6BO,MAAMN,KAAKO,OAAO,KACnET;IACN;IAEA,IAAIE,KAAKG,IAAI,KAAK,YAAYK,SAASV,QAAQ;QAC7C,OAAOL,OAAOC,WAAW,CACvBD,OAAOE,OAAO,CAACG,OAAOF,GAAG,CAAC,CAAC,CAACC,KAAKS,KAAK,GAAK;gBACzCT;gBACAE,6BAA6BO,MAAMN,KAAKS,MAAM,CAACZ,IAAI;aACpD;IAEL;IAEA,OAAOC;AACT;AAEA,SAASG,iBAAiBH,KAAc;IACtC,IAAI,OAAOA,UAAU,UAAU,OAAOA;IACtC,IAAI,OAAOA,UAAU,UAAU,OAAOY,OAAOC,aAAa,CAACb,SAASc,OAAOd,SAASA;IACpF,IAAI,OAAOA,UAAU,YAAY,CAACV,sBAAsByB,IAAI,CAACf,QAAQ,OAAOA;IAC5E,OAAOc,OAAOd;AAChB;AAEA,SAASI,mBAAmBJ,KAAc;IACxC,IAAIA,iBAAiBgB,QAAQ,OAAOhB,UAAU,YAAY,CAACA,MAAMiB,QAAQ,CAAC,MAAM,OAAOjB;IACvF,MAAMkB,YAAY,IAAIF,KAAKhB;IAC3B,OAAOY,OAAOO,KAAK,CAACD,UAAUE,OAAO,MAAMpB,QAAQkB;AACrD;AAEA,SAASR,SAASV,KAAc;IAC9B,OAAO,OAAOA,UAAU,YAAYA,UAAU,QAAQ,CAACM,MAAMC,OAAO,CAACP;AACvE"}
@@ -1 +1 @@
1
- {"version":3,"file":"create-workflow-expression.d.ts","sourceRoot":"","sources":["../../src/expression/create-workflow-expression.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,8BAA8B,EAI9B,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAelC,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,8BAA8B,GACrC,kBAAkB,CAuDpB;AAcD,wBAAgB,kCAAkC,CAAC,MAAM,EAAE;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;CACpC,GAAG,kBAAkB,CAOrB"}
1
+ {"version":3,"file":"create-workflow-expression.d.ts","sourceRoot":"","sources":["../../src/expression/create-workflow-expression.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,8BAA8B,EAK9B,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAiBlC,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,8BAA8B,GACrC,kBAAkB,CAyDpB;AA0CD,wBAAgB,kCAAkC,CAAC,MAAM,EAAE;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;CACpC,GAAG,kBAAkB,CAOrB"}
@@ -8,6 +8,7 @@ const scalarTypeToCelType = {
8
8
  null: 'null',
9
9
  timestamp: 'google.protobuf.Timestamp'
10
10
  };
11
+ const directPathPattern = /^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/;
11
12
  export function createWorkflowExpression(params) {
12
13
  const source = params.source.trim();
13
14
  let resultType;
@@ -51,7 +52,7 @@ export function createWorkflowExpression(params) {
51
52
  reason: `Expression source must return ${scalarTypeToCelType[params.check.expectedResultType]}; got ${typeCheckResult.type ?? 'unknown'}.`
52
53
  });
53
54
  }
54
- resultType = fromCelType(typeCheckResult.type);
55
+ resultType = resolveKnownPathType(source, params.check.typeEnvironment) ?? fromCelType(typeCheckResult.type);
55
56
  }
56
57
  return {
57
58
  language: 'cel',
@@ -62,6 +63,22 @@ export function createWorkflowExpression(params) {
62
63
  }
63
64
  };
64
65
  }
66
+ function resolveKnownPathType(source, typeEnvironment) {
67
+ // cel-js erases list element detail from custom result type strings, so recover
68
+ // known direct paths before falling back to its lossy result type conversion.
69
+ if (typeEnvironment === undefined || !directPathPattern.test(source)) {
70
+ return undefined;
71
+ }
72
+ const [root, ...path] = source.split('.');
73
+ let current = root === undefined ? undefined : typeEnvironment[root];
74
+ for (const segment of path){
75
+ if (current === undefined || typeof current === 'string' || current.kind !== 'object') {
76
+ return undefined;
77
+ }
78
+ current = current.fields[segment];
79
+ }
80
+ return current;
81
+ }
65
82
  function createTypeCheckingEnvironment() {
66
83
  const environment = new Environment({
67
84
  unlistedVariablesAreDyn: false
@@ -71,6 +88,11 @@ function createTypeCheckingEnvironment() {
71
88
  environment.registerOperator('double == int', (left, right)=>{
72
89
  return Number.isInteger(left) && BigInt(left) === right;
73
90
  });
91
+ // Typed context fields may be absent at runtime while still exposing their
92
+ // known shape when present. CEL's built-in equality overloads do not allow a
93
+ // declared object type to compare with null, so keep null checks aligned with
94
+ // the runtime context contract.
95
+ environment.registerOperator('dyn != null', (left, right)=>left !== right);
74
96
  return environment;
75
97
  }
76
98
  export function unsafeWorkflowExpressionFromSource(params) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/expression/create-workflow-expression.ts"],"sourcesContent":["import {Environment, parse as parseCel} from '@marcbachmann/cel-js';\nimport {InvalidWorkflowExpressionError} from './errors.js';\nimport type {\n CreateWorkflowExpressionParams,\n ExpressionScalarType,\n ExpressionType,\n ValidCelExpression,\n WorkflowExpression,\n} from './workflow-expression.js';\n\nconst scalarTypeToCelType = {\n string: 'string',\n int: 'int',\n double: 'double',\n bool: 'bool',\n null: 'null',\n timestamp: 'google.protobuf.Timestamp',\n} satisfies Record<ExpressionScalarType, string>;\n\ntype CelSchema = {\n [field: string]: string | CelSchema;\n};\n\nexport function createWorkflowExpression(\n params: CreateWorkflowExpressionParams,\n): WorkflowExpression {\n const source = params.source.trim();\n let resultType: ExpressionType | undefined;\n if (source.length === 0) {\n throw new InvalidWorkflowExpressionError({\n source: params.source,\n reason: 'Expression source must not be empty.',\n });\n }\n\n try {\n parseCel(source);\n } catch (error) {\n throw new InvalidWorkflowExpressionError({\n source,\n reason: error instanceof Error ? error.message : 'Expression source could not be parsed.',\n });\n }\n\n if (params.check.mode === 'typed') {\n const environment = createTypeCheckingEnvironment();\n for (const [name, type] of Object.entries(params.check.typeEnvironment ?? {})) {\n const celType = toCelType(type, environment, name);\n if (typeof celType === 'string') {\n environment.registerVariable(name, celType);\n } else {\n environment.registerVariable({name, schema: celType.schema});\n }\n }\n\n const typeCheckResult = environment.check(source);\n if (!typeCheckResult.valid) {\n throw new InvalidWorkflowExpressionError({\n source,\n reason: typeCheckResult.error?.message ?? 'Expression source did not type-check.',\n });\n }\n if (\n params.check.expectedResultType !== undefined &&\n typeCheckResult.type !== scalarTypeToCelType[params.check.expectedResultType]\n ) {\n throw new InvalidWorkflowExpressionError({\n source,\n reason: `Expression source must return ${scalarTypeToCelType[params.check.expectedResultType]}; got ${typeCheckResult.type ?? 'unknown'}.`,\n });\n }\n resultType = fromCelType(typeCheckResult.type);\n }\n\n return {\n language: 'cel',\n source: source as ValidCelExpression,\n check: params.check.mode,\n ...(resultType === undefined ? {} : {resultType}),\n };\n}\n\nfunction createTypeCheckingEnvironment(): Environment {\n const environment = new Environment({unlistedVariablesAreDyn: false});\n\n // CEL evaluates numeric equality across types, but its static checker normally\n // rejects the same expression. Match validation to the runtime contract.\n environment.registerOperator('double == int', (left: number, right: bigint) => {\n return Number.isInteger(left) && BigInt(left) === right;\n });\n\n return environment;\n}\n\nexport function unsafeWorkflowExpressionFromSource(params: {\n source: string;\n check: WorkflowExpression['check'];\n}): WorkflowExpression {\n // Use only when rehydrating a source that was already validated before storage.\n return {\n language: 'cel',\n source: params.source as ValidCelExpression,\n check: params.check,\n };\n}\n\nfunction toCelType(\n type: ExpressionType,\n environment: Environment,\n variableName: string,\n): string | {schema: CelSchema} {\n if (typeof type === 'string') return scalarTypeToCelType[type];\n if (type.kind === 'list') {\n return `list<${toCelListElementType(type.element, environment, variableName)}>`;\n }\n if (type.kind === 'map') return 'map';\n\n return {\n schema: Object.fromEntries(\n Object.entries(type.fields).map(([name, field]) => [name, toCelSchemaType(field)]),\n ),\n };\n}\n\nfunction toCelSchemaType(type: ExpressionType): string | CelSchema {\n if (typeof type === 'string') return scalarTypeToCelType[type];\n if (type.kind === 'list') return `list<${toCelSchemaListElementType(type.element)}>`;\n if (type.kind === 'map') return 'map';\n return Object.fromEntries(\n Object.entries(type.fields).map(([name, field]) => [name, toCelSchemaType(field)]),\n );\n}\n\nfunction toCelSchemaListElementType(type: ExpressionType): string {\n if (typeof type === 'string') return scalarTypeToCelType[type];\n if (type.kind === 'map') return 'map';\n if (type.kind === 'object') return 'dyn';\n return `list<${toCelSchemaListElementType(type.element)}>`;\n}\n\nfunction toCelListElementType(\n type: ExpressionType,\n environment: Environment,\n variableName: string,\n): string {\n if (typeof type === 'string') return scalarTypeToCelType[type];\n if (type.kind === 'map') return 'map';\n if (type.kind === 'object') {\n const typeName = `$${variableName}.item`;\n environment.registerType({\n name: typeName,\n schema: Object.fromEntries(\n Object.entries(type.fields).map(([name, field]) => [name, toCelSchemaType(field)]),\n ),\n });\n return typeName;\n }\n return 'dyn';\n}\n\nfunction fromCelType(type: string | undefined): ExpressionType | undefined {\n if (type === undefined) return undefined;\n\n switch (type) {\n case 'string':\n return 'string';\n case 'int':\n return 'int';\n case 'double':\n return 'double';\n case 'bool':\n return 'bool';\n case 'null':\n return 'null';\n case 'google.protobuf.Timestamp':\n return 'timestamp';\n case 'map':\n return {kind: 'map'};\n case 'dyn':\n return 'string';\n default:\n // cel-js currently exposes custom/list element result types as opaque strings.\n // Keep the outer list shape when present, but erase element detail rather than\n // pretending we can round-trip the original schema.\n if (type.startsWith('list<')) return {kind: 'list', element: {kind: 'map'}};\n return {kind: 'map'};\n }\n}\n"],"names":["Environment","parse","parseCel","InvalidWorkflowExpressionError","scalarTypeToCelType","string","int","double","bool","null","timestamp","createWorkflowExpression","params","source","trim","resultType","length","reason","error","Error","message","check","mode","environment","createTypeCheckingEnvironment","name","type","Object","entries","typeEnvironment","celType","toCelType","registerVariable","schema","typeCheckResult","valid","expectedResultType","undefined","fromCelType","language","unlistedVariablesAreDyn","registerOperator","left","right","Number","isInteger","BigInt","unsafeWorkflowExpressionFromSource","variableName","kind","toCelListElementType","element","fromEntries","fields","map","field","toCelSchemaType","toCelSchemaListElementType","typeName","registerType","startsWith"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/expression/create-workflow-expression.ts"],"sourcesContent":["import {Environment, parse as parseCel} from '@marcbachmann/cel-js';\nimport {InvalidWorkflowExpressionError} from './errors.js';\nimport type {\n CreateWorkflowExpressionParams,\n ExpressionScalarType,\n ExpressionType,\n ExpressionTypeEnvironment,\n ValidCelExpression,\n WorkflowExpression,\n} from './workflow-expression.js';\n\nconst scalarTypeToCelType = {\n string: 'string',\n int: 'int',\n double: 'double',\n bool: 'bool',\n null: 'null',\n timestamp: 'google.protobuf.Timestamp',\n} satisfies Record<ExpressionScalarType, string>;\n\ntype CelSchema = {\n [field: string]: string | CelSchema;\n};\n\nconst directPathPattern = /^[A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*)*$/;\n\nexport function createWorkflowExpression(\n params: CreateWorkflowExpressionParams,\n): WorkflowExpression {\n const source = params.source.trim();\n let resultType: ExpressionType | undefined;\n if (source.length === 0) {\n throw new InvalidWorkflowExpressionError({\n source: params.source,\n reason: 'Expression source must not be empty.',\n });\n }\n\n try {\n parseCel(source);\n } catch (error) {\n throw new InvalidWorkflowExpressionError({\n source,\n reason: error instanceof Error ? error.message : 'Expression source could not be parsed.',\n });\n }\n\n if (params.check.mode === 'typed') {\n const environment = createTypeCheckingEnvironment();\n for (const [name, type] of Object.entries(params.check.typeEnvironment ?? {})) {\n const celType = toCelType(type, environment, name);\n if (typeof celType === 'string') {\n environment.registerVariable(name, celType);\n } else {\n environment.registerVariable({name, schema: celType.schema});\n }\n }\n\n const typeCheckResult = environment.check(source);\n if (!typeCheckResult.valid) {\n throw new InvalidWorkflowExpressionError({\n source,\n reason: typeCheckResult.error?.message ?? 'Expression source did not type-check.',\n });\n }\n if (\n params.check.expectedResultType !== undefined &&\n typeCheckResult.type !== scalarTypeToCelType[params.check.expectedResultType]\n ) {\n throw new InvalidWorkflowExpressionError({\n source,\n reason: `Expression source must return ${scalarTypeToCelType[params.check.expectedResultType]}; got ${typeCheckResult.type ?? 'unknown'}.`,\n });\n }\n resultType =\n resolveKnownPathType(source, params.check.typeEnvironment) ??\n fromCelType(typeCheckResult.type);\n }\n\n return {\n language: 'cel',\n source: source as ValidCelExpression,\n check: params.check.mode,\n ...(resultType === undefined ? {} : {resultType}),\n };\n}\n\nfunction resolveKnownPathType(\n source: string,\n typeEnvironment: ExpressionTypeEnvironment | undefined,\n): ExpressionType | undefined {\n // cel-js erases list element detail from custom result type strings, so recover\n // known direct paths before falling back to its lossy result type conversion.\n if (typeEnvironment === undefined || !directPathPattern.test(source)) {\n return undefined;\n }\n\n const [root, ...path] = source.split('.');\n let current = root === undefined ? undefined : typeEnvironment[root];\n for (const segment of path) {\n if (current === undefined || typeof current === 'string' || current.kind !== 'object') {\n return undefined;\n }\n current = current.fields[segment];\n }\n\n return current;\n}\n\nfunction createTypeCheckingEnvironment(): Environment {\n const environment = new Environment({unlistedVariablesAreDyn: false});\n\n // CEL evaluates numeric equality across types, but its static checker normally\n // rejects the same expression. Match validation to the runtime contract.\n environment.registerOperator('double == int', (left: number, right: bigint) => {\n return Number.isInteger(left) && BigInt(left) === right;\n });\n\n // Typed context fields may be absent at runtime while still exposing their\n // known shape when present. CEL's built-in equality overloads do not allow a\n // declared object type to compare with null, so keep null checks aligned with\n // the runtime context contract.\n environment.registerOperator('dyn != null', (left: unknown, right: null) => left !== right);\n\n return environment;\n}\n\nexport function unsafeWorkflowExpressionFromSource(params: {\n source: string;\n check: WorkflowExpression['check'];\n}): WorkflowExpression {\n // Use only when rehydrating a source that was already validated before storage.\n return {\n language: 'cel',\n source: params.source as ValidCelExpression,\n check: params.check,\n };\n}\n\nfunction toCelType(\n type: ExpressionType,\n environment: Environment,\n variableName: string,\n): string | {schema: CelSchema} {\n if (typeof type === 'string') return scalarTypeToCelType[type];\n if (type.kind === 'list') {\n return `list<${toCelListElementType(type.element, environment, variableName)}>`;\n }\n if (type.kind === 'map') return 'map';\n\n return {\n schema: Object.fromEntries(\n Object.entries(type.fields).map(([name, field]) => [name, toCelSchemaType(field)]),\n ),\n };\n}\n\nfunction toCelSchemaType(type: ExpressionType): string | CelSchema {\n if (typeof type === 'string') return scalarTypeToCelType[type];\n if (type.kind === 'list') return `list<${toCelSchemaListElementType(type.element)}>`;\n if (type.kind === 'map') return 'map';\n return Object.fromEntries(\n Object.entries(type.fields).map(([name, field]) => [name, toCelSchemaType(field)]),\n );\n}\n\nfunction toCelSchemaListElementType(type: ExpressionType): string {\n if (typeof type === 'string') return scalarTypeToCelType[type];\n if (type.kind === 'map') return 'map';\n if (type.kind === 'object') return 'dyn';\n return `list<${toCelSchemaListElementType(type.element)}>`;\n}\n\nfunction toCelListElementType(\n type: ExpressionType,\n environment: Environment,\n variableName: string,\n): string {\n if (typeof type === 'string') return scalarTypeToCelType[type];\n if (type.kind === 'map') return 'map';\n if (type.kind === 'object') {\n const typeName = `$${variableName}.item`;\n environment.registerType({\n name: typeName,\n schema: Object.fromEntries(\n Object.entries(type.fields).map(([name, field]) => [name, toCelSchemaType(field)]),\n ),\n });\n return typeName;\n }\n return 'dyn';\n}\n\nfunction fromCelType(type: string | undefined): ExpressionType | undefined {\n if (type === undefined) return undefined;\n\n switch (type) {\n case 'string':\n return 'string';\n case 'int':\n return 'int';\n case 'double':\n return 'double';\n case 'bool':\n return 'bool';\n case 'null':\n return 'null';\n case 'google.protobuf.Timestamp':\n return 'timestamp';\n case 'map':\n return {kind: 'map'};\n case 'dyn':\n return 'string';\n default:\n // cel-js currently exposes custom/list element result types as opaque strings.\n // Keep the outer list shape when present, but erase element detail rather than\n // pretending we can round-trip the original schema.\n if (type.startsWith('list<')) return {kind: 'list', element: {kind: 'map'}};\n return {kind: 'map'};\n }\n}\n"],"names":["Environment","parse","parseCel","InvalidWorkflowExpressionError","scalarTypeToCelType","string","int","double","bool","null","timestamp","directPathPattern","createWorkflowExpression","params","source","trim","resultType","length","reason","error","Error","message","check","mode","environment","createTypeCheckingEnvironment","name","type","Object","entries","typeEnvironment","celType","toCelType","registerVariable","schema","typeCheckResult","valid","expectedResultType","undefined","resolveKnownPathType","fromCelType","language","test","root","path","split","current","segment","kind","fields","unlistedVariablesAreDyn","registerOperator","left","right","Number","isInteger","BigInt","unsafeWorkflowExpressionFromSource","variableName","toCelListElementType","element","fromEntries","map","field","toCelSchemaType","toCelSchemaListElementType","typeName","registerType","startsWith"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/expression/errors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kCAAkC,gCAAgC,CAAC;AAEhF,qBAAa,8BAA+B,SAAQ,KAAK;IACvD,QAAQ,CAAC,IAAI,iCAAsC;IACnD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAC;CAMtE"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/expression/errors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kCAAkC,gCAAgC,CAAC;AAEhF,qBAAa,8BAA+B,SAAQ,KAAK;IACvD,QAAQ,CAAC,IAAI,iCAAsC;IACnD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,YAAY,MAAM,EAAE;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAC,EAKpE;CACF"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { WorkflowExpressionEvaluationError, type WorkflowExpressionEvaluationFailureReason, workflowExpressionEvaluationErrorCode, } from './evaluator/errors.js';
2
2
  export { evaluateWorkflowExpression, evaluateWorkflowExpressionWithEnvironment, evaluateWorkflowPredicate, evaluateWorkflowPredicateFailClosed, type FailClosedPredicateOutcome, type WorkflowExpressionEnvironment, type WorkflowExpressionEvaluationContext, type WorkflowExpressionEvaluationValue, } from './evaluator/evaluate-workflow-expression.js';
3
3
  export { createRangeEnvironment, MAX_RANGE_ELEMENTS } from './evaluator/range.js';
4
+ export { rehydrateJsonExpressionRecord, rehydrateJsonExpressionValue, } from './evaluator/rehydrate-json-expression.js';
4
5
  export { createWorkflowExpression, unsafeWorkflowExpressionFromSource, } from './expression/create-workflow-expression.js';
5
6
  export { InvalidWorkflowExpressionError, invalidWorkflowExpressionErrorCode, } from './expression/errors.js';
6
7
  export type { CreateWorkflowExpressionParams, ExpressionScalarType, ExpressionType, ExpressionTypeEnvironment, ValidCelExpression, WorkflowExpression, WorkflowExpressionCheck, WorkflowExpressionCheckOptions, } from './expression/workflow-expression.js';
@@ -18,11 +19,12 @@ export type { ResolvedField, ResolvedFieldDeferredSegment, ResolvedFieldLiteralS
18
19
  export { type RoutedExpression, routeExpression } from './plan/route-expression.js';
19
20
  export { type ServerEvaluabilityResult, type ServerEvaluabilityViolation, validateServerEvaluable, } from './plan/validate-server-evaluable.js';
20
21
  export { WorkflowTemplateResolutionError, workflowTemplateResolutionErrorCode, } from './resolver/errors.js';
21
- export { type HoistedPlannedRunCommand, hoistPlannedRunCommand, type PlannedRunCommandBinding, type RunCommandHoistOptions, UnsafeRunInterpolationError, unsafeRunInterpolationErrorCode, } from './run/hoist-run-command.js';
22
+ export { type HoistedPlannedRunCommand, hoistPlannedRunCommand, type PlannedRunCommandBinding, type RunCommandHoistOptions, type UnsafeRunInterpolation, UnsafeRunInterpolationError, unsafeRunInterpolationErrorCode, } from './run/hoist-run-command.js';
23
+ export { classifyShellCodePosition, type ShellCodePositionAnalysis, type ShellCodePositionMatch, type ShellReevaluatingConstruct, } from './run/shell-code-position.js';
22
24
  export { InvalidWorkflowTemplateError, invalidWorkflowTemplateErrorCode, } from './template/errors.js';
23
25
  export { extractCelContextRoots } from './template/extract-cel-context-roots.js';
24
- export { extractCelUntrustedPathAccesses } from './template/extract-cel-untrusted-path-accesses.js';
25
26
  export { parseWorkflowTemplate } from './template/parse-workflow-template.js';
26
27
  export type { WorkflowTemplateExprSegment, WorkflowTemplateLiteralSegment, WorkflowTemplateSegment, } from './template/template-segment.js';
27
- export { type AvailabilitySite, availabilitySites, buildTypedRootsEnvironment, type FillTarget, getWorkflowContextAvailability, getWorkflowContextDefinition, getWorkflowContextHost, getWorkflowContextSensitivity, getWorkflowContextTypeEnvironment, getWorkflowContextUntrustedPaths, getWorkflowInterpolationFieldFailurePolicy, getWorkflowPredicateFieldMinimumFillTarget, type OpenWorkflowContextDefinition, type ReservedRootDefinition, type RunnerWorkflowContextDefinition, resolveContextRootAvailability, resolveContextRootHost, rootsAvailableAt, runnerFillTarget, type TypedWorkflowContextDefinition, unavailableRootsAt, type WorkflowContextAvailabilityReferenceEntry, type WorkflowContextDefinition, type WorkflowContextHost, type WorkflowContextName, type WorkflowContextReservedRoot, type WorkflowContextSensitivity, type WorkflowContextShape, type WorkflowContextTrustTier, type WorkflowFieldFailurePolicy, type WorkflowInterpolationFailurePolicy, type WorkflowInterpolationField, type WorkflowInterpolationFieldPolicy, type WorkflowJobTypeOverlay, type WorkflowPredicateField, type WorkflowStepTypeOverlay, workflowContextAvailabilityReference, workflowContextDefinitions, workflowContextHosts, workflowContextNames, workflowContextReservedRoots, workflowContextRootRequiresLiteralKey, workflowContextSensitivities, workflowContextTrustTiers, workflowFieldFailurePolicies, workflowInterpolationFieldAcceptsContext, workflowInterpolationFieldAcceptsHost, workflowInterpolationFieldAcceptsTrustTier, workflowInterpolationFieldPolicies, workflowInterpolationFields, workflowPredicateFieldFailurePolicy, workflowPredicateFields, } from './workflow-context/workflow-context.js';
28
+ export { type AvailabilitySite, availabilitySites, buildTypedRootsEnvironment, contextRootsForField, type FillTarget, getWorkflowContextAvailability, getWorkflowContextDefinition, getWorkflowContextHost, getWorkflowContextSensitivity, getWorkflowContextTypeEnvironment, getWorkflowInterpolationFieldFailurePolicy, getWorkflowInterpolationFieldSelfReference, getWorkflowPredicateContextRoots, getWorkflowPredicateFieldMinimumFillTarget, getWorkflowPredicateFieldTypeEnvironment, isWorkflowPredicateField, type OpenWorkflowContextDefinition, projectWorkflowPredicateContext, type ReservedRootDefinition, type RunnerWorkflowContextDefinition, resolveContextRootAvailability, resolveContextRootHost, rootsAvailableAt, runnerFillTarget, type TypedWorkflowContextDefinition, unavailableRootsAt, type WorkflowContextAvailabilityReferenceEntry, type WorkflowContextDefinition, type WorkflowContextHost, type WorkflowContextName, type WorkflowContextReservedRoot, type WorkflowContextSensitivity, type WorkflowContextShape, type WorkflowFieldFailurePolicy, type WorkflowInterpolationFailurePolicy, type WorkflowInterpolationField, type WorkflowInterpolationFieldPolicy, type WorkflowJobTypeOverlay, type WorkflowPredicateContextRoot, type WorkflowPredicateField, type WorkflowStepTypeOverlay, workflowContextAvailabilityReference, workflowContextDefinitions, workflowContextHosts, workflowContextNames, workflowContextReservedRoots, workflowContextRootRequiresLiteralKey, workflowContextSensitivities, workflowFieldFailurePolicies, workflowInterpolationFieldAcceptsHost, workflowInterpolationFieldPolicies, workflowInterpolationFields, workflowPredicateContextRoots, workflowPredicateFieldFailurePolicy, workflowPredicateFields, } from './workflow-context/workflow-context.js';
29
+ export { type WorkflowContextDoc, workflowContextDocs, } from './workflow-context/workflow-context-docs.js';
28
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export { WorkflowExpressionEvaluationError, workflowExpressionEvaluationErrorCode } from './evaluator/errors.js';
2
2
  export { evaluateWorkflowExpression, evaluateWorkflowExpressionWithEnvironment, evaluateWorkflowPredicate, evaluateWorkflowPredicateFailClosed } from './evaluator/evaluate-workflow-expression.js';
3
3
  export { createRangeEnvironment, MAX_RANGE_ELEMENTS } from './evaluator/range.js';
4
+ export { rehydrateJsonExpressionRecord, rehydrateJsonExpressionValue } from './evaluator/rehydrate-json-expression.js';
4
5
  export { createWorkflowExpression, unsafeWorkflowExpressionFromSource } from './expression/create-workflow-expression.js';
5
6
  export { InvalidWorkflowExpressionError, invalidWorkflowExpressionErrorCode } from './expression/errors.js';
6
7
  export { coerceStepOutputs, jsonSchemaToExpressionType, outputDeclarationsToExpressionFields, outputDeclarationToExpressionType, outputTypes, validateJsonSchema } from './outputs/index.js';
@@ -17,10 +18,11 @@ export { routeExpression } from './plan/route-expression.js';
17
18
  export { validateServerEvaluable } from './plan/validate-server-evaluable.js';
18
19
  export { WorkflowTemplateResolutionError, workflowTemplateResolutionErrorCode } from './resolver/errors.js';
19
20
  export { hoistPlannedRunCommand, UnsafeRunInterpolationError, unsafeRunInterpolationErrorCode } from './run/hoist-run-command.js';
21
+ export { classifyShellCodePosition } from './run/shell-code-position.js';
20
22
  export { InvalidWorkflowTemplateError, invalidWorkflowTemplateErrorCode } from './template/errors.js';
21
23
  export { extractCelContextRoots } from './template/extract-cel-context-roots.js';
22
- export { extractCelUntrustedPathAccesses } from './template/extract-cel-untrusted-path-accesses.js';
23
24
  export { parseWorkflowTemplate } from './template/parse-workflow-template.js';
24
- export { availabilitySites, buildTypedRootsEnvironment, getWorkflowContextAvailability, getWorkflowContextDefinition, getWorkflowContextHost, getWorkflowContextSensitivity, getWorkflowContextTypeEnvironment, getWorkflowContextUntrustedPaths, getWorkflowInterpolationFieldFailurePolicy, getWorkflowPredicateFieldMinimumFillTarget, resolveContextRootAvailability, resolveContextRootHost, rootsAvailableAt, runnerFillTarget, unavailableRootsAt, workflowContextAvailabilityReference, workflowContextDefinitions, workflowContextHosts, workflowContextNames, workflowContextReservedRoots, workflowContextRootRequiresLiteralKey, workflowContextSensitivities, workflowContextTrustTiers, workflowFieldFailurePolicies, workflowInterpolationFieldAcceptsContext, workflowInterpolationFieldAcceptsHost, workflowInterpolationFieldAcceptsTrustTier, workflowInterpolationFieldPolicies, workflowInterpolationFields, workflowPredicateFieldFailurePolicy, workflowPredicateFields } from './workflow-context/workflow-context.js';
25
+ export { availabilitySites, buildTypedRootsEnvironment, contextRootsForField, getWorkflowContextAvailability, getWorkflowContextDefinition, getWorkflowContextHost, getWorkflowContextSensitivity, getWorkflowContextTypeEnvironment, getWorkflowInterpolationFieldFailurePolicy, getWorkflowInterpolationFieldSelfReference, getWorkflowPredicateContextRoots, getWorkflowPredicateFieldMinimumFillTarget, getWorkflowPredicateFieldTypeEnvironment, isWorkflowPredicateField, projectWorkflowPredicateContext, resolveContextRootAvailability, resolveContextRootHost, rootsAvailableAt, runnerFillTarget, unavailableRootsAt, workflowContextAvailabilityReference, workflowContextDefinitions, workflowContextHosts, workflowContextNames, workflowContextReservedRoots, workflowContextRootRequiresLiteralKey, workflowContextSensitivities, workflowFieldFailurePolicies, workflowInterpolationFieldAcceptsHost, workflowInterpolationFieldPolicies, workflowInterpolationFields, workflowPredicateContextRoots, workflowPredicateFieldFailurePolicy, workflowPredicateFields } from './workflow-context/workflow-context.js';
26
+ export { workflowContextDocs } from './workflow-context/workflow-context-docs.js';
25
27
 
26
28
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export {\n WorkflowExpressionEvaluationError,\n type WorkflowExpressionEvaluationFailureReason,\n workflowExpressionEvaluationErrorCode,\n} from './evaluator/errors.js';\nexport {\n evaluateWorkflowExpression,\n evaluateWorkflowExpressionWithEnvironment,\n evaluateWorkflowPredicate,\n evaluateWorkflowPredicateFailClosed,\n type FailClosedPredicateOutcome,\n type WorkflowExpressionEnvironment,\n type WorkflowExpressionEvaluationContext,\n type WorkflowExpressionEvaluationValue,\n} from './evaluator/evaluate-workflow-expression.js';\nexport {createRangeEnvironment, MAX_RANGE_ELEMENTS} from './evaluator/range.js';\nexport {\n createWorkflowExpression,\n unsafeWorkflowExpressionFromSource,\n} from './expression/create-workflow-expression.js';\nexport {\n InvalidWorkflowExpressionError,\n invalidWorkflowExpressionErrorCode,\n} from './expression/errors.js';\nexport type {\n CreateWorkflowExpressionParams,\n ExpressionScalarType,\n ExpressionType,\n ExpressionTypeEnvironment,\n ValidCelExpression,\n WorkflowExpression,\n WorkflowExpressionCheck,\n WorkflowExpressionCheckOptions,\n} from './expression/workflow-expression.js';\nexport {\n type CoerceStepOutputsResult,\n coerceStepOutputs,\n type JsonSchemaValidationResult,\n jsonSchemaToExpressionType,\n type OutputDeclarations,\n type OutputType,\n type OutputTypeDeclaration,\n outputDeclarationsToExpressionFields,\n outputDeclarationToExpressionType,\n outputTypes,\n type StepOutputCoercionError,\n type StepOutputCoercionErrorReason,\n validateJsonSchema,\n} from './outputs/index.js';\nexport {isBareContextReference} from './plan/bare-reference.js';\nexport {\n analyzeContextKeyAccess,\n analyzeContextRootKeyAccess,\n type ContextKeyAccessAnalysis,\n type ContextKeyAccessReference,\n type ContextKeyAccessViolation,\n type ContextRootKeyAccessAnalysis,\n type ContextRootKeyAccessReference,\n} from './plan/context-key-access.js';\nexport {evaluatePlannedPredicateAtSite} from './plan/evaluate-planned-predicate.js';\nexport {\n capTraceEntries,\n capTraceValue,\n EVALUATION_TRACE_MAX_ENTRIES,\n EVALUATION_TRACE_VALUE_CAP_BYTES,\n type EvaluationTraceEntry,\n type EvaluationTraceLimitEntry,\n type EvaluationTraceRowEntry,\n evaluationTraceEntry,\n predicateTraceEntry,\n} from './plan/evaluation-trace.js';\nexport {extractExactContextRoots} from './plan/extract-exact-context-roots.js';\nexport {\n type FrozenResolvedField,\n freezeResolvedFieldAtSite,\n resolveFieldAtSite,\n type SiteResolvedField,\n type WorkflowTemplateDiagnostic,\n type WorkflowTemplateFailurePolicy,\n} from './plan/freeze.js';\nexport {\n type FrozenPlannedRunCommand,\n freezePlannedRunCommandAtSite,\n} from './plan/freeze-run-command.js';\nexport {\n type FieldPlan,\n type FieldPlanResult,\n type PlanViolation,\n planInterpolationField,\n} from './plan/plan-field.js';\nexport {predicateSourceIsBooleanShaped} from './plan/predicate-shape.js';\nexport type {\n ResolvedField,\n ResolvedFieldDeferredSegment,\n ResolvedFieldLiteralSegment,\n ResolvedFieldSegment,\n} from './plan/resolved-field.js';\nexport {type RoutedExpression, routeExpression} from './plan/route-expression.js';\nexport {\n type ServerEvaluabilityResult,\n type ServerEvaluabilityViolation,\n validateServerEvaluable,\n} from './plan/validate-server-evaluable.js';\nexport {\n WorkflowTemplateResolutionError,\n workflowTemplateResolutionErrorCode,\n} from './resolver/errors.js';\nexport {\n type HoistedPlannedRunCommand,\n hoistPlannedRunCommand,\n type PlannedRunCommandBinding,\n type RunCommandHoistOptions,\n UnsafeRunInterpolationError,\n unsafeRunInterpolationErrorCode,\n} from './run/hoist-run-command.js';\nexport {\n InvalidWorkflowTemplateError,\n invalidWorkflowTemplateErrorCode,\n} from './template/errors.js';\nexport {extractCelContextRoots} from './template/extract-cel-context-roots.js';\nexport {extractCelUntrustedPathAccesses} from './template/extract-cel-untrusted-path-accesses.js';\nexport {parseWorkflowTemplate} from './template/parse-workflow-template.js';\nexport type {\n WorkflowTemplateExprSegment,\n WorkflowTemplateLiteralSegment,\n WorkflowTemplateSegment,\n} from './template/template-segment.js';\nexport {\n type AvailabilitySite,\n availabilitySites,\n buildTypedRootsEnvironment,\n type FillTarget,\n getWorkflowContextAvailability,\n getWorkflowContextDefinition,\n getWorkflowContextHost,\n getWorkflowContextSensitivity,\n getWorkflowContextTypeEnvironment,\n getWorkflowContextUntrustedPaths,\n getWorkflowInterpolationFieldFailurePolicy,\n getWorkflowPredicateFieldMinimumFillTarget,\n type OpenWorkflowContextDefinition,\n type ReservedRootDefinition,\n type RunnerWorkflowContextDefinition,\n resolveContextRootAvailability,\n resolveContextRootHost,\n rootsAvailableAt,\n runnerFillTarget,\n type TypedWorkflowContextDefinition,\n unavailableRootsAt,\n type WorkflowContextAvailabilityReferenceEntry,\n type WorkflowContextDefinition,\n type WorkflowContextHost,\n type WorkflowContextName,\n type WorkflowContextReservedRoot,\n type WorkflowContextSensitivity,\n type WorkflowContextShape,\n type WorkflowContextTrustTier,\n type WorkflowFieldFailurePolicy,\n type WorkflowInterpolationFailurePolicy,\n type WorkflowInterpolationField,\n type WorkflowInterpolationFieldPolicy,\n type WorkflowJobTypeOverlay,\n type WorkflowPredicateField,\n type WorkflowStepTypeOverlay,\n workflowContextAvailabilityReference,\n workflowContextDefinitions,\n workflowContextHosts,\n workflowContextNames,\n workflowContextReservedRoots,\n workflowContextRootRequiresLiteralKey,\n workflowContextSensitivities,\n workflowContextTrustTiers,\n workflowFieldFailurePolicies,\n workflowInterpolationFieldAcceptsContext,\n workflowInterpolationFieldAcceptsHost,\n workflowInterpolationFieldAcceptsTrustTier,\n workflowInterpolationFieldPolicies,\n workflowInterpolationFields,\n workflowPredicateFieldFailurePolicy,\n workflowPredicateFields,\n} from './workflow-context/workflow-context.js';\n"],"names":["WorkflowExpressionEvaluationError","workflowExpressionEvaluationErrorCode","evaluateWorkflowExpression","evaluateWorkflowExpressionWithEnvironment","evaluateWorkflowPredicate","evaluateWorkflowPredicateFailClosed","createRangeEnvironment","MAX_RANGE_ELEMENTS","createWorkflowExpression","unsafeWorkflowExpressionFromSource","InvalidWorkflowExpressionError","invalidWorkflowExpressionErrorCode","coerceStepOutputs","jsonSchemaToExpressionType","outputDeclarationsToExpressionFields","outputDeclarationToExpressionType","outputTypes","validateJsonSchema","isBareContextReference","analyzeContextKeyAccess","analyzeContextRootKeyAccess","evaluatePlannedPredicateAtSite","capTraceEntries","capTraceValue","EVALUATION_TRACE_MAX_ENTRIES","EVALUATION_TRACE_VALUE_CAP_BYTES","evaluationTraceEntry","predicateTraceEntry","extractExactContextRoots","freezeResolvedFieldAtSite","resolveFieldAtSite","freezePlannedRunCommandAtSite","planInterpolationField","predicateSourceIsBooleanShaped","routeExpression","validateServerEvaluable","WorkflowTemplateResolutionError","workflowTemplateResolutionErrorCode","hoistPlannedRunCommand","UnsafeRunInterpolationError","unsafeRunInterpolationErrorCode","InvalidWorkflowTemplateError","invalidWorkflowTemplateErrorCode","extractCelContextRoots","extractCelUntrustedPathAccesses","parseWorkflowTemplate","availabilitySites","buildTypedRootsEnvironment","getWorkflowContextAvailability","getWorkflowContextDefinition","getWorkflowContextHost","getWorkflowContextSensitivity","getWorkflowContextTypeEnvironment","getWorkflowContextUntrustedPaths","getWorkflowInterpolationFieldFailurePolicy","getWorkflowPredicateFieldMinimumFillTarget","resolveContextRootAvailability","resolveContextRootHost","rootsAvailableAt","runnerFillTarget","unavailableRootsAt","workflowContextAvailabilityReference","workflowContextDefinitions","workflowContextHosts","workflowContextNames","workflowContextReservedRoots","workflowContextRootRequiresLiteralKey","workflowContextSensitivities","workflowContextTrustTiers","workflowFieldFailurePolicies","workflowInterpolationFieldAcceptsContext","workflowInterpolationFieldAcceptsHost","workflowInterpolationFieldAcceptsTrustTier","workflowInterpolationFieldPolicies","workflowInterpolationFields","workflowPredicateFieldFailurePolicy","workflowPredicateFields"],"mappings":"AAAA,SACEA,iCAAiC,EAEjCC,qCAAqC,QAChC,wBAAwB;AAC/B,SACEC,0BAA0B,EAC1BC,yCAAyC,EACzCC,yBAAyB,EACzBC,mCAAmC,QAK9B,8CAA8C;AACrD,SAAQC,sBAAsB,EAAEC,kBAAkB,QAAO,uBAAuB;AAChF,SACEC,wBAAwB,EACxBC,kCAAkC,QAC7B,6CAA6C;AACpD,SACEC,8BAA8B,EAC9BC,kCAAkC,QAC7B,yBAAyB;AAWhC,SAEEC,iBAAiB,EAEjBC,0BAA0B,EAI1BC,oCAAoC,EACpCC,iCAAiC,EACjCC,WAAW,EAGXC,kBAAkB,QACb,qBAAqB;AAC5B,SAAQC,sBAAsB,QAAO,2BAA2B;AAChE,SACEC,uBAAuB,EACvBC,2BAA2B,QAMtB,+BAA+B;AACtC,SAAQC,8BAA8B,QAAO,uCAAuC;AACpF,SACEC,eAAe,EACfC,aAAa,EACbC,4BAA4B,EAC5BC,gCAAgC,EAIhCC,oBAAoB,EACpBC,mBAAmB,QACd,6BAA6B;AACpC,SAAQC,wBAAwB,QAAO,wCAAwC;AAC/E,SAEEC,yBAAyB,EACzBC,kBAAkB,QAIb,mBAAmB;AAC1B,SAEEC,6BAA6B,QACxB,+BAA+B;AACtC,SAIEC,sBAAsB,QACjB,uBAAuB;AAC9B,SAAQC,8BAA8B,QAAO,4BAA4B;AAOzE,SAA+BC,eAAe,QAAO,6BAA6B;AAClF,SAGEC,uBAAuB,QAClB,sCAAsC;AAC7C,SACEC,+BAA+B,EAC/BC,mCAAmC,QAC9B,uBAAuB;AAC9B,SAEEC,sBAAsB,EAGtBC,2BAA2B,EAC3BC,+BAA+B,QAC1B,6BAA6B;AACpC,SACEC,4BAA4B,EAC5BC,gCAAgC,QAC3B,uBAAuB;AAC9B,SAAQC,sBAAsB,QAAO,0CAA0C;AAC/E,SAAQC,+BAA+B,QAAO,oDAAoD;AAClG,SAAQC,qBAAqB,QAAO,wCAAwC;AAM5E,SAEEC,iBAAiB,EACjBC,0BAA0B,EAE1BC,8BAA8B,EAC9BC,4BAA4B,EAC5BC,sBAAsB,EACtBC,6BAA6B,EAC7BC,iCAAiC,EACjCC,gCAAgC,EAChCC,0CAA0C,EAC1CC,0CAA0C,EAI1CC,8BAA8B,EAC9BC,sBAAsB,EACtBC,gBAAgB,EAChBC,gBAAgB,EAEhBC,kBAAkB,EAgBlBC,oCAAoC,EACpCC,0BAA0B,EAC1BC,oBAAoB,EACpBC,oBAAoB,EACpBC,4BAA4B,EAC5BC,qCAAqC,EACrCC,4BAA4B,EAC5BC,yBAAyB,EACzBC,4BAA4B,EAC5BC,wCAAwC,EACxCC,qCAAqC,EACrCC,0CAA0C,EAC1CC,kCAAkC,EAClCC,2BAA2B,EAC3BC,mCAAmC,EACnCC,uBAAuB,QAClB,yCAAyC"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export {\n WorkflowExpressionEvaluationError,\n type WorkflowExpressionEvaluationFailureReason,\n workflowExpressionEvaluationErrorCode,\n} from './evaluator/errors.js';\nexport {\n evaluateWorkflowExpression,\n evaluateWorkflowExpressionWithEnvironment,\n evaluateWorkflowPredicate,\n evaluateWorkflowPredicateFailClosed,\n type FailClosedPredicateOutcome,\n type WorkflowExpressionEnvironment,\n type WorkflowExpressionEvaluationContext,\n type WorkflowExpressionEvaluationValue,\n} from './evaluator/evaluate-workflow-expression.js';\nexport {createRangeEnvironment, MAX_RANGE_ELEMENTS} from './evaluator/range.js';\nexport {\n rehydrateJsonExpressionRecord,\n rehydrateJsonExpressionValue,\n} from './evaluator/rehydrate-json-expression.js';\nexport {\n createWorkflowExpression,\n unsafeWorkflowExpressionFromSource,\n} from './expression/create-workflow-expression.js';\nexport {\n InvalidWorkflowExpressionError,\n invalidWorkflowExpressionErrorCode,\n} from './expression/errors.js';\nexport type {\n CreateWorkflowExpressionParams,\n ExpressionScalarType,\n ExpressionType,\n ExpressionTypeEnvironment,\n ValidCelExpression,\n WorkflowExpression,\n WorkflowExpressionCheck,\n WorkflowExpressionCheckOptions,\n} from './expression/workflow-expression.js';\nexport {\n type CoerceStepOutputsResult,\n coerceStepOutputs,\n type JsonSchemaValidationResult,\n jsonSchemaToExpressionType,\n type OutputDeclarations,\n type OutputType,\n type OutputTypeDeclaration,\n outputDeclarationsToExpressionFields,\n outputDeclarationToExpressionType,\n outputTypes,\n type StepOutputCoercionError,\n type StepOutputCoercionErrorReason,\n validateJsonSchema,\n} from './outputs/index.js';\nexport {isBareContextReference} from './plan/bare-reference.js';\nexport {\n analyzeContextKeyAccess,\n analyzeContextRootKeyAccess,\n type ContextKeyAccessAnalysis,\n type ContextKeyAccessReference,\n type ContextKeyAccessViolation,\n type ContextRootKeyAccessAnalysis,\n type ContextRootKeyAccessReference,\n} from './plan/context-key-access.js';\nexport {evaluatePlannedPredicateAtSite} from './plan/evaluate-planned-predicate.js';\nexport {\n capTraceEntries,\n capTraceValue,\n EVALUATION_TRACE_MAX_ENTRIES,\n EVALUATION_TRACE_VALUE_CAP_BYTES,\n type EvaluationTraceEntry,\n type EvaluationTraceLimitEntry,\n type EvaluationTraceRowEntry,\n evaluationTraceEntry,\n predicateTraceEntry,\n} from './plan/evaluation-trace.js';\nexport {extractExactContextRoots} from './plan/extract-exact-context-roots.js';\nexport {\n type FrozenResolvedField,\n freezeResolvedFieldAtSite,\n resolveFieldAtSite,\n type SiteResolvedField,\n type WorkflowTemplateDiagnostic,\n type WorkflowTemplateFailurePolicy,\n} from './plan/freeze.js';\nexport {\n type FrozenPlannedRunCommand,\n freezePlannedRunCommandAtSite,\n} from './plan/freeze-run-command.js';\nexport {\n type FieldPlan,\n type FieldPlanResult,\n type PlanViolation,\n planInterpolationField,\n} from './plan/plan-field.js';\nexport {predicateSourceIsBooleanShaped} from './plan/predicate-shape.js';\nexport type {\n ResolvedField,\n ResolvedFieldDeferredSegment,\n ResolvedFieldLiteralSegment,\n ResolvedFieldSegment,\n} from './plan/resolved-field.js';\nexport {type RoutedExpression, routeExpression} from './plan/route-expression.js';\nexport {\n type ServerEvaluabilityResult,\n type ServerEvaluabilityViolation,\n validateServerEvaluable,\n} from './plan/validate-server-evaluable.js';\nexport {\n WorkflowTemplateResolutionError,\n workflowTemplateResolutionErrorCode,\n} from './resolver/errors.js';\nexport {\n type HoistedPlannedRunCommand,\n hoistPlannedRunCommand,\n type PlannedRunCommandBinding,\n type RunCommandHoistOptions,\n type UnsafeRunInterpolation,\n UnsafeRunInterpolationError,\n unsafeRunInterpolationErrorCode,\n} from './run/hoist-run-command.js';\nexport {\n classifyShellCodePosition,\n type ShellCodePositionAnalysis,\n type ShellCodePositionMatch,\n type ShellReevaluatingConstruct,\n} from './run/shell-code-position.js';\nexport {\n InvalidWorkflowTemplateError,\n invalidWorkflowTemplateErrorCode,\n} from './template/errors.js';\nexport {extractCelContextRoots} from './template/extract-cel-context-roots.js';\nexport {parseWorkflowTemplate} from './template/parse-workflow-template.js';\nexport type {\n WorkflowTemplateExprSegment,\n WorkflowTemplateLiteralSegment,\n WorkflowTemplateSegment,\n} from './template/template-segment.js';\nexport {\n type AvailabilitySite,\n availabilitySites,\n buildTypedRootsEnvironment,\n contextRootsForField,\n type FillTarget,\n getWorkflowContextAvailability,\n getWorkflowContextDefinition,\n getWorkflowContextHost,\n getWorkflowContextSensitivity,\n getWorkflowContextTypeEnvironment,\n getWorkflowInterpolationFieldFailurePolicy,\n getWorkflowInterpolationFieldSelfReference,\n getWorkflowPredicateContextRoots,\n getWorkflowPredicateFieldMinimumFillTarget,\n getWorkflowPredicateFieldTypeEnvironment,\n isWorkflowPredicateField,\n type OpenWorkflowContextDefinition,\n projectWorkflowPredicateContext,\n type ReservedRootDefinition,\n type RunnerWorkflowContextDefinition,\n resolveContextRootAvailability,\n resolveContextRootHost,\n rootsAvailableAt,\n runnerFillTarget,\n type TypedWorkflowContextDefinition,\n unavailableRootsAt,\n type WorkflowContextAvailabilityReferenceEntry,\n type WorkflowContextDefinition,\n type WorkflowContextHost,\n type WorkflowContextName,\n type WorkflowContextReservedRoot,\n type WorkflowContextSensitivity,\n type WorkflowContextShape,\n type WorkflowFieldFailurePolicy,\n type WorkflowInterpolationFailurePolicy,\n type WorkflowInterpolationField,\n type WorkflowInterpolationFieldPolicy,\n type WorkflowJobTypeOverlay,\n type WorkflowPredicateContextRoot,\n type WorkflowPredicateField,\n type WorkflowStepTypeOverlay,\n workflowContextAvailabilityReference,\n workflowContextDefinitions,\n workflowContextHosts,\n workflowContextNames,\n workflowContextReservedRoots,\n workflowContextRootRequiresLiteralKey,\n workflowContextSensitivities,\n workflowFieldFailurePolicies,\n workflowInterpolationFieldAcceptsHost,\n workflowInterpolationFieldPolicies,\n workflowInterpolationFields,\n workflowPredicateContextRoots,\n workflowPredicateFieldFailurePolicy,\n workflowPredicateFields,\n} from './workflow-context/workflow-context.js';\nexport {\n type WorkflowContextDoc,\n workflowContextDocs,\n} from './workflow-context/workflow-context-docs.js';\n"],"names":["WorkflowExpressionEvaluationError","workflowExpressionEvaluationErrorCode","evaluateWorkflowExpression","evaluateWorkflowExpressionWithEnvironment","evaluateWorkflowPredicate","evaluateWorkflowPredicateFailClosed","createRangeEnvironment","MAX_RANGE_ELEMENTS","rehydrateJsonExpressionRecord","rehydrateJsonExpressionValue","createWorkflowExpression","unsafeWorkflowExpressionFromSource","InvalidWorkflowExpressionError","invalidWorkflowExpressionErrorCode","coerceStepOutputs","jsonSchemaToExpressionType","outputDeclarationsToExpressionFields","outputDeclarationToExpressionType","outputTypes","validateJsonSchema","isBareContextReference","analyzeContextKeyAccess","analyzeContextRootKeyAccess","evaluatePlannedPredicateAtSite","capTraceEntries","capTraceValue","EVALUATION_TRACE_MAX_ENTRIES","EVALUATION_TRACE_VALUE_CAP_BYTES","evaluationTraceEntry","predicateTraceEntry","extractExactContextRoots","freezeResolvedFieldAtSite","resolveFieldAtSite","freezePlannedRunCommandAtSite","planInterpolationField","predicateSourceIsBooleanShaped","routeExpression","validateServerEvaluable","WorkflowTemplateResolutionError","workflowTemplateResolutionErrorCode","hoistPlannedRunCommand","UnsafeRunInterpolationError","unsafeRunInterpolationErrorCode","classifyShellCodePosition","InvalidWorkflowTemplateError","invalidWorkflowTemplateErrorCode","extractCelContextRoots","parseWorkflowTemplate","availabilitySites","buildTypedRootsEnvironment","contextRootsForField","getWorkflowContextAvailability","getWorkflowContextDefinition","getWorkflowContextHost","getWorkflowContextSensitivity","getWorkflowContextTypeEnvironment","getWorkflowInterpolationFieldFailurePolicy","getWorkflowInterpolationFieldSelfReference","getWorkflowPredicateContextRoots","getWorkflowPredicateFieldMinimumFillTarget","getWorkflowPredicateFieldTypeEnvironment","isWorkflowPredicateField","projectWorkflowPredicateContext","resolveContextRootAvailability","resolveContextRootHost","rootsAvailableAt","runnerFillTarget","unavailableRootsAt","workflowContextAvailabilityReference","workflowContextDefinitions","workflowContextHosts","workflowContextNames","workflowContextReservedRoots","workflowContextRootRequiresLiteralKey","workflowContextSensitivities","workflowFieldFailurePolicies","workflowInterpolationFieldAcceptsHost","workflowInterpolationFieldPolicies","workflowInterpolationFields","workflowPredicateContextRoots","workflowPredicateFieldFailurePolicy","workflowPredicateFields","workflowContextDocs"],"mappings":"AAAA,SACEA,iCAAiC,EAEjCC,qCAAqC,QAChC,wBAAwB;AAC/B,SACEC,0BAA0B,EAC1BC,yCAAyC,EACzCC,yBAAyB,EACzBC,mCAAmC,QAK9B,8CAA8C;AACrD,SAAQC,sBAAsB,EAAEC,kBAAkB,QAAO,uBAAuB;AAChF,SACEC,6BAA6B,EAC7BC,4BAA4B,QACvB,2CAA2C;AAClD,SACEC,wBAAwB,EACxBC,kCAAkC,QAC7B,6CAA6C;AACpD,SACEC,8BAA8B,EAC9BC,kCAAkC,QAC7B,yBAAyB;AAWhC,SAEEC,iBAAiB,EAEjBC,0BAA0B,EAI1BC,oCAAoC,EACpCC,iCAAiC,EACjCC,WAAW,EAGXC,kBAAkB,QACb,qBAAqB;AAC5B,SAAQC,sBAAsB,QAAO,2BAA2B;AAChE,SACEC,uBAAuB,EACvBC,2BAA2B,QAMtB,+BAA+B;AACtC,SAAQC,8BAA8B,QAAO,uCAAuC;AACpF,SACEC,eAAe,EACfC,aAAa,EACbC,4BAA4B,EAC5BC,gCAAgC,EAIhCC,oBAAoB,EACpBC,mBAAmB,QACd,6BAA6B;AACpC,SAAQC,wBAAwB,QAAO,wCAAwC;AAC/E,SAEEC,yBAAyB,EACzBC,kBAAkB,QAIb,mBAAmB;AAC1B,SAEEC,6BAA6B,QACxB,+BAA+B;AACtC,SAIEC,sBAAsB,QACjB,uBAAuB;AAC9B,SAAQC,8BAA8B,QAAO,4BAA4B;AAOzE,SAA+BC,eAAe,QAAO,6BAA6B;AAClF,SAGEC,uBAAuB,QAClB,sCAAsC;AAC7C,SACEC,+BAA+B,EAC/BC,mCAAmC,QAC9B,uBAAuB;AAC9B,SAEEC,sBAAsB,EAItBC,2BAA2B,EAC3BC,+BAA+B,QAC1B,6BAA6B;AACpC,SACEC,yBAAyB,QAIpB,+BAA+B;AACtC,SACEC,4BAA4B,EAC5BC,gCAAgC,QAC3B,uBAAuB;AAC9B,SAAQC,sBAAsB,QAAO,0CAA0C;AAC/E,SAAQC,qBAAqB,QAAO,wCAAwC;AAM5E,SAEEC,iBAAiB,EACjBC,0BAA0B,EAC1BC,oBAAoB,EAEpBC,8BAA8B,EAC9BC,4BAA4B,EAC5BC,sBAAsB,EACtBC,6BAA6B,EAC7BC,iCAAiC,EACjCC,0CAA0C,EAC1CC,0CAA0C,EAC1CC,gCAAgC,EAChCC,0CAA0C,EAC1CC,wCAAwC,EACxCC,wBAAwB,EAExBC,+BAA+B,EAG/BC,8BAA8B,EAC9BC,sBAAsB,EACtBC,gBAAgB,EAChBC,gBAAgB,EAEhBC,kBAAkB,EAgBlBC,oCAAoC,EACpCC,0BAA0B,EAC1BC,oBAAoB,EACpBC,oBAAoB,EACpBC,4BAA4B,EAC5BC,qCAAqC,EACrCC,4BAA4B,EAC5BC,4BAA4B,EAC5BC,qCAAqC,EACrCC,kCAAkC,EAClCC,2BAA2B,EAC3BC,6BAA6B,EAC7BC,mCAAmC,EACnCC,uBAAuB,QAClB,yCAAyC;AAChD,SAEEC,mBAAmB,QACd,8CAA8C"}
@@ -6,6 +6,8 @@ export interface ContextKeyAccessReference {
6
6
  }
7
7
  export interface ContextKeyAccessViolation {
8
8
  readonly root: string;
9
+ /** First key when a computed access still uses a literal string key. */
10
+ readonly key?: string;
9
11
  readonly source: string;
10
12
  }
11
13
  export interface ContextKeyAccessAnalysis {
@@ -1 +1 @@
1
- {"version":3,"file":"context-key-access.d.ts","sourceRoot":"","sources":["../../src/plan/context-key-access.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,sCAAsC,CAAC;AAoB7E,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,UAAU,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC1D,QAAQ,CAAC,UAAU,EAAE,SAAS,yBAAyB,EAAE,CAAC;CAC3D;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,UAAU,EAAE,SAAS,6BAA6B,EAAE,CAAC;IAC9D,QAAQ,CAAC,UAAU,EAAE,SAAS,yBAAyB,EAAE,CAAC;CAC3D;AAaD,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,kBAAkB,GAAG,MAAM,GACtC,wBAAwB,CAY1B;AAED,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,kBAAkB,GAAG,MAAM,EACvC,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,4BAA4B,CAa9B"}
1
+ {"version":3,"file":"context-key-access.d.ts","sourceRoot":"","sources":["../../src/plan/context-key-access.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,sCAAsC,CAAC;AAoB7E,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,UAAU,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC1D,QAAQ,CAAC,UAAU,EAAE,SAAS,yBAAyB,EAAE,CAAC;CAC3D;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,UAAU,EAAE,SAAS,6BAA6B,EAAE,CAAC;IAC9D,QAAQ,CAAC,UAAU,EAAE,SAAS,yBAAyB,EAAE,CAAC;CAC3D;AAcD,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,kBAAkB,GAAG,MAAM,GACtC,wBAAwB,CAY1B;AAED,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,kBAAkB,GAAG,MAAM,EACvC,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,4BAA4B,CAa9B"}
@@ -160,9 +160,12 @@ function recordLiteralKeyRootAccess(chain, source, references, violations) {
160
160
  }
161
161
  function recordContextRootKeyAccess(chain, source, references, violations) {
162
162
  const [key] = chain.segments;
163
- if (chain.computed || key === undefined) {
163
+ if (chain.rootKeyComputed || key === undefined) {
164
164
  violations.push({
165
165
  root: chain.root,
166
+ ...key === undefined ? {} : {
167
+ key
168
+ },
166
169
  source
167
170
  });
168
171
  return;
@@ -178,7 +181,8 @@ function accessChain(node, scopedIdentifiers) {
178
181
  return scopedIdentifiers.has(node.args) ? undefined : {
179
182
  root: node.args,
180
183
  segments: [],
181
- computed: false
184
+ computed: false,
185
+ rootKeyComputed: false
182
186
  };
183
187
  case '.':
184
188
  {
@@ -202,7 +206,8 @@ function accessChain(node, scopedIdentifiers) {
202
206
  ...target.segments,
203
207
  node.args[1]
204
208
  ],
205
- computed: true
209
+ computed: true,
210
+ rootKeyComputed: target.segments.length === 0 || target.rootKeyComputed
206
211
  };
207
212
  }
208
213
  case '[]':
@@ -217,7 +222,8 @@ function accessChain(node, scopedIdentifiers) {
217
222
  ...target.segments,
218
223
  literalSegment
219
224
  ],
220
- computed: true
225
+ computed: true,
226
+ rootKeyComputed: target.segments.length === 0 || target.rootKeyComputed
221
227
  };
222
228
  }
223
229
  default:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plan/context-key-access.ts"],"sourcesContent":["import {type ASTNode, type BinaryOperator, parse as parseCel} from '@marcbachmann/cel-js';\nimport type {WorkflowExpression} from '../expression/workflow-expression.js';\nimport {workflowContextRootRequiresLiteralKey} from '../workflow-context/workflow-context.js';\n\nconst binaryOperators = new Set<BinaryOperator>([\n '!=',\n '==',\n 'in',\n '+',\n '-',\n '*',\n '/',\n '%',\n '<',\n '<=',\n '>',\n '>=',\n]);\n\nconst comprehensionMethods = new Set(['all', 'exists', 'exists_one', 'filter', 'map']);\n\nexport interface ContextKeyAccessReference {\n readonly root: 'vars' | 'secrets';\n readonly store?: string;\n readonly key: string;\n}\n\nexport interface ContextKeyAccessViolation {\n readonly root: string;\n readonly source: string;\n}\n\nexport interface ContextKeyAccessAnalysis {\n readonly references: readonly ContextKeyAccessReference[];\n readonly violations: readonly ContextKeyAccessViolation[];\n}\n\nexport interface ContextRootKeyAccessReference {\n readonly root: string;\n readonly key: string;\n}\n\nexport interface ContextRootKeyAccessAnalysis {\n readonly references: readonly ContextRootKeyAccessReference[];\n readonly violations: readonly ContextKeyAccessViolation[];\n}\n\ninterface AccessChain {\n readonly root: string;\n readonly segments: readonly string[];\n readonly computed: boolean;\n}\n\ninterface ContextAccessVisitor {\n readonly shouldRecord: (chain: AccessChain) => boolean;\n readonly record: (chain: AccessChain, source: string) => void;\n}\n\nexport function analyzeContextKeyAccess(\n expression: WorkflowExpression | string,\n): ContextKeyAccessAnalysis {\n const source = typeof expression === 'string' ? expression : expression.source;\n const references: ContextKeyAccessReference[] = [];\n const violations: ContextKeyAccessViolation[] = [];\n\n collectContextAccesses(parseCel(source).ast, source, new Set(), {\n shouldRecord: (chain) => workflowContextRootRequiresLiteralKey(chain.root),\n record: (chain, expressionSource) =>\n recordLiteralKeyRootAccess(chain, expressionSource, references, violations),\n });\n\n return {references, violations};\n}\n\nexport function analyzeContextRootKeyAccess(\n expression: WorkflowExpression | string,\n roots: readonly string[],\n): ContextRootKeyAccessAnalysis {\n const source = typeof expression === 'string' ? expression : expression.source;\n const references: ContextRootKeyAccessReference[] = [];\n const violations: ContextKeyAccessViolation[] = [];\n const selectedRoots = new Set(roots);\n\n collectContextAccesses(parseCel(source).ast, source, new Set(), {\n shouldRecord: (chain) => selectedRoots.has(chain.root),\n record: (chain, expressionSource) =>\n recordContextRootKeyAccess(chain, expressionSource, references, violations),\n });\n\n return {references, violations};\n}\n\nfunction collectContextAccesses(\n node: ASTNode,\n source: string,\n scopedIdentifiers: ReadonlySet<string>,\n visitor: ContextAccessVisitor,\n): void {\n if (binaryOperators.has(node.op as BinaryOperator) || node.op === '||' || node.op === '&&') {\n collectBinaryContextAccesses(\n node.args as [ASTNode, ASTNode],\n source,\n scopedIdentifiers,\n visitor,\n );\n return;\n }\n\n const chain = accessChain(node, scopedIdentifiers);\n if (chain && visitor.shouldRecord(chain)) {\n visitor.record(chain, source);\n return;\n }\n\n switch (node.op) {\n case 'id':\n case 'value':\n return;\n case '.':\n case '.?':\n collectContextAccesses(node.args[0], source, scopedIdentifiers, visitor);\n return;\n case '[]':\n case '[?]':\n collectBinaryContextAccesses(node.args, source, scopedIdentifiers, visitor);\n return;\n case 'call':\n for (const argument of node.args[1]) {\n collectContextAccesses(argument, source, scopedIdentifiers, visitor);\n }\n return;\n case 'rcall': {\n const [method, receiver, args] = node.args as [string, ASTNode, ASTNode[]];\n collectContextAccesses(receiver, source, scopedIdentifiers, visitor);\n const binding = bindComprehensionAlias(method, args, scopedIdentifiers);\n for (const argument of args.slice(binding.skipArgs)) {\n collectContextAccesses(argument, source, binding.scopedIdentifiers, visitor);\n }\n return;\n }\n case 'list':\n for (const element of node.args) {\n collectContextAccesses(element, source, scopedIdentifiers, visitor);\n }\n return;\n case 'map':\n for (const [key, value] of node.args) {\n if (key.op !== 'id') {\n collectContextAccesses(key, source, scopedIdentifiers, visitor);\n }\n collectContextAccesses(value, source, scopedIdentifiers, visitor);\n }\n return;\n case '?:':\n collectContextAccesses(node.args[0], source, scopedIdentifiers, visitor);\n collectContextAccesses(node.args[1], source, scopedIdentifiers, visitor);\n collectContextAccesses(node.args[2], source, scopedIdentifiers, visitor);\n return;\n case '!_':\n case '-_':\n collectContextAccesses(node.args, source, scopedIdentifiers, visitor);\n return;\n }\n\n throw new Error(`Unsupported CEL AST operator: ${(node as {op: string}).op}`);\n}\n\nfunction collectBinaryContextAccesses(\n [left, right]: [ASTNode, ASTNode],\n source: string,\n scopedIdentifiers: ReadonlySet<string>,\n visitor: ContextAccessVisitor,\n): void {\n collectContextAccesses(left, source, scopedIdentifiers, visitor);\n collectContextAccesses(right, source, scopedIdentifiers, visitor);\n}\n\nfunction recordLiteralKeyRootAccess(\n chain: AccessChain,\n source: string,\n references: ContextKeyAccessReference[],\n violations: ContextKeyAccessViolation[],\n): void {\n if (chain.computed) {\n violations.push({root: chain.root, source});\n return;\n }\n\n if (chain.root === 'vars' && chain.segments.length === 1) {\n const key = chain.segments[0];\n if (key === undefined) throw new Error('Expected vars key segment');\n references.push({root: chain.root, key});\n return;\n }\n\n if (chain.root === 'secrets' && chain.segments.length === 1) {\n const key = chain.segments[0];\n if (key === undefined) throw new Error('Expected secret key segment');\n references.push({root: chain.root, key});\n return;\n }\n\n if (chain.root === 'secrets' && chain.segments.length === 2) {\n const store = chain.segments[0];\n const key = chain.segments[1];\n if (store === undefined || key === undefined) {\n throw new Error('Expected secret store and key segments');\n }\n references.push({root: chain.root, store, key});\n return;\n }\n\n violations.push({root: chain.root, source});\n}\n\nfunction recordContextRootKeyAccess(\n chain: AccessChain,\n source: string,\n references: ContextRootKeyAccessReference[],\n violations: ContextKeyAccessViolation[],\n): void {\n const [key] = chain.segments;\n if (chain.computed || key === undefined) {\n violations.push({root: chain.root, source});\n return;\n }\n\n references.push({root: chain.root, key});\n}\n\nfunction accessChain(\n node: ASTNode,\n scopedIdentifiers: ReadonlySet<string>,\n): AccessChain | undefined {\n switch (node.op) {\n case 'id':\n return scopedIdentifiers.has(node.args)\n ? undefined\n : {root: node.args, segments: [], computed: false};\n case '.': {\n const target = accessChain(node.args[0], scopedIdentifiers);\n if (target === undefined) return undefined;\n return {...target, segments: [...target.segments, node.args[1]]};\n }\n case '.?': {\n const target = accessChain(node.args[0], scopedIdentifiers);\n if (target === undefined) return undefined;\n return {...target, segments: [...target.segments, node.args[1]], computed: true};\n }\n case '[]':\n case '[?]': {\n const target = accessChain(node.args[0], scopedIdentifiers);\n if (target === undefined) return undefined;\n const literalSegment = literalStringValue(node.args[1]);\n return {\n ...target,\n segments:\n literalSegment === undefined ? target.segments : [...target.segments, literalSegment],\n computed: true,\n };\n }\n default:\n return undefined;\n }\n}\n\nfunction literalStringValue(node: ASTNode): string | undefined {\n return node.op === 'value' && typeof node.args === 'string' ? node.args : undefined;\n}\n\nfunction bindComprehensionAlias(\n method: string,\n args: readonly ASTNode[],\n scopedIdentifiers: ReadonlySet<string>,\n): {readonly scopedIdentifiers: ReadonlySet<string>; readonly skipArgs: number} {\n if (!comprehensionMethods.has(method)) return {scopedIdentifiers, skipArgs: 0};\n\n const [alias] = args;\n if (alias?.op !== 'id') return {scopedIdentifiers, skipArgs: 0};\n\n return {\n scopedIdentifiers: new Set([...scopedIdentifiers, alias.args]),\n skipArgs: 1,\n };\n}\n"],"names":["parse","parseCel","workflowContextRootRequiresLiteralKey","binaryOperators","Set","comprehensionMethods","analyzeContextKeyAccess","expression","source","references","violations","collectContextAccesses","ast","shouldRecord","chain","root","record","expressionSource","recordLiteralKeyRootAccess","analyzeContextRootKeyAccess","roots","selectedRoots","has","recordContextRootKeyAccess","node","scopedIdentifiers","visitor","op","collectBinaryContextAccesses","args","accessChain","argument","method","receiver","binding","bindComprehensionAlias","slice","skipArgs","element","key","value","Error","left","right","computed","push","segments","length","undefined","store","target","literalSegment","literalStringValue","alias"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/plan/context-key-access.ts"],"sourcesContent":["import {type ASTNode, type BinaryOperator, parse as parseCel} from '@marcbachmann/cel-js';\nimport type {WorkflowExpression} from '../expression/workflow-expression.js';\nimport {workflowContextRootRequiresLiteralKey} from '../workflow-context/workflow-context.js';\n\nconst binaryOperators = new Set<BinaryOperator>([\n '!=',\n '==',\n 'in',\n '+',\n '-',\n '*',\n '/',\n '%',\n '<',\n '<=',\n '>',\n '>=',\n]);\n\nconst comprehensionMethods = new Set(['all', 'exists', 'exists_one', 'filter', 'map']);\n\nexport interface ContextKeyAccessReference {\n readonly root: 'vars' | 'secrets';\n readonly store?: string;\n readonly key: string;\n}\n\nexport interface ContextKeyAccessViolation {\n readonly root: string;\n /** First key when a computed access still uses a literal string key. */\n readonly key?: string;\n readonly source: string;\n}\n\nexport interface ContextKeyAccessAnalysis {\n readonly references: readonly ContextKeyAccessReference[];\n readonly violations: readonly ContextKeyAccessViolation[];\n}\n\nexport interface ContextRootKeyAccessReference {\n readonly root: string;\n readonly key: string;\n}\n\nexport interface ContextRootKeyAccessAnalysis {\n readonly references: readonly ContextRootKeyAccessReference[];\n readonly violations: readonly ContextKeyAccessViolation[];\n}\n\ninterface AccessChain {\n readonly root: string;\n readonly segments: readonly string[];\n readonly computed: boolean;\n readonly rootKeyComputed: boolean;\n}\n\ninterface ContextAccessVisitor {\n readonly shouldRecord: (chain: AccessChain) => boolean;\n readonly record: (chain: AccessChain, source: string) => void;\n}\n\nexport function analyzeContextKeyAccess(\n expression: WorkflowExpression | string,\n): ContextKeyAccessAnalysis {\n const source = typeof expression === 'string' ? expression : expression.source;\n const references: ContextKeyAccessReference[] = [];\n const violations: ContextKeyAccessViolation[] = [];\n\n collectContextAccesses(parseCel(source).ast, source, new Set(), {\n shouldRecord: (chain) => workflowContextRootRequiresLiteralKey(chain.root),\n record: (chain, expressionSource) =>\n recordLiteralKeyRootAccess(chain, expressionSource, references, violations),\n });\n\n return {references, violations};\n}\n\nexport function analyzeContextRootKeyAccess(\n expression: WorkflowExpression | string,\n roots: readonly string[],\n): ContextRootKeyAccessAnalysis {\n const source = typeof expression === 'string' ? expression : expression.source;\n const references: ContextRootKeyAccessReference[] = [];\n const violations: ContextKeyAccessViolation[] = [];\n const selectedRoots = new Set(roots);\n\n collectContextAccesses(parseCel(source).ast, source, new Set(), {\n shouldRecord: (chain) => selectedRoots.has(chain.root),\n record: (chain, expressionSource) =>\n recordContextRootKeyAccess(chain, expressionSource, references, violations),\n });\n\n return {references, violations};\n}\n\nfunction collectContextAccesses(\n node: ASTNode,\n source: string,\n scopedIdentifiers: ReadonlySet<string>,\n visitor: ContextAccessVisitor,\n): void {\n if (binaryOperators.has(node.op as BinaryOperator) || node.op === '||' || node.op === '&&') {\n collectBinaryContextAccesses(\n node.args as [ASTNode, ASTNode],\n source,\n scopedIdentifiers,\n visitor,\n );\n return;\n }\n\n const chain = accessChain(node, scopedIdentifiers);\n if (chain && visitor.shouldRecord(chain)) {\n visitor.record(chain, source);\n return;\n }\n\n switch (node.op) {\n case 'id':\n case 'value':\n return;\n case '.':\n case '.?':\n collectContextAccesses(node.args[0], source, scopedIdentifiers, visitor);\n return;\n case '[]':\n case '[?]':\n collectBinaryContextAccesses(node.args, source, scopedIdentifiers, visitor);\n return;\n case 'call':\n for (const argument of node.args[1]) {\n collectContextAccesses(argument, source, scopedIdentifiers, visitor);\n }\n return;\n case 'rcall': {\n const [method, receiver, args] = node.args as [string, ASTNode, ASTNode[]];\n collectContextAccesses(receiver, source, scopedIdentifiers, visitor);\n const binding = bindComprehensionAlias(method, args, scopedIdentifiers);\n for (const argument of args.slice(binding.skipArgs)) {\n collectContextAccesses(argument, source, binding.scopedIdentifiers, visitor);\n }\n return;\n }\n case 'list':\n for (const element of node.args) {\n collectContextAccesses(element, source, scopedIdentifiers, visitor);\n }\n return;\n case 'map':\n for (const [key, value] of node.args) {\n if (key.op !== 'id') {\n collectContextAccesses(key, source, scopedIdentifiers, visitor);\n }\n collectContextAccesses(value, source, scopedIdentifiers, visitor);\n }\n return;\n case '?:':\n collectContextAccesses(node.args[0], source, scopedIdentifiers, visitor);\n collectContextAccesses(node.args[1], source, scopedIdentifiers, visitor);\n collectContextAccesses(node.args[2], source, scopedIdentifiers, visitor);\n return;\n case '!_':\n case '-_':\n collectContextAccesses(node.args, source, scopedIdentifiers, visitor);\n return;\n }\n\n throw new Error(`Unsupported CEL AST operator: ${(node as {op: string}).op}`);\n}\n\nfunction collectBinaryContextAccesses(\n [left, right]: [ASTNode, ASTNode],\n source: string,\n scopedIdentifiers: ReadonlySet<string>,\n visitor: ContextAccessVisitor,\n): void {\n collectContextAccesses(left, source, scopedIdentifiers, visitor);\n collectContextAccesses(right, source, scopedIdentifiers, visitor);\n}\n\nfunction recordLiteralKeyRootAccess(\n chain: AccessChain,\n source: string,\n references: ContextKeyAccessReference[],\n violations: ContextKeyAccessViolation[],\n): void {\n if (chain.computed) {\n violations.push({root: chain.root, source});\n return;\n }\n\n if (chain.root === 'vars' && chain.segments.length === 1) {\n const key = chain.segments[0];\n if (key === undefined) throw new Error('Expected vars key segment');\n references.push({root: chain.root, key});\n return;\n }\n\n if (chain.root === 'secrets' && chain.segments.length === 1) {\n const key = chain.segments[0];\n if (key === undefined) throw new Error('Expected secret key segment');\n references.push({root: chain.root, key});\n return;\n }\n\n if (chain.root === 'secrets' && chain.segments.length === 2) {\n const store = chain.segments[0];\n const key = chain.segments[1];\n if (store === undefined || key === undefined) {\n throw new Error('Expected secret store and key segments');\n }\n references.push({root: chain.root, store, key});\n return;\n }\n\n violations.push({root: chain.root, source});\n}\n\nfunction recordContextRootKeyAccess(\n chain: AccessChain,\n source: string,\n references: ContextRootKeyAccessReference[],\n violations: ContextKeyAccessViolation[],\n): void {\n const [key] = chain.segments;\n if (chain.rootKeyComputed || key === undefined) {\n violations.push({root: chain.root, ...(key === undefined ? {} : {key}), source});\n return;\n }\n\n references.push({root: chain.root, key});\n}\n\nfunction accessChain(\n node: ASTNode,\n scopedIdentifiers: ReadonlySet<string>,\n): AccessChain | undefined {\n switch (node.op) {\n case 'id':\n return scopedIdentifiers.has(node.args)\n ? undefined\n : {root: node.args, segments: [], computed: false, rootKeyComputed: false};\n case '.': {\n const target = accessChain(node.args[0], scopedIdentifiers);\n if (target === undefined) return undefined;\n return {...target, segments: [...target.segments, node.args[1]]};\n }\n case '.?': {\n const target = accessChain(node.args[0], scopedIdentifiers);\n if (target === undefined) return undefined;\n return {\n ...target,\n segments: [...target.segments, node.args[1]],\n computed: true,\n rootKeyComputed: target.segments.length === 0 || target.rootKeyComputed,\n };\n }\n case '[]':\n case '[?]': {\n const target = accessChain(node.args[0], scopedIdentifiers);\n if (target === undefined) return undefined;\n const literalSegment = literalStringValue(node.args[1]);\n return {\n ...target,\n segments:\n literalSegment === undefined ? target.segments : [...target.segments, literalSegment],\n computed: true,\n rootKeyComputed: target.segments.length === 0 || target.rootKeyComputed,\n };\n }\n default:\n return undefined;\n }\n}\n\nfunction literalStringValue(node: ASTNode): string | undefined {\n return node.op === 'value' && typeof node.args === 'string' ? node.args : undefined;\n}\n\nfunction bindComprehensionAlias(\n method: string,\n args: readonly ASTNode[],\n scopedIdentifiers: ReadonlySet<string>,\n): {readonly scopedIdentifiers: ReadonlySet<string>; readonly skipArgs: number} {\n if (!comprehensionMethods.has(method)) return {scopedIdentifiers, skipArgs: 0};\n\n const [alias] = args;\n if (alias?.op !== 'id') return {scopedIdentifiers, skipArgs: 0};\n\n return {\n scopedIdentifiers: new Set([...scopedIdentifiers, alias.args]),\n skipArgs: 1,\n };\n}\n"],"names":["parse","parseCel","workflowContextRootRequiresLiteralKey","binaryOperators","Set","comprehensionMethods","analyzeContextKeyAccess","expression","source","references","violations","collectContextAccesses","ast","shouldRecord","chain","root","record","expressionSource","recordLiteralKeyRootAccess","analyzeContextRootKeyAccess","roots","selectedRoots","has","recordContextRootKeyAccess","node","scopedIdentifiers","visitor","op","collectBinaryContextAccesses","args","accessChain","argument","method","receiver","binding","bindComprehensionAlias","slice","skipArgs","element","key","value","Error","left","right","computed","push","segments","length","undefined","store","rootKeyComputed","target","literalSegment","literalStringValue","alias"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate-planned-predicate.d.ts","sourceRoot":"","sources":["../../src/plan/evaluate-planned-predicate.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,0BAA0B,EAC/B,KAAK,mCAAmC,EACzC,MAAM,8CAA8C,CAAC;AACtD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,sCAAsC,CAAC;AAC7E,OAAO,KAAK,EACV,gBAAgB,EAEhB,sBAAsB,EACvB,MAAM,yCAAyC,CAAC;AAGjD,OAAO,EAAC,KAAK,gBAAgB,EAAkB,MAAM,uBAAuB,CAAC;AAE7E,MAAM,WAAW,gCAAiC,SAAQ,0BAA0B;IAClF,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;CAClC;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACrD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,sBAAsB,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,mCAAmC,CAAC;CACvD,GAAG,gCAAgC,CAOnC"}
1
+ {"version":3,"file":"evaluate-planned-predicate.d.ts","sourceRoot":"","sources":["../../src/plan/evaluate-planned-predicate.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,0BAA0B,EAC/B,KAAK,mCAAmC,EACzC,MAAM,8CAA8C,CAAC;AACtD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,sCAAsC,CAAC;AAC7E,OAAO,KAAK,EACV,gBAAgB,EAEhB,sBAAsB,EACvB,MAAM,yCAAyC,CAAC;AAMjD,OAAO,EAAC,KAAK,gBAAgB,EAAkB,MAAM,uBAAuB,CAAC;AAE7E,MAAM,WAAW,gCAAiC,SAAQ,0BAA0B;IAClF,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;CAClC;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACrD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,sBAAsB,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,mCAAmC,CAAC;CACvD,GAAG,gCAAgC,CAanC"}