@telorun/cel 0.0.0-stage → 0.108.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 (223) hide show
  1. package/LICENSE +17 -0
  2. package/README.md +281 -2
  3. package/dist/activation.d.ts +27 -0
  4. package/dist/activation.d.ts.map +1 -0
  5. package/dist/activation.js +24 -0
  6. package/dist/backend-runtime.d.ts +184 -0
  7. package/dist/backend-runtime.d.ts.map +1 -0
  8. package/dist/backend-runtime.js +425 -0
  9. package/dist/bounded-cache.d.ts +21 -0
  10. package/dist/bounded-cache.d.ts.map +1 -0
  11. package/dist/bounded-cache.js +42 -0
  12. package/dist/catalog-runtime.d.ts +59 -0
  13. package/dist/catalog-runtime.d.ts.map +1 -0
  14. package/dist/catalog-runtime.js +786 -0
  15. package/dist/cel-expression.d.ts +32 -0
  16. package/dist/cel-expression.d.ts.map +1 -0
  17. package/dist/cel-expression.js +29 -0
  18. package/dist/cel-map-value.d.ts +47 -0
  19. package/dist/cel-map-value.d.ts.map +1 -0
  20. package/dist/cel-map-value.js +85 -0
  21. package/dist/cel-program.d.ts +44 -0
  22. package/dist/cel-program.d.ts.map +1 -0
  23. package/dist/cel-program.js +72 -0
  24. package/dist/cel-type.d.ts +131 -0
  25. package/dist/cel-type.d.ts.map +1 -0
  26. package/dist/cel-type.js +293 -0
  27. package/dist/cel-value.d.ts +166 -0
  28. package/dist/cel-value.d.ts.map +1 -0
  29. package/dist/cel-value.js +225 -0
  30. package/dist/check-diagnostic.d.ts +54 -0
  31. package/dist/check-diagnostic.d.ts.map +1 -0
  32. package/dist/check-diagnostic.js +66 -0
  33. package/dist/checker.d.ts +86 -0
  34. package/dist/checker.d.ts.map +1 -0
  35. package/dist/checker.js +806 -0
  36. package/dist/closure-backend.d.ts +21 -0
  37. package/dist/closure-backend.d.ts.map +1 -0
  38. package/dist/closure-backend.js +487 -0
  39. package/dist/comprehension-bindings.d.ts +33 -0
  40. package/dist/comprehension-bindings.d.ts.map +1 -0
  41. package/dist/comprehension-bindings.js +50 -0
  42. package/dist/comprehension-runtime.d.ts +44 -0
  43. package/dist/comprehension-runtime.d.ts.map +1 -0
  44. package/dist/comprehension-runtime.js +137 -0
  45. package/dist/declared-chain.d.ts +35 -0
  46. package/dist/declared-chain.d.ts.map +1 -0
  47. package/dist/declared-chain.js +36 -0
  48. package/dist/duration-value.d.ts +70 -0
  49. package/dist/duration-value.d.ts.map +1 -0
  50. package/dist/duration-value.js +149 -0
  51. package/dist/emitted-module.d.ts +207 -0
  52. package/dist/emitted-module.d.ts.map +1 -0
  53. package/dist/emitted-module.js +359 -0
  54. package/dist/engine-version.d.ts +3 -0
  55. package/dist/engine-version.d.ts.map +1 -0
  56. package/dist/engine-version.js +8 -0
  57. package/dist/environment-digest.d.ts +44 -0
  58. package/dist/environment-digest.d.ts.map +1 -0
  59. package/dist/environment-digest.js +98 -0
  60. package/dist/environment.d.ts +291 -0
  61. package/dist/environment.d.ts.map +1 -0
  62. package/dist/environment.js +474 -0
  63. package/dist/function-catalog.d.ts +66 -0
  64. package/dist/function-catalog.d.ts.map +1 -0
  65. package/dist/function-catalog.js +77 -0
  66. package/dist/function-registry.d.ts +118 -0
  67. package/dist/function-registry.d.ts.map +1 -0
  68. package/dist/function-registry.js +292 -0
  69. package/dist/index.d.ts +93 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +65 -0
  72. package/dist/integer-arithmetic.d.ts +27 -0
  73. package/dist/integer-arithmetic.d.ts.map +1 -0
  74. package/dist/integer-arithmetic.js +58 -0
  75. package/dist/js-emitter.d.ts +133 -0
  76. package/dist/js-emitter.d.ts.map +1 -0
  77. package/dist/js-emitter.js +568 -0
  78. package/dist/json-schema-type.d.ts +182 -0
  79. package/dist/json-schema-type.d.ts.map +1 -0
  80. package/dist/json-schema-type.js +487 -0
  81. package/dist/json-text-scan.d.ts +28 -0
  82. package/dist/json-text-scan.d.ts.map +1 -0
  83. package/dist/json-text-scan.js +159 -0
  84. package/dist/lexer.d.ts +103 -0
  85. package/dist/lexer.d.ts.map +1 -0
  86. package/dist/lexer.js +458 -0
  87. package/dist/macro-check.d.ts +41 -0
  88. package/dist/macro-check.d.ts.map +1 -0
  89. package/dist/macro-check.js +162 -0
  90. package/dist/macro-shape.d.ts +24 -0
  91. package/dist/macro-shape.d.ts.map +1 -0
  92. package/dist/macro-shape.js +55 -0
  93. package/dist/member-read.d.ts +89 -0
  94. package/dist/member-read.d.ts.map +1 -0
  95. package/dist/member-read.js +166 -0
  96. package/dist/namespace-resolution.d.ts +35 -0
  97. package/dist/namespace-resolution.d.ts.map +1 -0
  98. package/dist/namespace-resolution.js +160 -0
  99. package/dist/nominal-type.d.ts +63 -0
  100. package/dist/nominal-type.d.ts.map +1 -0
  101. package/dist/nominal-type.js +98 -0
  102. package/dist/nullable-access.d.ts +38 -0
  103. package/dist/nullable-access.d.ts.map +1 -0
  104. package/dist/nullable-access.js +93 -0
  105. package/dist/parse-limits.d.ts +26 -0
  106. package/dist/parse-limits.d.ts.map +1 -0
  107. package/dist/parse-limits.js +21 -0
  108. package/dist/parser.d.ts +48 -0
  109. package/dist/parser.d.ts.map +1 -0
  110. package/dist/parser.js +503 -0
  111. package/dist/qualified-calls.d.ts +22 -0
  112. package/dist/qualified-calls.d.ts.map +1 -0
  113. package/dist/qualified-calls.js +27 -0
  114. package/dist/regular-expression.d.ts +48 -0
  115. package/dist/regular-expression.d.ts.map +1 -0
  116. package/dist/regular-expression.js +77 -0
  117. package/dist/reserved-words.d.ts +52 -0
  118. package/dist/reserved-words.d.ts.map +1 -0
  119. package/dist/reserved-words.js +77 -0
  120. package/dist/resolved-call.d.ts +46 -0
  121. package/dist/resolved-call.d.ts.map +1 -0
  122. package/dist/resolved-call.js +15 -0
  123. package/dist/root-references.d.ts +23 -0
  124. package/dist/root-references.d.ts.map +1 -0
  125. package/dist/root-references.js +120 -0
  126. package/dist/runtime-library.d.ts +67 -0
  127. package/dist/runtime-library.d.ts.map +1 -0
  128. package/dist/runtime-library.js +554 -0
  129. package/dist/serializer.d.ts +24 -0
  130. package/dist/serializer.d.ts.map +1 -0
  131. package/dist/serializer.js +256 -0
  132. package/dist/sha256.d.ts +20 -0
  133. package/dist/sha256.d.ts.map +1 -0
  134. package/dist/sha256.js +103 -0
  135. package/dist/signature.d.ts +72 -0
  136. package/dist/signature.d.ts.map +1 -0
  137. package/dist/signature.js +61 -0
  138. package/dist/signatures/function-catalog.json +788 -0
  139. package/dist/signatures/standard-library.json +229 -0
  140. package/dist/standard-library.d.ts +41 -0
  141. package/dist/standard-library.d.ts.map +1 -0
  142. package/dist/standard-library.js +85 -0
  143. package/dist/syntax-diagnostic.d.ts +61 -0
  144. package/dist/syntax-diagnostic.d.ts.map +1 -0
  145. package/dist/syntax-diagnostic.js +28 -0
  146. package/dist/syntax-tree.d.ts +160 -0
  147. package/dist/syntax-tree.d.ts.map +1 -0
  148. package/dist/syntax-tree.js +58 -0
  149. package/dist/timestamp-value.d.ts +62 -0
  150. package/dist/timestamp-value.d.ts.map +1 -0
  151. package/dist/timestamp-value.js +238 -0
  152. package/dist/tree-equality.d.ts +15 -0
  153. package/dist/tree-equality.d.ts.map +1 -0
  154. package/dist/tree-equality.js +105 -0
  155. package/dist/type-expression.d.ts +42 -0
  156. package/dist/type-expression.d.ts.map +1 -0
  157. package/dist/type-expression.js +154 -0
  158. package/dist/value-equality.d.ts +38 -0
  159. package/dist/value-equality.d.ts.map +1 -0
  160. package/dist/value-equality.js +196 -0
  161. package/dist/value-text.d.ts +25 -0
  162. package/dist/value-text.d.ts.map +1 -0
  163. package/dist/value-text.js +44 -0
  164. package/dist/zoned-calendar.d.ts +61 -0
  165. package/dist/zoned-calendar.d.ts.map +1 -0
  166. package/dist/zoned-calendar.js +143 -0
  167. package/package.json +56 -3
  168. package/src/activation.ts +32 -0
  169. package/src/backend-runtime.ts +604 -0
  170. package/src/bounded-cache.ts +45 -0
  171. package/src/catalog-runtime.ts +921 -0
  172. package/src/cel-expression.ts +53 -0
  173. package/src/cel-map-value.ts +97 -0
  174. package/src/cel-program.ts +103 -0
  175. package/src/cel-type.ts +359 -0
  176. package/src/cel-value.ts +361 -0
  177. package/src/check-diagnostic.ts +104 -0
  178. package/src/checker.ts +1045 -0
  179. package/src/closure-backend.ts +547 -0
  180. package/src/comprehension-bindings.ts +66 -0
  181. package/src/comprehension-runtime.ts +157 -0
  182. package/src/declared-chain.ts +45 -0
  183. package/src/duration-value.ts +160 -0
  184. package/src/emitted-module.ts +494 -0
  185. package/src/engine-version.ts +9 -0
  186. package/src/environment-digest.ts +111 -0
  187. package/src/environment.ts +761 -0
  188. package/src/function-catalog.ts +140 -0
  189. package/src/function-registry.ts +341 -0
  190. package/src/index.ts +407 -0
  191. package/src/integer-arithmetic.ts +64 -0
  192. package/src/js-emitter.ts +721 -0
  193. package/src/json-schema-type.ts +664 -0
  194. package/src/json-text-scan.ts +163 -0
  195. package/src/lexer.ts +562 -0
  196. package/src/macro-check.ts +197 -0
  197. package/src/macro-shape.ts +66 -0
  198. package/src/member-read.ts +167 -0
  199. package/src/namespace-resolution.ts +167 -0
  200. package/src/nominal-type.ts +149 -0
  201. package/src/nullable-access.ts +95 -0
  202. package/src/parse-limits.ts +36 -0
  203. package/src/parser.ts +554 -0
  204. package/src/qualified-calls.ts +39 -0
  205. package/src/regular-expression.ts +101 -0
  206. package/src/reserved-words.ts +94 -0
  207. package/src/resolved-call.ts +47 -0
  208. package/src/root-references.ts +126 -0
  209. package/src/runtime-library.ts +639 -0
  210. package/src/serializer.ts +262 -0
  211. package/src/sha256.ts +112 -0
  212. package/src/signature.ts +127 -0
  213. package/src/signatures/function-catalog.json +788 -0
  214. package/src/signatures/standard-library.json +235 -0
  215. package/src/standard-library.ts +149 -0
  216. package/src/syntax-diagnostic.ts +72 -0
  217. package/src/syntax-tree.ts +229 -0
  218. package/src/timestamp-value.ts +310 -0
  219. package/src/tree-equality.ts +130 -0
  220. package/src/type-expression.ts +182 -0
  221. package/src/value-equality.ts +201 -0
  222. package/src/value-text.ts +45 -0
  223. package/src/zoned-calendar.ts +178 -0
