@usine/expression 0.2.0 → 0.4.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/README.md CHANGED
@@ -1,17 +1,17 @@
1
1
  # @usine/expression
2
2
 
3
- Typed CEL checking and evaluation for [usine](https://github.com/basaltbytes/usine). Callers describe object types and root variables with `Environment`, then use `ExpressionEngine` to check boolean trigger expressions, check scalar prompt expressions, or evaluate either form over plain JSON.
3
+ Typed CEL checking and evaluation for [usine](https://github.com/basaltbytes/usine). Describe types and root variables with `Environment`. `ExpressionEngine` then checks boolean trigger and scalar prompt expressions, and evaluates them over plain JSON.
4
4
 
5
- Unknown variables and object paths fail during checking, including paths inside CEL macros such as `exists`. Failures are typed values: `ExpressionCheckError` from parsing, type checking, or result-type checking, `ExpressionEvaluationError` from evaluation, and the `ExpressionError` union covering both. JSON integers declared as CEL `int` or `uint` are converted to `bigint` before evaluation so GraphQL payloads keep CEL integer semantics.
5
+ Import `ExpressionEngine`, `Source`, `Environment`, the environment descriptors, `Scalar`, and the typed errors from `@usine/expression/expression-engine`, which replaces `@usine/expression/model`. The CEL adapter layer is in `@usine/expression/marcbachmann-cel`.
6
6
 
7
- `relatedStringLiterals(source, memberPath)` reports string literals from the smallest expression subtrees that use a member path. Config validation uses it to diagnose undeclared GitHub labels without coupling `@usine/config` to the CEL adapter's AST.
7
+ A `nullable` `ObjectField` can be `null`, and an absent key reads as `null`. Expressions compare it with `null` in either order, and paths below it stay type-checked. Unknown variables and paths fail checking, also inside macros such as `exists`.
8
8
 
9
- `MarcbachmannCelLayer` uses `@marcbachmann/cel-js@8.0.0`. The exported `ExpressionEngine` contract contains CEL type names and usine-owned descriptors rather than library objects; an `@bufbuild/cel` adapter can provide the same service tag without changing callers.
9
+ Expressions can use CEL optional values: `.?` and `[?]` select a value that might be missing, and `optional` helpers such as `orValue` give a fallback. `item.?milestone.?title.orValue("none")` is `"none"` if `milestone` is null or absent. A null field counts as present, so `item.?milestone` holds `null`, not an empty optional.
10
10
 
11
- All APIs remain 0.x and can change between minor releases.
11
+ Errors: `ExpressionCheckError` (parse, type, or result type), `ExpressionEvaluationError`, and the union `ExpressionError`. JSON integers declared as CEL `int` or `uint` become `bigint` before evaluation, so GraphQL payloads keep CEL integer semantics.
12
12
 
13
- Import `ExpressionEngine`, `Source`, `Environment`, the environment descriptors,
14
- `Scalar`, and the typed expression errors from `@usine/expression/expression-engine`.
15
- This entry point replaces `@usine/expression/model`; existing imports from that
16
- subpath must use `/expression-engine`. Import the CEL adapter layer separately
17
- from `@usine/expression/marcbachmann-cel`.
13
+ `relatedStringLiterals(source, memberPath)` returns string literals from the smallest subtrees that use a member path. It accepts the same syntax as the checks, including `.?`. Config validation uses it to report undeclared labels without depending on the CEL AST.
14
+
15
+ `MarcbachmannCelLayer` uses `@marcbachmann/cel-js@8.0.0`. The contract uses CEL type names and usine descriptors, not library objects; an `@bufbuild/cel` adapter can provide the same tag.
16
+
17
+ The 0.x APIs can change between minor releases.
@@ -1,33 +1,43 @@
1
1
  import { Schema } from "effect";
2
- /** A type name in CEL syntax such as `string`, `Issue`, or `list<Label>`. */
2
+ /**
3
+ * A CEL type name without spaces, such as `string`, `Label`, `list<T>`, or `map<K,V>`.
4
+ * Decoding checks only the syntax; an undeclared object type fails when an expression is checked.
5
+ */
3
6
  export declare const TypeReference: Schema.brand<Schema.String, "CelTypeReference">;
4
7
  export type TypeReference = typeof TypeReference.Type;
5
8
  declare const ObjectField_base: Schema.Class<ObjectField, Schema.Struct<{
6
9
  readonly name: Schema.String;
10
+ /** The CEL type of a non-`null` value. */
7
11
  readonly type: Schema.brand<Schema.String, "CelTypeReference">;
12
+ /** Whether the value can be `null` or absent. Reading an absent non-nullable field fails evaluation. */
13
+ readonly nullable: Schema.withConstructorDefault<Schema.Boolean>;
8
14
  }>, {}>;
9
- /** One named field and its CEL type within an object descriptor. */
15
+ /** A field of an {@link ObjectType}. If the field is nullable and its key is absent, it evaluates to `null`. */
10
16
  export declare class ObjectField extends ObjectField_base {
11
17
  }
12
18
  declare const ObjectType_base: Schema.Class<ObjectType, Schema.Struct<{
13
19
  readonly name: Schema.String;
14
20
  readonly fields: Schema.$Array<typeof ObjectField>;
15
21
  }>, {}>;
16
- /** A CEL object type. Declare a type before the types that reference it. */
22
+ /** An object type that expressions can read fields from, such as `IssuePayload`. */
17
23
  export declare class ObjectType extends ObjectType_base {
18
24
  }
19
25
  declare const Variable_base: Schema.Class<Variable, Schema.Struct<{
20
26
  readonly name: Schema.String;
21
27
  readonly type: Schema.brand<Schema.String, "CelTypeReference">;
22
28
  }>, {}>;
23
- /** A root variable available to CEL expressions in an Environment. */
29
+ /** A root variable, such as `repo` or `item`, whose value is the `context` entry with the same name. */
24
30
  export declare class Variable extends Variable_base {
25
31
  }
26
32
  declare const Environment_base: Schema.Class<Environment, Schema.Struct<{
33
+ /** The object types, each declared before any type whose fields reference it. */
27
34
  readonly types: Schema.$Array<typeof ObjectType>;
28
35
  readonly variables: Schema.$Array<typeof Variable>;
29
36
  }>, {}>;
30
- /** The types and root variables an expression is checked and evaluated against. */
37
+ /**
38
+ * The types and root variables that expressions are checked and evaluated against. An
39
+ * expression that references anything else fails checking.
40
+ */
31
41
  export declare class Environment extends Environment_base {
32
42
  }
33
43
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,6EAA6E;AAC7E,eAAO,MAAM,aAAa,iDAKc,CAAC;AACzC,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC;;;;;AAkBtD,oEAAoE;AACpE,qBAAa,WAAY,SAAQ,gBAG/B;CAAG;;;;;AAEL,4EAA4E;AAC5E,qBAAa,UAAW,SAAQ,eAG9B;CAAG;;;;;AAEL,sEAAsE;AACtE,qBAAa,QAAS,SAAQ,aAG5B;CAAG;;;;;AAEL,mFAAmF;AACnF,qBAAa,WAAY,SAAQ,gBAG/B;CAAG"}
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,aAAa,iDAKc,CAAC;AACzC,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC;;;IAqBpD,0CAA0C;;IAE1C,wGAAwG;;;AAL1G,gHAAgH;AAChH,qBAAa,WAAY,SAAQ,gBAM/B;CAAG;;;;;AAEL,oFAAoF;AACpF,qBAAa,UAAW,SAAQ,eAG9B;CAAG;;;;;AAEL,wGAAwG;AACxG,qBAAa,QAAS,SAAQ,aAG5B;CAAG;;IAOH,iFAAiF;;;;AALnF;;;GAGG;AACH,qBAAa,WAAY,SAAQ,gBAI/B;CAAG"}
@@ -1,31 +1,41 @@
1
- import { Schema } from "effect";
2
- /** A type name in CEL syntax such as `string`, `Issue`, or `list<Label>`. */
1
+ import { Effect, Schema } from "effect";
2
+ /**
3
+ * A CEL type name without spaces, such as `string`, `Label`, `list<T>`, or `map<K,V>`.
4
+ * Decoding checks only the syntax; an undeclared object type fails when an expression is checked.
5
+ */
3
6
  export const TypeReference = Schema.String.check(Schema.isPattern(/^(?:[A-Za-z_][A-Za-z0-9_.]*|list<[A-Za-z_][A-Za-z0-9_.]*>|map<[A-Za-z_][A-Za-z0-9_.]*,[A-Za-z_][A-Za-z0-9_.]*>)$/u, { message: "Expected a CEL type reference" })).pipe(Schema.brand("CelTypeReference"));
4
7
  const Identifier = Schema.String.check(Schema.isPattern(/^[A-Za-z_][A-Za-z0-9_]*$/u, { message: "Expected a CEL identifier" }));
5
8
  const ObjectTypeName = Schema.String.check(Schema.isPattern(/^[A-Za-z_][A-Za-z0-9_.]*$/u, {
6
9
  message: "Expected a CEL object-type name",
7
10
  }));
8
11
  const uniqueNames = (message) => Schema.makeFilter((values) => new Set(values.map(({ name }) => name)).size === values.length, { message });
9
- /** One named field and its CEL type within an object descriptor. */
12
+ /** A field of an {@link ObjectType}. If the field is nullable and its key is absent, it evaluates to `null`. */
10
13
  export class ObjectField extends Schema.Class("@usine/expression/ObjectField")({
11
14
  name: Identifier,
15
+ /** The CEL type of a non-`null` value. */
12
16
  type: TypeReference,
17
+ /** Whether the value can be `null` or absent. Reading an absent non-nullable field fails evaluation. */
18
+ nullable: Schema.Boolean.pipe(Schema.withConstructorDefault(Effect.succeed(false))),
13
19
  }) {
14
20
  }
15
- /** A CEL object type. Declare a type before the types that reference it. */
21
+ /** An object type that expressions can read fields from, such as `IssuePayload`. */
16
22
  export class ObjectType extends Schema.Class("@usine/expression/ObjectType")({
17
23
  name: ObjectTypeName,
18
24
  fields: Schema.Array(ObjectField).check(uniqueNames("Expected unique CEL object-field names")),
19
25
  }) {
20
26
  }
21
- /** A root variable available to CEL expressions in an Environment. */
27
+ /** A root variable, such as `repo` or `item`, whose value is the `context` entry with the same name. */
22
28
  export class Variable extends Schema.Class("@usine/expression/Variable")({
23
29
  name: Identifier,
24
30
  type: TypeReference,
25
31
  }) {
26
32
  }
27
- /** The types and root variables an expression is checked and evaluated against. */
33
+ /**
34
+ * The types and root variables that expressions are checked and evaluated against. An
35
+ * expression that references anything else fails checking.
36
+ */
28
37
  export class Environment extends Schema.Class("@usine/expression/Environment")({
38
+ /** The object types, each declared before any type whose fields reference it. */
29
39
  types: Schema.Array(ObjectType).check(uniqueNames("Expected unique CEL object-type names")),
30
40
  variables: Schema.Array(Variable).check(uniqueNames("Expected unique CEL variable names")),
31
41
  }) {
@@ -1 +1 @@
1
- {"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAC9C,MAAM,CAAC,SAAS,CACd,mHAAmH,EACnH,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAC7C,CACF,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAGzC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CACpC,MAAM,CAAC,SAAS,CAAC,2BAA2B,EAAE,EAAE,OAAO,EAAE,2BAA2B,EAAE,CAAC,CACxF,CAAC;AAEF,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CACxC,MAAM,CAAC,SAAS,CAAC,4BAA4B,EAAE;IAC7C,OAAO,EAAE,iCAAiC;CAC3C,CAAC,CACH,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,EAAE,CACtC,MAAM,CAAC,UAAU,CACf,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,EAC1E,EAAE,OAAO,EAAE,CACZ,CAAC;AAEJ,oEAAoE;AACpE,MAAM,OAAO,WAAY,SAAQ,MAAM,CAAC,KAAK,CAAc,+BAA+B,CAAC,CAAC;IAC1F,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,aAAa;CACpB,CAAC;CAAG;AAEL,4EAA4E;AAC5E,MAAM,OAAO,UAAW,SAAQ,MAAM,CAAC,KAAK,CAAa,8BAA8B,CAAC,CAAC;IACvF,IAAI,EAAE,cAAc;IACpB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,wCAAwC,CAAC,CAAC;CAC/F,CAAC;CAAG;AAEL,sEAAsE;AACtE,MAAM,OAAO,QAAS,SAAQ,MAAM,CAAC,KAAK,CAAW,4BAA4B,CAAC,CAAC;IACjF,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,aAAa;CACpB,CAAC;CAAG;AAEL,mFAAmF;AACnF,MAAM,OAAO,WAAY,SAAQ,MAAM,CAAC,KAAK,CAAc,+BAA+B,CAAC,CAAC;IAC1F,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,uCAAuC,CAAC,CAAC;IAC3F,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,oCAAoC,CAAC,CAAC;CAC3F,CAAC;CAAG"}
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAC9C,MAAM,CAAC,SAAS,CACd,mHAAmH,EACnH,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAC7C,CACF,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAGzC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CACpC,MAAM,CAAC,SAAS,CAAC,2BAA2B,EAAE,EAAE,OAAO,EAAE,2BAA2B,EAAE,CAAC,CACxF,CAAC;AAEF,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CACxC,MAAM,CAAC,SAAS,CAAC,4BAA4B,EAAE;IAC7C,OAAO,EAAE,iCAAiC;CAC3C,CAAC,CACH,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,EAAE,CACtC,MAAM,CAAC,UAAU,CACf,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,EAC1E,EAAE,OAAO,EAAE,CACZ,CAAC;AAEJ,gHAAgH;AAChH,MAAM,OAAO,WAAY,SAAQ,MAAM,CAAC,KAAK,CAAc,+BAA+B,CAAC,CAAC;IAC1F,IAAI,EAAE,UAAU;IAChB,0CAA0C;IAC1C,IAAI,EAAE,aAAa;IACnB,wGAAwG;IACxG,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;CACpF,CAAC;CAAG;AAEL,oFAAoF;AACpF,MAAM,OAAO,UAAW,SAAQ,MAAM,CAAC,KAAK,CAAa,8BAA8B,CAAC,CAAC;IACvF,IAAI,EAAE,cAAc;IACpB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,wCAAwC,CAAC,CAAC;CAC/F,CAAC;CAAG;AAEL,wGAAwG;AACxG,MAAM,OAAO,QAAS,SAAQ,MAAM,CAAC,KAAK,CAAW,4BAA4B,CAAC,CAAC;IACjF,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,aAAa;CACpB,CAAC;CAAG;AAEL;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,MAAM,CAAC,KAAK,CAAc,+BAA+B,CAAC,CAAC;IAC1F,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,uCAAuC,CAAC,CAAC;IAC3F,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,oCAAoC,CAAC,CAAC;CAC3F,CAAC;CAAG"}
@@ -1,52 +1,82 @@
1
- import { Context, type Effect, Schema } from "effect";
1
+ import { Context, type Effect, type Result, Schema } from "effect";
2
2
  import type { Environment } from "./environment.ts";
3
- /** Non-blank CEL source text. */
3
+ /**
4
+ * The text of a CEL expression, such as a Loop's `if:` condition or a `{{ }}` interpolation.
5
+ * Decoding rejects blank text; {@link ExpressionEngine} checks syntax and types.
6
+ */
4
7
  export declare const Source: Schema.brand<Schema.String, "ExpressionSource">;
5
8
  export type Source = typeof Source.Type;
6
- /** Whether checking failed during parsing, type resolution, or result-type validation. */
9
+ /**
10
+ * - `parse_error`: the source is not valid CEL syntax.
11
+ * - `type_error`: the source references an unknown variable or field, or combines
12
+ * incompatible types.
13
+ * - `unexpected_result_type`: the result type is wrong for the operation, such as a non-`bool`
14
+ * selection condition.
15
+ * - `check_failed`: the CEL implementation rejected the {@link Environment} itself, such as an
16
+ * undeclared type name, or failed without a detail.
17
+ */
7
18
  export declare const CheckErrorCode: Schema.Literals<readonly ["check_failed", "parse_error", "type_error", "unexpected_result_type"]>;
8
19
  export type CheckErrorCode = typeof CheckErrorCode.Type;
9
20
  declare const ExpressionCheckError_base: Schema.Class<ExpressionCheckError, Schema.TaggedStruct<"ExpressionCheckError", {
10
21
  readonly source: Schema.brand<Schema.String, "ExpressionSource">;
11
22
  readonly code: Schema.Literals<readonly ["check_failed", "parse_error", "type_error", "unexpected_result_type"]>;
23
+ /**
24
+ * A human-readable description, possibly multi-line with a marked excerpt of `source`. The
25
+ * wording isn't stable; branch on `code`.
26
+ */
12
27
  readonly message: Schema.NonEmptyString;
28
+ /**
29
+ * The zero-based offset in `source` where the failure starts. Always `None` for
30
+ * `unexpected_result_type` and `check_failed`.
31
+ */
13
32
  readonly position: Schema.Option<Schema.Int>;
14
33
  }>, import("effect/Cause").YieldableError>;
15
- /** The expression failed to parse, to type-check, or to produce the expected result type. */
34
+ /** An error from checking an expression against an {@link Environment}; checking never reads a payload. */
16
35
  export declare class ExpressionCheckError extends ExpressionCheckError_base {
17
36
  }
18
37
  declare const ExpressionEvaluationError_base: Schema.Class<ExpressionEvaluationError, Schema.TaggedStruct<"ExpressionEvaluationError", {
19
38
  readonly source: Schema.brand<Schema.String, "ExpressionSource">;
39
+ /** A human-readable description, possibly multi-line with a marked excerpt of `source`. The wording isn't stable. */
20
40
  readonly message: Schema.NonEmptyString;
21
41
  }>, import("effect/Cause").YieldableError>;
22
- /** Evaluation failed on an expression that had already checked. */
42
+ /**
43
+ * An error from evaluating a checked expression, such as a missing `context` key, a value of the
44
+ * wrong type, division by zero, or an out-of-range list index.
45
+ */
23
46
  export declare class ExpressionEvaluationError extends ExpressionEvaluationError_base {
24
47
  }
25
- /** The failures callers can receive when checking or evaluating a CEL expression. */
26
48
  export declare const ExpressionError: Schema.Union<readonly [typeof ExpressionCheckError, typeof ExpressionEvaluationError]>;
27
49
  export type ExpressionError = typeof ExpressionError.Type;
28
- /** Values prompt interpolation can render. CEL ints stay bigint. */
50
+ /**
51
+ * The result of a prompt interpolation; CEL `int` is a `bigint` and `double` is a `number`. A
52
+ * `uint` result passes `checkScalar`, but `evaluateScalar` fails with
53
+ * {@link ExpressionEvaluationError}; wrap it in `string(...)` or `double(...)`.
54
+ */
29
55
  export declare const Scalar: Schema.Union<readonly [Schema.String, Schema.Number, Schema.BigInt, Schema.Boolean, Schema.Null]>;
30
56
  export type Scalar = typeof Scalar.Type;
31
- /** Checks and evaluates the expressions used to select Items and fill Loop task templates. */
32
57
  export interface ExpressionEngineService {
33
58
  /**
34
- * The string literals the expression compares against the `name` field of
35
- * values reached from `memberPath`, following macro bindings and collection
36
- * transformations. Config validation uses it to spot undeclared labels.
59
+ * Returns the string literals compared with the `name` field of values under `memberPath`,
60
+ * following macro bindings and collection transformations. Accepts the same syntax as
61
+ * `checkBoolean` and `checkScalar`, including optional selection (`.?`).
37
62
  */
38
63
  readonly relatedStringLiterals: (source: Source, memberPath: ReadonlyArray<string>) => Effect.Effect<ReadonlyArray<string>, ExpressionCheckError>;
39
- /** Checks whether the expression can select Items, without evaluating a payload. */
64
+ /** Checks that the expression has type `bool`. */
40
65
  readonly checkBoolean: (source: Source, environment: Environment) => Effect.Effect<void, ExpressionCheckError>;
41
- /** Checks whether the expression can produce one value for prompt interpolation. */
66
+ /** Checks that the expression can be a prompt interpolation. */
42
67
  readonly checkScalar: (source: Source, environment: Environment) => Effect.Effect<void, ExpressionCheckError>;
43
- /** Checks and evaluates a selection condition; `context` supplies values for the environment's root variables. */
68
+ /** Checks and evaluates a selection condition against `context`. */
44
69
  readonly evaluateBoolean: (source: Source, environment: Environment, context: Schema.JsonObject) => Effect.Effect<boolean, ExpressionError>;
45
- /** Checks and evaluates a prompt interpolation; `context` supplies values for the environment's root variables. */
70
+ /**
71
+ * Checks the condition once and evaluates it against each of `contexts`, returning one
72
+ * `Result` per context in order. Fails with `ExpressionCheckError` if the check fails.
73
+ */
74
+ readonly evaluateBooleanEach: (source: Source, environment: Environment, contexts: ReadonlyArray<Schema.JsonObject>) => Effect.Effect<ReadonlyArray<Result.Result<boolean, ExpressionEvaluationError>>, ExpressionCheckError>;
75
+ /** Checks and evaluates a prompt interpolation against `context`. */
46
76
  readonly evaluateScalar: (source: Source, environment: Environment, context: Schema.JsonObject) => Effect.Effect<Scalar, ExpressionError>;
47
77
  }
48
78
  declare const ExpressionEngine_base: Context.ServiceClass<ExpressionEngine, "@usine/expression/ExpressionEngine", ExpressionEngineService>;
49
- /** Evaluates Loop conditions and prompt expressions against their declared payload context. */
79
+ /** The CEL expression service, provided by `MarcbachmannCelLayer` from `@usine/expression/marcbachmann-cel`. */
50
80
  export declare class ExpressionEngine extends ExpressionEngine_base {
51
81
  }
52
82
  export { TypeReference, ObjectField, ObjectType, Variable, Environment } from "./environment.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"expression-engine.d.ts","sourceRoot":"","sources":["../src/expression-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,iCAAiC;AACjC,eAAO,MAAM,MAAM,iDAEqB,CAAC;AACzC,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,IAAI,CAAC;AAIxC,0FAA0F;AAC1F,eAAO,MAAM,cAAc,mGAKzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAC;;;;;;;AAExD,6FAA6F;AAC7F,qBAAa,oBAAqB,SAAQ,yBAOxC;CAAG;;;;;AAEL,mEAAmE;AACnE,qBAAa,yBAA0B,SAAQ,8BAK7C;CAAG;AAEL,qFAAqF;AACrF,eAAO,MAAM,eAAe,wFAAkE,CAAC;AAC/F,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAC;AAE1D,oEAAoE;AACpE,eAAO,MAAM,MAAM,mGAMjB,CAAC;AACH,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,IAAI,CAAC;AAExC,8FAA8F;AAC9F,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,QAAQ,CAAC,qBAAqB,EAAE,CAC9B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,KAC9B,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAC,CAAC;IAChE,oFAAoF;IACpF,QAAQ,CAAC,YAAY,EAAE,CACrB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,KACrB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;IAC/C,oFAAoF;IACpF,QAAQ,CAAC,WAAW,EAAE,CACpB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,KACrB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;IAC/C,kHAAkH;IAClH,QAAQ,CAAC,eAAe,EAAE,CACxB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,MAAM,CAAC,UAAU,KACvB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAC7C,mHAAmH;IACnH,QAAQ,CAAC,cAAc,EAAE,CACvB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,MAAM,CAAC,UAAU,KACvB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC7C;;AAED,+FAA+F;AAC/F,qBAAa,gBAAiB,SAAQ,qBAErC;CAAG;AAEJ,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"expression-engine.d.ts","sourceRoot":"","sources":["../src/expression-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,MAAM,iDAEqB,CAAC;AACzC,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,IAAI,CAAC;AAIxC;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,mGAKzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAC;;;;IAQtD;;;OAGG;;IAEH;;;OAGG;;;AAdL,2GAA2G;AAC3G,qBAAa,oBAAqB,SAAQ,yBAexC;CAAG;;;IAUH,qHAAqH;;;AARvH;;;GAGG;AACH,qBAAa,yBAA0B,SAAQ,8BAM7C;CAAG;AAEL,eAAO,MAAM,eAAe,wFAAkE,CAAC;AAC/F,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,MAAM,mGAMjB,CAAC;AACH,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,IAAI,CAAC;AAExC,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,QAAQ,CAAC,qBAAqB,EAAE,CAC9B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,KAC9B,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAC,CAAC;IAChE,kDAAkD;IAClD,QAAQ,CAAC,YAAY,EAAE,CACrB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,KACrB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;IAC/C,gEAAgE;IAChE,QAAQ,CAAC,WAAW,EAAE,CACpB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,KACrB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;IAC/C,oEAAoE;IACpE,QAAQ,CAAC,eAAe,EAAE,CACxB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,MAAM,CAAC,UAAU,KACvB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAC7C;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,EAAE,CAC5B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,KACvC,MAAM,CAAC,MAAM,CAChB,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,yBAAyB,CAAC,CAAC,EAChE,oBAAoB,CACrB,CAAC;IACF,qEAAqE;IACrE,QAAQ,CAAC,cAAc,EAAE,CACvB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,MAAM,CAAC,UAAU,KACvB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC7C;;AAED,gHAAgH;AAChH,qBAAa,gBAAiB,SAAQ,qBAErC;CAAG;AAEJ,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,31 +1,57 @@
1
1
  import { Context, Schema } from "effect";
2
- /** Non-blank CEL source text. */
2
+ /**
3
+ * The text of a CEL expression, such as a Loop's `if:` condition or a `{{ }}` interpolation.
4
+ * Decoding rejects blank text; {@link ExpressionEngine} checks syntax and types.
5
+ */
3
6
  export const Source = Schema.String.check(Schema.isPattern(/\S/u, { message: "Expected a non-blank CEL expression" })).pipe(Schema.brand("ExpressionSource"));
4
7
  const Position = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));
5
- /** Whether checking failed during parsing, type resolution, or result-type validation. */
8
+ /**
9
+ * - `parse_error`: the source is not valid CEL syntax.
10
+ * - `type_error`: the source references an unknown variable or field, or combines
11
+ * incompatible types.
12
+ * - `unexpected_result_type`: the result type is wrong for the operation, such as a non-`bool`
13
+ * selection condition.
14
+ * - `check_failed`: the CEL implementation rejected the {@link Environment} itself, such as an
15
+ * undeclared type name, or failed without a detail.
16
+ */
6
17
  export const CheckErrorCode = Schema.Literals([
7
18
  "check_failed",
8
19
  "parse_error",
9
20
  "type_error",
10
21
  "unexpected_result_type",
11
22
  ]);
12
- /** The expression failed to parse, to type-check, or to produce the expected result type. */
23
+ /** An error from checking an expression against an {@link Environment}; checking never reads a payload. */
13
24
  export class ExpressionCheckError extends Schema.TaggedError("@usine/expression/ExpressionCheckError")("ExpressionCheckError", {
14
25
  source: Source,
15
26
  code: CheckErrorCode,
27
+ /**
28
+ * A human-readable description, possibly multi-line with a marked excerpt of `source`. The
29
+ * wording isn't stable; branch on `code`.
30
+ */
16
31
  message: Schema.NonEmptyString,
32
+ /**
33
+ * The zero-based offset in `source` where the failure starts. Always `None` for
34
+ * `unexpected_result_type` and `check_failed`.
35
+ */
17
36
  position: Schema.Option(Position),
18
37
  }) {
19
38
  }
20
- /** Evaluation failed on an expression that had already checked. */
39
+ /**
40
+ * An error from evaluating a checked expression, such as a missing `context` key, a value of the
41
+ * wrong type, division by zero, or an out-of-range list index.
42
+ */
21
43
  export class ExpressionEvaluationError extends Schema.TaggedError("@usine/expression/ExpressionEvaluationError")("ExpressionEvaluationError", {
22
44
  source: Source,
45
+ /** A human-readable description, possibly multi-line with a marked excerpt of `source`. The wording isn't stable. */
23
46
  message: Schema.NonEmptyString,
24
47
  }) {
25
48
  }
26
- /** The failures callers can receive when checking or evaluating a CEL expression. */
27
49
  export const ExpressionError = Schema.Union([ExpressionCheckError, ExpressionEvaluationError]);
28
- /** Values prompt interpolation can render. CEL ints stay bigint. */
50
+ /**
51
+ * The result of a prompt interpolation; CEL `int` is a `bigint` and `double` is a `number`. A
52
+ * `uint` result passes `checkScalar`, but `evaluateScalar` fails with
53
+ * {@link ExpressionEvaluationError}; wrap it in `string(...)` or `double(...)`.
54
+ */
29
55
  export const Scalar = Schema.Union([
30
56
  Schema.String,
31
57
  Schema.Number,
@@ -33,7 +59,7 @@ export const Scalar = Schema.Union([
33
59
  Schema.Boolean,
34
60
  Schema.Null,
35
61
  ]);
36
- /** Evaluates Loop conditions and prompt expressions against their declared payload context. */
62
+ /** The CEL expression service, provided by `MarcbachmannCelLayer` from `@usine/expression/marcbachmann-cel`. */
37
63
  export class ExpressionEngine extends Context.Service()("@usine/expression/ExpressionEngine") {
38
64
  }
39
65
  export { TypeReference, ObjectField, ObjectType, Variable, Environment } from "./environment.js";
@@ -1 +1 @@
1
- {"version":3,"file":"expression-engine.js","sourceRoot":"","sources":["../src/expression-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGtD,iCAAiC;AACjC,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CACvC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,qCAAqC,EAAE,CAAC,CAC5E,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAGzC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE,0FAA0F;AAC1F,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC5C,cAAc;IACd,aAAa;IACb,YAAY;IACZ,wBAAwB;CACzB,CAAC,CAAC;AAGH,6FAA6F;AAC7F,MAAM,OAAO,oBAAqB,SAAQ,MAAM,CAAC,WAAW,CAC1D,wCAAwC,CACzC,CAAC,sBAAsB,EAAE;IACxB,MAAM,EAAE,MAAM;IACd,IAAI,EAAE,cAAc;IACpB,OAAO,EAAE,MAAM,CAAC,cAAc;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;CAClC,CAAC;CAAG;AAEL,mEAAmE;AACnE,MAAM,OAAO,yBAA0B,SAAQ,MAAM,CAAC,WAAW,CAC/D,6CAA6C,CAC9C,CAAC,2BAA2B,EAAE;IAC7B,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,MAAM,CAAC,cAAc;CAC/B,CAAC;CAAG;AAEL,qFAAqF;AACrF,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,EAAE,yBAAyB,CAAC,CAAC,CAAC;AAG/F,oEAAoE;AACpE,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;IACjC,MAAM,CAAC,MAAM;IACb,MAAM,CAAC,MAAM;IACb,MAAM,CAAC,MAAM;IACb,MAAM,CAAC,OAAO;IACd,MAAM,CAAC,IAAI;CACZ,CAAC,CAAC;AAsCH,+FAA+F;AAC/F,MAAM,OAAO,gBAAiB,SAAQ,OAAO,CAAC,OAAO,EAA6C,CAChG,oCAAoC,CACrC;CAAG;AAEJ,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"expression-engine.js","sourceRoot":"","sources":["../src/expression-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAA4B,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGnE;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CACvC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,qCAAqC,EAAE,CAAC,CAC5E,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAGzC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC5C,cAAc;IACd,aAAa;IACb,YAAY;IACZ,wBAAwB;CACzB,CAAC,CAAC;AAGH,2GAA2G;AAC3G,MAAM,OAAO,oBAAqB,SAAQ,MAAM,CAAC,WAAW,CAC1D,wCAAwC,CACzC,CAAC,sBAAsB,EAAE;IACxB,MAAM,EAAE,MAAM;IACd,IAAI,EAAE,cAAc;IACpB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC,cAAc;IAC9B;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;CAClC,CAAC;CAAG;AAEL;;;GAGG;AACH,MAAM,OAAO,yBAA0B,SAAQ,MAAM,CAAC,WAAW,CAC/D,6CAA6C,CAC9C,CAAC,2BAA2B,EAAE;IAC7B,MAAM,EAAE,MAAM;IACd,qHAAqH;IACrH,OAAO,EAAE,MAAM,CAAC,cAAc;CAC/B,CAAC;CAAG;AAEL,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,EAAE,yBAAyB,CAAC,CAAC,CAAC;AAG/F;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;IACjC,MAAM,CAAC,MAAM;IACb,MAAM,CAAC,MAAM;IACb,MAAM,CAAC,MAAM;IACb,MAAM,CAAC,OAAO;IACd,MAAM,CAAC,IAAI;CACZ,CAAC,CAAC;AAiDH,gHAAgH;AAChH,MAAM,OAAO,gBAAiB,SAAQ,OAAO,CAAC,OAAO,EAA6C,CAChG,oCAAoC,CACrC;CAAG;AAEJ,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,5 +1,20 @@
1
1
  import { Layer } from "effect";
2
2
  import { ExpressionEngine } from "./expression-engine.ts";
3
- /** The ExpressionEngine implementation on @marcbachmann/cel-js. */
3
+ /**
4
+ * Provides {@link ExpressionEngine} with `@marcbachmann/cel-js` 8.0.0
5
+ * ([ADR 0004](../../../docs/adr/0004-loop-files-markdown-cel-frontmatter.md)).
6
+ *
7
+ * Expressions can use CEL optional values, such as `item.?milestone.?title.orValue("none")`. A
8
+ * nullable field that holds `null` counts as present, so `item.?milestone` holds `null` and
9
+ * `item.?milestone.?title` is empty.
10
+ *
11
+ * Before evaluation, converts JSON integers to `bigint` wherever the {@link Environment}
12
+ * declares `int`, at any depth, and sets absent nullable fields to `null`. Values inside a
13
+ * `map<K,V>` aren't converted, so declare integer map values as `double`.
14
+ *
15
+ * `uint` isn't supported in `context`; declare such values as `int`. An expression that reads a
16
+ * non-nullable `uint` value type-checks but fails evaluation. On a nullable field, comparing with a
17
+ * `uint` literal works but `uint` arithmetic fails. A `uint` result fails `evaluateScalar`.
18
+ */
4
19
  export declare const MarcbachmannCelLayer: Layer.Layer<ExpressionEngine, never, never>;
5
20
  //# sourceMappingURL=marcbachmann-cel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"marcbachmann-cel.d.ts","sourceRoot":"","sources":["../src/marcbachmann-cel.ts"],"names":[],"mappings":"AAOA,OAAO,EAAU,KAAK,EAAkB,MAAM,QAAQ,CAAC;AAEvD,OAAO,EACL,gBAAgB,EAKjB,MAAM,wBAAwB,CAAC;AA6XhC,mEAAmE;AACnE,eAAO,MAAM,oBAAoB,6CAM/B,CAAC"}
1
+ {"version":3,"file":"marcbachmann-cel.d.ts","sourceRoot":"","sources":["../src/marcbachmann-cel.ts"],"names":[],"mappings":"AASA,OAAO,EAAU,KAAK,EAAqC,MAAM,QAAQ,CAAC;AAE1E,OAAO,EACL,gBAAgB,EAKjB,MAAM,wBAAwB,CAAC;AAsjBhC;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,6CAAqD,CAAC"}