@telorun/templating 0.16.0 → 0.17.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.
package/dist/engine.d.ts CHANGED
@@ -19,6 +19,18 @@ export interface CompileEnv {
19
19
  export interface AnalyzeEnv {
20
20
  readonly celEnv: Environment;
21
21
  readonly contextSchema: Record<string, unknown> | null;
22
+ /**
23
+ * The caller vouches that `celEnv` declares EVERY name legal at this site, so
24
+ * a root identifier it does not know is undeclared rather than merely
25
+ * unmodelled.
26
+ *
27
+ * Opt-in because the environment is only that complete when someone built it
28
+ * for a specific site: the base environment declares CEL's own type names and
29
+ * nothing else, so checking roots against it would report `variables` itself
30
+ * as unknown. Absent means the check is skipped, which is what every caller
31
+ * did before it existed.
32
+ */
33
+ readonly rootsDeclared?: boolean;
22
34
  }
23
35
  /** A mechanically applicable repair for a diagnostic. `replacement` is the
24
36
  * **whole analyzed source**, corrected — never a fragment — so a consumer can
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;wEAEwE;AACxE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED;;;;;;;;;eASe;AACf,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACxD;AAED;;;;;;;;;;;;;0EAa0E;AAC1E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;oDAEoD;AACpD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED;;;;yBAIyB;AACzB,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IACrC,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;oDAEgD;IAChD,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;iFAGiF;AACjF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAClD,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;4CAgB4C;AAC5C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;wBAEwB;AACxB,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;2EAKuE;IACvE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B;;;yDAGqD;IACrD,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,aAAa,GAAG,OAAO,CAAC;IAElE;;iEAE6D;IAC7D,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,aAAa,CAAC;IAExD;;;;;;;;;;;;uBAYmB;IACnB,UAAU,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,eAAe,EAAE,CAAC;IAExD;;;;;;;;;;;;;;;;;2CAiBuC;IACvC,YAAY,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;wEAEwE;AACxE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED;;;;;;;;;eASe;AACf,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACvD;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;;;;;;;;;;;0EAa0E;AAC1E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;oDAEoD;AACpD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED;;;;yBAIyB;AACzB,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IACrC,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;oDAEgD;IAChD,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;iFAGiF;AACjF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAClD,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;4CAgB4C;AAC5C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;wBAEwB;AACxB,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;2EAKuE;IACvE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B;;;yDAGqD;IACrD,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,aAAa,GAAG,OAAO,CAAC;IAElE;;iEAE6D;IAC7D,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,aAAa,CAAC;IAExD;;;;;;;;;;;;uBAYmB;IACnB,UAAU,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,eAAe,EAAE,CAAC;IAExD;;;;;;;;;;;;;;;;;2CAiBuC;IACvC,YAAY,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C"}
@@ -1 +1 @@
1
- {"version":3,"file":"cel.d.ts","sourceRoot":"","sources":["../../src/engines/cel.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAoB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAElG;;;;;;;;;;2BAU2B;AAC3B,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,aAAa,CAgFnF;AAYD;yCACyC;AACzC,eAAO,MAAM,SAAS,EAAE,gBAWvB,CAAC"}
1
+ {"version":3,"file":"cel.d.ts","sourceRoot":"","sources":["../../src/engines/cel.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAoB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAElG;;;;;;;;;;2BAU2B;AAC3B,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,aAAa,CAqGnF;AAYD;yCACyC;AACzC,eAAO,MAAM,SAAS,EAAE,gBAWvB,CAAC"}
@@ -69,6 +69,27 @@ export function analyzeCelExpression(source, env) {
69
69
  });
70
70
  }
71
71
  }
72
+ // An undeclared ROOT identifier. cel-js types an unknown name as `dyn` and
73
+ // accepts it, so `!cel "fff"` type-checked, reached the runtime and resolved
74
+ // to nothing — the one CEL mistake with no static report at all. Member
75
+ // access on a KNOWN root was already covered ("No such key"), which is why a
76
+ // typo one level in was caught and a typo at the root was not.
77
+ //
78
+ // Comprehension variables are not roots: `extractAccessChains` drops the
79
+ // names a `.all(x, …)` binds, so the check never sees them.
80
+ if (env.rootsDeclared) {
81
+ const reported = new Set();
82
+ for (const chain of extractAccessChains(parsed.ast)) {
83
+ const root = chain[0];
84
+ if (!root || reported.has(root) || env.celEnv.hasVariable(root))
85
+ continue;
86
+ reported.add(root);
87
+ out.push({
88
+ code: "CEL_UNKNOWN_IDENTIFIER",
89
+ message: `unknown identifier '${root}' — nothing by that name is in scope here.`,
90
+ });
91
+ }
92
+ }
72
93
  if (env.contextSchema) {
73
94
  const contextSchema = env.contextSchema;
74
95
  for (const chain of extractAccessChains(parsed.ast)) {
@@ -1 +1 @@
1
- {"version":3,"file":"literal.d.ts","sourceRoot":"","sources":["../../src/engines/literal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;+CAE+C;AAC/C,eAAO,MAAM,aAAa,EAAE,gBAU3B,CAAC"}
1
+ {"version":3,"file":"literal.d.ts","sourceRoot":"","sources":["../../src/engines/literal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;+CAE+C;AAC/C,eAAO,MAAM,aAAa,EAAE,gBAyB3B,CAAC"}
@@ -6,6 +6,20 @@ export const literalEngine = {
6
6
  compile(source) {
7
7
  return source;
8
8
  },
9
+ /**
10
+ * Opaque text is TEXT — the type is a constant of the tag, exactly as an
11
+ * embed's is, not a function of the slot.
12
+ *
13
+ * Declaring nothing put `!literal` in the other category, the one `!cel` and
14
+ * `!ref` belong to, and everything downstream then treated it as producing
15
+ * whatever the slot asked for. So the editor offered it at a boolean
16
+ * predicate — where opaque text cannot satisfy the slot and `Run.Choice` has
17
+ * a runtime error saying so — and the analyzer type-checked one against a
18
+ * slot-shaped placeholder instead of the string it will actually be.
19
+ */
20
+ producedType() {
21
+ return { type: "string" };
22
+ },
9
23
  analyze() {
10
24
  return { diagnostics: [], calls: [] };
11
25
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telorun/templating",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "Telo Templating - Engine registry and shared CEL core for Telo manifests.",
5
5
  "keywords": [
6
6
  "telo",
@@ -44,7 +44,7 @@
44
44
  "@types/node": "^20.0.0",
45
45
  "typescript": "^5.0.0",
46
46
  "vitest": "^2.1.8",
47
- "@telorun/sdk": "0.75.0"
47
+ "@telorun/sdk": "0.82.1"
48
48
  },
49
49
  "peerDependencies": {
50
50
  "@telorun/sdk": "*"
package/src/engine.ts CHANGED
@@ -21,6 +21,18 @@ export interface CompileEnv {
21
21
  export interface AnalyzeEnv {
22
22
  readonly celEnv: Environment;
23
23
  readonly contextSchema: Record<string, unknown> | null;
24
+ /**
25
+ * The caller vouches that `celEnv` declares EVERY name legal at this site, so
26
+ * a root identifier it does not know is undeclared rather than merely
27
+ * unmodelled.
28
+ *
29
+ * Opt-in because the environment is only that complete when someone built it
30
+ * for a specific site: the base environment declares CEL's own type names and
31
+ * nothing else, so checking roots against it would report `variables` itself
32
+ * as unknown. Absent means the check is skipped, which is what every caller
33
+ * did before it existed.
34
+ */
35
+ readonly rootsDeclared?: boolean;
24
36
  }
25
37
 
26
38
  /** A mechanically applicable repair for a diagnostic. `replacement` is the
@@ -79,6 +79,27 @@ export function analyzeCelExpression(source: string, env: AnalyzeEnv): AnalyzeRe
79
79
  }
80
80
  }
81
81
 
82
+ // An undeclared ROOT identifier. cel-js types an unknown name as `dyn` and
83
+ // accepts it, so `!cel "fff"` type-checked, reached the runtime and resolved
84
+ // to nothing — the one CEL mistake with no static report at all. Member
85
+ // access on a KNOWN root was already covered ("No such key"), which is why a
86
+ // typo one level in was caught and a typo at the root was not.
87
+ //
88
+ // Comprehension variables are not roots: `extractAccessChains` drops the
89
+ // names a `.all(x, …)` binds, so the check never sees them.
90
+ if (env.rootsDeclared) {
91
+ const reported = new Set<string>();
92
+ for (const chain of extractAccessChains(parsed.ast)) {
93
+ const root = chain[0];
94
+ if (!root || reported.has(root) || env.celEnv.hasVariable(root)) continue;
95
+ reported.add(root);
96
+ out.push({
97
+ code: "CEL_UNKNOWN_IDENTIFIER",
98
+ message: `unknown identifier '${root}' — nothing by that name is in scope here.`,
99
+ });
100
+ }
101
+ }
102
+
82
103
  if (env.contextSchema) {
83
104
  const contextSchema = env.contextSchema as Record<string, any>;
84
105
  for (const chain of extractAccessChains(parsed.ast)) {
@@ -10,6 +10,21 @@ export const literalEngine: TemplatingEngine = {
10
10
  return source;
11
11
  },
12
12
 
13
+ /**
14
+ * Opaque text is TEXT — the type is a constant of the tag, exactly as an
15
+ * embed's is, not a function of the slot.
16
+ *
17
+ * Declaring nothing put `!literal` in the other category, the one `!cel` and
18
+ * `!ref` belong to, and everything downstream then treated it as producing
19
+ * whatever the slot asked for. So the editor offered it at a boolean
20
+ * predicate — where opaque text cannot satisfy the slot and `Run.Choice` has
21
+ * a runtime error saying so — and the analyzer type-checked one against a
22
+ * slot-shaped placeholder instead of the string it will actually be.
23
+ */
24
+ producedType() {
25
+ return { type: "string" };
26
+ },
27
+
13
28
  analyze() {
14
29
  return { diagnostics: [], calls: [] };
15
30
  },