@@ -0,0 +1,225 @@
1
+ /**
2
+ * The CEL value domain, and how a value says what it is.
3
+ *
4
+ * **Identity is a string type key under `Symbol.for("telo.cel.value")`, never
5
+ * `instanceof`.** Two copies of this engine loaded independently are two sets of
6
+ * classes, so a constructor check would make a `uint` built by one copy not a uint to
7
+ * the other — `+`, `type()` and every overload would refuse it. A symbol from the
8
+ * global registry is the same symbol in both, so the key is readable across copies,
9
+ * and because a symbol-keyed member cannot appear in parsed JSON an inbound request
10
+ * body cannot forge a duration. A plain object carrying a *string*-keyed look-alike
11
+ * (`{"telo.cel.value": "uint"}`) is therefore data: it reads as a map, as it must.
12
+ *
13
+ * What is **plain** carries no key, because the host platform already represents it
14
+ * one way and only one: `null`, a boolean, a string, a double (`number`), an int
15
+ * (`bigint`), bytes (`Uint8Array`), a list (an array) and a map whose keys are all
16
+ * strings (a plain object, which is how a host hands one over). What has no faithful
17
+ * plain form carries the key: a `uint` (a `bigint` is already an int), a timestamp and
18
+ * a duration (both nanosecond-precise, which no host date type holds), a type value,
19
+ * an optional, a map with typed keys, and a CEL error. A host's own named type
20
+ * registers its own key, checked against this set at registration.
21
+ *
22
+ * The keys are a **closed set** (`CEL_VALUE_KEYS`); a new one is a change here.
23
+ */
24
+ export const CEL_VALUE_TYPE = Symbol.for("telo.cel.value");
25
+ /** The type keys this engine owns. A host-registered type may not reuse one. */
26
+ export const CEL_VALUE_KEYS = [
27
+ "uint",
28
+ "google.protobuf.Timestamp",
29
+ "google.protobuf.Duration",
30
+ "type",
31
+ "optional",
32
+ "map",
33
+ "error",
34
+ ];
35
+ /** Every evaluation failure this engine names. A code is never derived from a message. */
36
+ export const CEL_EVALUATION_CODES = [
37
+ /** A map or a record does not hold the key read. */
38
+ "no_such_key",
39
+ /** A name nothing in the activation holds, at any prefix. */
40
+ "no_such_variable",
41
+ /** A list index below zero or past the last element. */
42
+ "index_out_of_range",
43
+ /** No registered overload takes the values a call was handed. */
44
+ "no_matching_overload",
45
+ /** A select, an index or an iteration over a value that holds no members. */
46
+ "unsupported_container",
47
+ /** A map key, or an index, of a type no map is keyed by. */
48
+ "unsupported_key_type",
49
+ /** A map literal or a comprehension building two entries with one key. */
50
+ "duplicate_map_key",
51
+ /** An int or uint result outside its own range. */
52
+ "numeric_overflow",
53
+ "division_by_zero",
54
+ "modulo_by_zero",
55
+ /** A conversion the value cannot make: `int('x')`, `timestamp` out of range. */
56
+ "invalid_conversion",
57
+ /** An argument a function refuses: an unknown time zone, a negative index. */
58
+ "invalid_argument",
59
+ /** A pattern RE2 cannot parse. */
60
+ "invalid_regular_expression",
61
+ /** `value()` on an optional that holds nothing. */
62
+ "optional_value_missing",
63
+ /** A namespaced call nothing bound an implementation for. */
64
+ "unbound_function",
65
+ /** A thenable reached evaluation. Evaluation is synchronous on both backends. */
66
+ "async_value_unsupported",
67
+ ];
68
+ // --- constructors ----------------------------------------------------------
69
+ export function celUint(value) {
70
+ return { [CEL_VALUE_TYPE]: "uint", value };
71
+ }
72
+ export function celTypeValue(name) {
73
+ return { [CEL_VALUE_TYPE]: "type", name };
74
+ }
75
+ const NONE = { [CEL_VALUE_TYPE]: "optional", present: false };
76
+ export function celNone() {
77
+ return NONE;
78
+ }
79
+ export function celSome(held) {
80
+ return { [CEL_VALUE_TYPE]: "optional", present: true, held };
81
+ }
82
+ export function celError(code, message, range) {
83
+ return { [CEL_VALUE_TYPE]: "error", code, message, ...(range ? { range } : {}) };
84
+ }
85
+ // --- reading what a value is ----------------------------------------------
86
+ /** The type key a value carries, or nothing when it carries none. */
87
+ function brandOf(value) {
88
+ const key = value[CEL_VALUE_TYPE];
89
+ return typeof key === "string" ? key : undefined;
90
+ }
91
+ export function isCelError(value) {
92
+ return typeof value === "object" && value !== null && brandOf(value) === "error";
93
+ }
94
+ export function isCelOptional(value) {
95
+ return typeof value === "object" && value !== null && brandOf(value) === "optional";
96
+ }
97
+ export function isCelUint(value) {
98
+ return typeof value === "object" && value !== null && brandOf(value) === "uint";
99
+ }
100
+ export function isCelMap(value) {
101
+ return typeof value === "object" && value !== null && brandOf(value) === "map";
102
+ }
103
+ export function isCelTimestamp(value) {
104
+ return typeof value === "object" && value !== null && brandOf(value) === "google.protobuf.Timestamp";
105
+ }
106
+ export function isCelDuration(value) {
107
+ return typeof value === "object" && value !== null && brandOf(value) === "google.protobuf.Duration";
108
+ }
109
+ export function isCelTypeValue(value) {
110
+ return typeof value === "object" && value !== null && brandOf(value) === "type";
111
+ }
112
+ /**
113
+ * Whether a value is bytes. `Object.prototype.toString` rather than `instanceof`, so a
114
+ * buffer built in another realm is still bytes — the same reason the brand is a
115
+ * registered symbol.
116
+ */
117
+ export function isCelBytes(value) {
118
+ return (typeof value === "object" &&
119
+ value !== null &&
120
+ Object.prototype.toString.call(value) === "[object Uint8Array]");
121
+ }
122
+ /**
123
+ * Whether a value is a map a host handed over: a plain object, not a branded one.
124
+ *
125
+ * The prototype decides, which is why nothing else needs checking: an array, a buffer and
126
+ * a class instance all have a prototype of their own, so none of them is a record. It is
127
+ * also the cheapest test there is, and this runs on every member read.
128
+ */
129
+ export function isCelRecord(value) {
130
+ if (typeof value !== "object" || value === null)
131
+ return false;
132
+ const prototype = Object.getPrototypeOf(value);
133
+ if (prototype !== Object.prototype && prototype !== null)
134
+ return false;
135
+ return brandOf(value) === undefined;
136
+ }
137
+ /**
138
+ * The name of a value's CEL type, or nothing when the value is of no CEL type. It is
139
+ * what `type()` answers and what an overload is dispatched on, so it must answer for
140
+ * **any** value — `type()` has no `dyn` overload to fall back on.
141
+ */
142
+ export function celTypeNameOf(value) {
143
+ switch (typeof value) {
144
+ case "boolean":
145
+ return "bool";
146
+ case "string":
147
+ return "string";
148
+ case "number":
149
+ return "double";
150
+ case "bigint":
151
+ return "int";
152
+ case "object":
153
+ break;
154
+ default:
155
+ return undefined;
156
+ }
157
+ if (value === null)
158
+ return "null_type";
159
+ const branded = brandOf(value);
160
+ if (branded !== undefined)
161
+ return branded === "error" ? undefined : branded;
162
+ // Ordered by what an expression meets most: a host's map, then a list, then bytes,
163
+ // whose test is the expensive one.
164
+ const prototype = Object.getPrototypeOf(value);
165
+ if (prototype === Object.prototype || prototype === null)
166
+ return "map";
167
+ if (Array.isArray(value))
168
+ return "list";
169
+ return isCelBytes(value) ? "bytes" : undefined;
170
+ }
171
+ /**
172
+ * A thenable reaching evaluation is refused, never passed along: evaluation is
173
+ * synchronous, and a promise flowing through an expression would be an invocation in
174
+ * disguise — invisible to a journal, absent from a trace, and unrepresentable as a
175
+ * step.
176
+ *
177
+ * The check is made at every **door** a host value comes through — an activation read, a
178
+ * registered implementation's result, a member read, an element entering a comprehension
179
+ * body, the value a name is bound to — and the list of them is in the package guide, which
180
+ * is where completeness is argued. `asyncValueRefused` is the one error they all answer
181
+ * with, so the code and the wording cannot drift between doors.
182
+ */
183
+ export function isThenable(value) {
184
+ return (typeof value === "object" &&
185
+ value !== null &&
186
+ typeof value.then === "function");
187
+ }
188
+ /**
189
+ * The refusal a value that must be awaited becomes, or nothing where it is an ordinary
190
+ * value.
191
+ *
192
+ * **A container is NOT walked**, and that is deliberate rather than a gap: a thenable inside
193
+ * a host list or map is refused when it becomes a value the engine reasons about — read by
194
+ * index, read as a member, or bound into a body — so every element costs one `typeof` when it
195
+ * is actually used, instead of every read costing a walk of what it returned.
196
+ */
197
+ export function asyncValueRefused(value, range) {
198
+ if (!isThenable(value))
199
+ return undefined;
200
+ return celError("async_value_unsupported", "a value that must be awaited reached evaluation, and CEL evaluates synchronously", range);
201
+ }
202
+ /**
203
+ * The value a literal node denotes. A tagged literal is not a bare host value — `1` and
204
+ * `1u` are different expressions — so the one reading of a tag lives here, where both
205
+ * backends and the checker's literal-argument guard reach it rather than each keeping a
206
+ * switch of its own.
207
+ */
208
+ export function literalValue(literal) {
209
+ switch (literal.type) {
210
+ case "int":
211
+ return literal.value;
212
+ case "uint":
213
+ return celUint(literal.value);
214
+ case "double":
215
+ return literal.value;
216
+ case "string":
217
+ return literal.value;
218
+ case "bytes":
219
+ return literal.value;
220
+ case "bool":
221
+ return literal.value;
222
+ case "null":
223
+ return null;
224
+ }
225
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * What the checker says, and the fact that **the checker says it**.
3
+ *
4
+ * Every verdict here carries its own code and the range of the text it is about. That
5
+ * is the whole point: an engine that reports one sentence for unrelated mistakes forces
6
+ * whoever consumes it to re-derive the cause afterwards from a registry it has to walk
7
+ * again — a classifier that can only ever explain, never decide, and that must stay
8
+ * silent on anything it cannot account for. The component that already knows decides
9
+ * here, once, and nothing downstream reads a message string.
10
+ *
11
+ * A **fix is a whole-source replacement**, never a sub-range splice. A CEL expression
12
+ * is usually one YAML scalar, an edit to it is applied by replacing that scalar, and a
13
+ * sub-range offset means something different the moment the scalar is re-indented.
14
+ */
15
+ import type { SourceRange } from "./syntax-tree.js";
16
+ /**
17
+ * Every verdict this engine decides. The type follows the list, so a code can only be
18
+ * added in one place and a host reading the vocabulary reads the same set the compiler
19
+ * holds every diagnostic to.
20
+ */
21
+ export declare const CEL_CHECK_CODES: readonly ["CEL_SYNTAX_ERROR", "CEL_TYPE_ERROR", "CEL_UNKNOWN_IDENTIFIER", "CEL_UNKNOWN_FIELD", "CEL_UNKNOWN_FUNCTION", "CEL_WRONG_CALL_FORM", "CEL_TYPE_ARGUMENT_MISMATCH", "CEL_NULLABLE_ACCESS", "CEL_INVALID_ARGUMENT", "FUNCTION_UNRESOLVED", "FUNCTION_ARITY_MISMATCH", "FUNCTION_ARGUMENT_MISMATCH"];
22
+ export type CelCheckCode = (typeof CEL_CHECK_CODES)[number];
23
+ export interface CelDiagnosticFix {
24
+ /** The whole expression, corrected. */
25
+ readonly replacement: string;
26
+ }
27
+ export interface CelCheckDiagnostic {
28
+ readonly code: CelCheckCode;
29
+ readonly message: string;
30
+ readonly range: SourceRange;
31
+ readonly fix?: CelDiagnosticFix;
32
+ }
33
+ /**
34
+ * An engine error: the caller used the engine wrongly, so nothing is checked or
35
+ * compiled. It is not a verdict about the expression — `unreadable_expression` is the
36
+ * refusal to compile a tree the front end already reported a syntax diagnostic for,
37
+ * which is a question the caller should have asked before compiling, and
38
+ * `emitted_module_rejected` is the refusal to run a loaded module whose integrity header
39
+ * is not the one the emission asked for, and `signature_too_wide` is a registration
40
+ * declaring more values than an implementation receives.
41
+ */
42
+ export type CelEngineErrorCode = "namespaces_mismatch" | "unreadable_expression" | "emitted_module_rejected" | "signature_too_wide";
43
+ export declare class CelEngineError extends Error {
44
+ readonly code: CelEngineErrorCode;
45
+ constructor(code: CelEngineErrorCode, message: string);
46
+ }
47
+ /** Collects diagnostics in discovery order, which is source order for one pass. */
48
+ export declare class DiagnosticList {
49
+ private readonly held;
50
+ add(diagnostic: CelCheckDiagnostic): void;
51
+ get length(): number;
52
+ list(): readonly CelCheckDiagnostic[];
53
+ }
54
+ //# sourceMappingURL=check-diagnostic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-diagnostic.d.ts","sourceRoot":"","sources":["../src/check-diagnostic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,eAAe,4SAyBlB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,GAAG,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAC1B,qBAAqB,GACrB,uBAAuB,GACvB,yBAAyB,GACzB,oBAAoB,CAAC;AAEzB,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;gBAEtB,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM;CAKtD;AAED,mFAAmF;AACnF,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IAEjD,GAAG,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI;IAIzC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,IAAI,SAAS,kBAAkB,EAAE;CAGtC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * What the checker says, and the fact that **the checker says it**.
3
+ *
4
+ * Every verdict here carries its own code and the range of the text it is about. That
5
+ * is the whole point: an engine that reports one sentence for unrelated mistakes forces
6
+ * whoever consumes it to re-derive the cause afterwards from a registry it has to walk
7
+ * again — a classifier that can only ever explain, never decide, and that must stay
8
+ * silent on anything it cannot account for. The component that already knows decides
9
+ * here, once, and nothing downstream reads a message string.
10
+ *
11
+ * A **fix is a whole-source replacement**, never a sub-range splice. A CEL expression
12
+ * is usually one YAML scalar, an edit to it is applied by replacing that scalar, and a
13
+ * sub-range offset means something different the moment the scalar is re-indented.
14
+ */
15
+ /**
16
+ * Every verdict this engine decides. The type follows the list, so a code can only be
17
+ * added in one place and a host reading the vocabulary reads the same set the compiler
18
+ * holds every diagnostic to.
19
+ */
20
+ export const CEL_CHECK_CODES = [
21
+ /** The source could not be read at all (the front end's verdict, carried through). */
22
+ "CEL_SYNTAX_ERROR",
23
+ /** A type is not the one the expression needs here. */
24
+ "CEL_TYPE_ERROR",
25
+ /** A name nothing declares. */
26
+ "CEL_UNKNOWN_IDENTIFIER",
27
+ /** A member a declared type does not hold. */
28
+ "CEL_UNKNOWN_FIELD",
29
+ /** A function nothing registers. */
30
+ "CEL_UNKNOWN_FUNCTION",
31
+ /** A registered function called in the other form — `x.f()` for `f(x)`, or back. */
32
+ "CEL_WRONG_CALL_FORM",
33
+ /** A named type whose type argument differs from the one wanted. */
34
+ "CEL_TYPE_ARGUMENT_MISMATCH",
35
+ /** A dereference of something that may be null, with no guard proving it is not. */
36
+ "CEL_NULLABLE_ACCESS",
37
+ /** An argument a construct refuses on sight — a macro's variable that is not a name. */
38
+ "CEL_INVALID_ARGUMENT",
39
+ /** A namespaced call naming a function the namespace does not declare. */
40
+ "FUNCTION_UNRESOLVED",
41
+ /** A namespaced call with the wrong number of arguments. */
42
+ "FUNCTION_ARITY_MISMATCH",
43
+ /** A namespaced call whose argument is not the declared type. */
44
+ "FUNCTION_ARGUMENT_MISMATCH",
45
+ ];
46
+ export class CelEngineError extends Error {
47
+ code;
48
+ constructor(code, message) {
49
+ super(message);
50
+ this.name = "CelEngineError";
51
+ this.code = code;
52
+ }
53
+ }
54
+ /** Collects diagnostics in discovery order, which is source order for one pass. */
55
+ export class DiagnosticList {
56
+ held = [];
57
+ add(diagnostic) {
58
+ this.held.push(diagnostic);
59
+ }
60
+ get length() {
61
+ return this.held.length;
62
+ }
63
+ list() {
64
+ return this.held;
65
+ }
66
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * The type checker: one walk, every verdict.
3
+ *
4
+ * It answers three things at once, because all three come from the same walk and
5
+ * nothing else can derive them: the type of the expression, every mistake in it with a
6
+ * range and a code, and which signature each call resolved to.
7
+ *
8
+ * Two properties are deliberate and worth keeping:
9
+ *
10
+ * - **One mistake is one diagnostic.** A subexpression that failed is typed `dyn`, so
11
+ * the operator above it does not report a second mistake about the first one. An
12
+ * editor shows what is wrong, not what is downstream of it.
13
+ * - **Nothing reads a message.** Every code is decided where the cause is known — an
14
+ * unknown name, a call written in the other form, a type argument that differs — and
15
+ * a repair, where there is an obvious one, is built by rewriting the tree and writing
16
+ * it back out, so a fix is always a whole source that parses.
17
+ */
18
+ import type { CelExpression } from "./cel-expression.js";
19
+ import type { CelType } from "./cel-type.js";
20
+ import type { CelCheckDiagnostic } from "./check-diagnostic.js";
21
+ import type { FunctionRegistry } from "./function-registry.js";
22
+ import type { ResolvedCall } from "./resolved-call.js";
23
+ /**
24
+ * A namespaced function the host has declared.
25
+ *
26
+ * **The parameter list is optional, and withholding it is structural rather than a flag.**
27
+ * A host whose own signature grammar is richer than this engine's — optional trailing
28
+ * parameters, a declared JSON Schema per parameter — judges arity and arguments itself and
29
+ * declares only what this engine needs to type the call's RESULT. There is deliberately no
30
+ * way to supply parameters and ask for them not to be judged: that shape would let a
31
+ * declaration carry a list nothing reads, which is the state a reader cannot tell from a
32
+ * list that is simply wrong.
33
+ */
34
+ export interface NamespaceFunction {
35
+ readonly name: string;
36
+ readonly returns: CelType;
37
+ /** Absent where the host withholds it; the call's arity and arguments are then unjudged. */
38
+ readonly parameters?: readonly CelType[];
39
+ /** How the declaration is written, for a listing; absent with the parameters. */
40
+ readonly signature?: string;
41
+ /**
42
+ * Types the declaration named that nothing is registered under, in the order written.
43
+ *
44
+ * The declaration is accepted and reads `dyn` where one stands: a host's declaration is
45
+ * data out of someone's manifest, so a name its own registry does not carry is the host
46
+ * disagreeing with itself — reported at the call, where there is a range, rather than
47
+ * thrown at registration, where there is none. Same rule as an unjudged schema node.
48
+ */
49
+ readonly unregisteredTypes?: readonly string[];
50
+ readonly deterministic?: boolean;
51
+ readonly hostBacked?: boolean;
52
+ readonly throws?: readonly string[];
53
+ }
54
+ export interface CheckerOptions {
55
+ readonly unlistedVariablesAreDyn: boolean;
56
+ readonly homogeneousAggregateLiterals: boolean;
57
+ readonly enableOptionalTypes: boolean;
58
+ }
59
+ /** Everything the checker reads about the environment it is checking against. */
60
+ export interface CheckerContext {
61
+ readonly registry: FunctionRegistry;
62
+ readonly variable: (name: string) => CelType | undefined;
63
+ readonly declaredVariableNames: () => readonly string[];
64
+ readonly namespaceFunction: (namespace: string, name: string) => NamespaceFunction | undefined;
65
+ /**
66
+ * Whether a namespace declares every function reachable through it. An **open** namespace
67
+ * does not: a name it did not declare types `dyn`, is listed as a call, and is reported by
68
+ * nobody — the host resolves such a name against its own vocabulary (an export gate, a
69
+ * capability, a re-export chain) and words that verdict itself. Refusing it here would be
70
+ * this engine deciding a question only the host can answer, and the host would then have to
71
+ * suppress the refusal, which is the after-the-fact classifier this engine exists to retire.
72
+ */
73
+ readonly namespaceIsOpen: (namespace: string) => boolean;
74
+ readonly options: CheckerOptions;
75
+ }
76
+ export interface CheckResult {
77
+ readonly valid: boolean;
78
+ /** The type of the whole expression; `dyn` where something failed. */
79
+ readonly type: CelType;
80
+ /** How that type is written. */
81
+ readonly typeName: string;
82
+ readonly diagnostics: readonly CelCheckDiagnostic[];
83
+ readonly calls: readonly ResolvedCall[];
84
+ }
85
+ export declare function checkExpression(expression: CelExpression, context: CheckerContext): CheckResult;
86
+ //# sourceMappingURL=checker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checker.d.ts","sourceRoot":"","sources":["../src/checker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAc,MAAM,eAAe,CAAC;AAyBzD,OAAO,KAAK,EAAgB,kBAAkB,EAAoB,MAAM,uBAAuB,CAAC;AAGhG,OAAO,KAAK,EAAE,gBAAgB,EAAyC,MAAM,wBAAwB,CAAC;AAKtG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAYvD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,4FAA4F;IAC5F,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IACzC,iFAAiF;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;OAOG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC;IAC1C,QAAQ,CAAC,4BAA4B,EAAE,OAAO,CAAC;IAC/C,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;CACvC;AAED,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAAG,SAAS,CAAC;IACzD,QAAQ,CAAC,qBAAqB,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;IACxD,QAAQ,CAAC,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,iBAAiB,GAAG,SAAS,CAAC;IAC/F;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IACzD,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,gCAAgC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACpD,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;CACzC;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,GAAG,WAAW,CAG/F"}