@ripplo/testing 0.7.11 → 0.7.13
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/DSL.md +20 -20
- package/dist/{engine-Dv3trweR.d.ts → engine-D-X3F_hc.d.ts} +4 -7
- package/dist/express.d.ts +1 -1
- package/dist/express.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +97 -62
- package/package.json +1 -1
package/DSL.md
CHANGED
|
@@ -47,16 +47,14 @@ If you're unsure, it's backend. A value that's cached in the browser but owned b
|
|
|
47
47
|
### `field(options)`
|
|
48
48
|
|
|
49
49
|
```ts
|
|
50
|
-
field({ value: v.email() }); // required
|
|
50
|
+
field({ value: v.email() }); // required — Ripplo checks the app's value matches what the test expected
|
|
51
51
|
field({ value: v.word(), optional: true }); // nullable; `null` is a valid set/assert value
|
|
52
|
-
field({ value: v.number({ min: 0, max: 100 }), stable: false }); // adopt-only, drift not checked
|
|
53
52
|
```
|
|
54
53
|
|
|
55
|
-
| option | meaning
|
|
56
|
-
| ---------- |
|
|
57
|
-
| `value` | the value-space (`v.*`) — required
|
|
58
|
-
| `optional` | `true` ⇒ the field is nullable (`null` allowed in `of`/`updated`/assertions); Ripplo treats `null ≡ absent`
|
|
59
|
-
| `stable` | default `true` (Ripplo checks the app's value matches what the test expected). `false` = adopt-only, drift unchecked |
|
|
54
|
+
| option | meaning |
|
|
55
|
+
| ---------- | ----------------------------------------------------------------------------------------------------------- |
|
|
56
|
+
| `value` | the value-space (`v.*`) — required |
|
|
57
|
+
| `optional` | `true` ⇒ the field is nullable (`null` allowed in `of`/`updated`/assertions); Ripplo treats `null ≡ absent` |
|
|
60
58
|
|
|
61
59
|
### Identity: `id()` and `key(options)`
|
|
62
60
|
|
|
@@ -165,19 +163,20 @@ The compiler enumerates one concrete test per `when` branch at `ripplo compile`/
|
|
|
165
163
|
|
|
166
164
|
Each returns a step; chain `.expect(...assertions)` to assert after it runs.
|
|
167
165
|
|
|
168
|
-
| action | signature
|
|
169
|
-
| ---------- |
|
|
170
|
-
| `goto` | `` goto`/path/${handle.id}` ``
|
|
171
|
-
| `click` | `click(locator)`
|
|
172
|
-
| `dblclick` | `dblclick(locator)`
|
|
173
|
-
| `fill` | `fill(locator, value)`
|
|
174
|
-
| `clear` | `clear(locator)`
|
|
175
|
-
| `select` | `select(locator, value)`
|
|
176
|
-
|
|
|
177
|
-
| `
|
|
178
|
-
| `
|
|
179
|
-
| `
|
|
180
|
-
| `
|
|
166
|
+
| action | signature | example |
|
|
167
|
+
| ---------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
|
|
168
|
+
| `goto` | `` goto`/path/${handle.id}` `` | `` goto`/projects/${p.id}` `` |
|
|
169
|
+
| `click` | `click(locator)` | `click(button("Save"))` |
|
|
170
|
+
| `dblclick` | `dblclick(locator)` | `dblclick(testId\`row-${r.id}\`)` |
|
|
171
|
+
| `fill` | `fill(locator, value)` | `fill(textbox("Name"), "Acme")` |
|
|
172
|
+
| `clear` | `clear(locator)` | `clear(textbox("Name"))` |
|
|
173
|
+
| `select` | `select(locator, value)` | `select(combobox("Plan"), "pro")` |
|
|
174
|
+
| — | drives native `<select>` and ARIA comboboxes (react-select, etc.); `value` is the visible option text | `select(combobox("Timezone"), "Europe/London")` |
|
|
175
|
+
| `check` | `check(locator)` | `check(checkbox("Agree"))` |
|
|
176
|
+
| `uncheck` | `uncheck(locator)` | `uncheck(checkbox("Agree"))` |
|
|
177
|
+
| `hover` | `hover(locator)` | `hover(button("More"))` |
|
|
178
|
+
| `upload` | `upload(locator, files)` | `upload(testId\`avatar\`, ["face.png"])` |
|
|
179
|
+
| `press` | `press(key, locator?)` | `press("Enter", textbox("Search"))` |
|
|
181
180
|
|
|
182
181
|
`fill`/`select`/`value`/`text` accept a literal string or a `Binding<string>` (e.g. `arbitrary(...)` or a handle field). `goto`/`testId` are template literals — interpolate handle ids directly.
|
|
183
182
|
|
|
@@ -232,6 +231,7 @@ Used inside a step's `.expect(...)`.
|
|
|
232
231
|
| `disabled` | `disabled(locator)` | element is disabled |
|
|
233
232
|
| `enabled` | `enabled(locator)` | element is enabled |
|
|
234
233
|
| `focused` | `focused(locator)` | element has focus |
|
|
234
|
+
| `checked` | `checked(locator)` | checkbox, radio, or switch is checked |
|
|
235
235
|
| `value` | `value(locator, string\|binding)` | input's value equals |
|
|
236
236
|
| `text` | `text(locator, string\|binding)` | element's text equals |
|
|
237
237
|
| `not` | `not(assertion)` | negation — `not(visible(role("dialog")))` |
|
|
@@ -143,7 +143,6 @@ declare const propSpecSchema: z.ZodObject<{
|
|
|
143
143
|
eventual: "eventual";
|
|
144
144
|
}>>;
|
|
145
145
|
optional: z.ZodBoolean;
|
|
146
|
-
stable: z.ZodBoolean;
|
|
147
146
|
type: z.ZodEnum<{
|
|
148
147
|
string: "string";
|
|
149
148
|
number: "number";
|
|
@@ -171,7 +170,6 @@ declare const entitySchemaSchema: z.ZodObject<{
|
|
|
171
170
|
eventual: "eventual";
|
|
172
171
|
}>>;
|
|
173
172
|
optional: z.ZodBoolean;
|
|
174
|
-
stable: z.ZodBoolean;
|
|
175
173
|
type: z.ZodEnum<{
|
|
176
174
|
string: "string";
|
|
177
175
|
number: "number";
|
|
@@ -591,7 +589,6 @@ declare const lockfileSchema: z.ZodObject<{
|
|
|
591
589
|
eventual: "eventual";
|
|
592
590
|
}>>;
|
|
593
591
|
optional: z.ZodBoolean;
|
|
594
|
-
stable: z.ZodBoolean;
|
|
595
592
|
type: z.ZodEnum<{
|
|
596
593
|
string: "string";
|
|
597
594
|
number: "number";
|
|
@@ -1012,6 +1009,7 @@ declare function visible(locator: Locator): LeafPredicate;
|
|
|
1012
1009
|
declare function disabled(locator: Locator): LeafPredicate;
|
|
1013
1010
|
declare function enabled(locator: Locator): LeafPredicate;
|
|
1014
1011
|
declare function focused(locator: Locator): LeafPredicate;
|
|
1012
|
+
declare function checked(locator: Locator): LeafPredicate;
|
|
1015
1013
|
declare function value(locator: Locator, binding: Binding<string> | string): LeafPredicate;
|
|
1016
1014
|
declare function text(locator: Locator, binding: Binding<string> | string): LeafPredicate;
|
|
1017
1015
|
declare function not(input: ConditionInput): ConditionPredicate;
|
|
@@ -1029,11 +1027,11 @@ interface BranchInput {
|
|
|
1029
1027
|
readonly branch: WhenBranch;
|
|
1030
1028
|
}
|
|
1031
1029
|
interface NamedBranch {
|
|
1032
|
-
readonly expect: (
|
|
1030
|
+
readonly expect: (...consequences: ReadonlyArray<PredicateInput>) => BranchInput;
|
|
1033
1031
|
readonly if: (condition: ConditionInput) => ConditionedBranch;
|
|
1034
1032
|
}
|
|
1035
1033
|
interface ConditionedBranch {
|
|
1036
|
-
readonly expect: (
|
|
1034
|
+
readonly expect: (...consequences: ReadonlyArray<PredicateInput>) => BranchInput;
|
|
1037
1035
|
}
|
|
1038
1036
|
declare function branch(name: string): NamedBranch;
|
|
1039
1037
|
declare function when(...branches: ReadonlyArray<BranchInput>): LeafPredicate;
|
|
@@ -1075,7 +1073,6 @@ interface PropBuilder<T extends Primitive, Opt extends boolean = boolean> {
|
|
|
1075
1073
|
type Mods = Partial<{
|
|
1076
1074
|
readonly consistency: ConsistencyClass;
|
|
1077
1075
|
readonly optional: boolean;
|
|
1078
|
-
readonly stable: boolean;
|
|
1079
1076
|
}>;
|
|
1080
1077
|
type IsOptional = {
|
|
1081
1078
|
readonly optional: true;
|
|
@@ -1292,4 +1289,4 @@ interface Engine {
|
|
|
1292
1289
|
}
|
|
1293
1290
|
declare function createEngine<R extends DeclSource>(ripplo: R, impls: EngineImpls<R, "backend">, teardown: Teardown): Engine;
|
|
1294
1291
|
|
|
1295
|
-
export {
|
|
1292
|
+
export { entity as $, type AnyBinding as A, type Binding as B, type Capture as C, type DeclSource as D, type Engine as E, type FieldHandle as F, type GivenItem as G, type Handle as H, type SingletonConfig as I, type SingletonImpl as J, type SingletonValue as K, type Locator as L, type WithinMatcher as M, type NamedBranch as N, and as O, type PredicateInput as P, branch as Q, type Row as R, type Step as S, changed as T, type UniqueNames as U, checked as V, type Workflow as W, count as X, createEngine as Y, disabled as Z, enabled as _, type EntityList as a, field as a0, focused as a1, id as a2, key as a3, not as a4, singleton as a5, text as a6, v as a7, value as a8, visible as a9, when as aa, within as ab, type SingletonList as b, type Lockfile as c, type BrowserSingleton as d, type LeafPredicate as e, type Primitive as f, type Primitive$1 as g, type SingletonDef as h, type AbsenceHandle as i, type BranchInput as j, CLIENT_MOUNT_KEY as k, CLIENT_SEED_KEY as l, type ConditionInput as m, type ConditionPredicate as n, type ConditionedBranch as o, type CountCondition as p, type DuplicateEntityName as q, type EngineError as r, type EngineImpls as s, type EngineRead as t, type EntityDef as u, type EntityHandle as v, type EntityImpl as w, type FieldOptions as x, type Fields as y, type Selection as z };
|
package/dist/express.d.ts
CHANGED
package/dist/express.js
CHANGED
|
@@ -71,7 +71,6 @@ var valueSpaceSchema = z.object({
|
|
|
71
71
|
var propSpecSchema = z.object({
|
|
72
72
|
consistency: consistencyClassSchema.default("strict"),
|
|
73
73
|
optional: z.boolean(),
|
|
74
|
-
stable: z.boolean(),
|
|
75
74
|
type: primitiveTypeSchema,
|
|
76
75
|
valueSpace: z.string().min(1).optional()
|
|
77
76
|
});
|
|
@@ -146,7 +145,7 @@ var conditionSchema = z2.lazy(
|
|
|
146
145
|
var whenBranchSchema = z2.lazy(
|
|
147
146
|
() => z2.object({
|
|
148
147
|
condition: z2.union([conditionSchema, z2.undefined()]).optional().transform((value) => value),
|
|
149
|
-
consequence: predicateSchema,
|
|
148
|
+
consequence: z2.array(predicateSchema),
|
|
150
149
|
name: z2.string().min(1)
|
|
151
150
|
})
|
|
152
151
|
);
|
|
@@ -156,6 +155,7 @@ var predicateSchema = z2.lazy(
|
|
|
156
155
|
z2.object({ kind: z2.literal("disabled"), locator: locatorSchema, wait }),
|
|
157
156
|
z2.object({ kind: z2.literal("enabled"), locator: locatorSchema, wait }),
|
|
158
157
|
z2.object({ kind: z2.literal("focused"), locator: locatorSchema, wait }),
|
|
158
|
+
z2.object({ kind: z2.literal("checked"), locator: locatorSchema, wait }),
|
|
159
159
|
z2.object({ kind: z2.literal("value"), locator: locatorSchema, value: stringValueSchema, wait }),
|
|
160
160
|
z2.object({ kind: z2.literal("text"), locator: locatorSchema, value: stringValueSchema, wait }),
|
|
161
161
|
singletonPredicateSchema,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as Capture, S as Step, P as PredicateInput, L as Locator, B as Binding, A as AnyBinding, G as GivenItem, W as Workflow, a as EntityList, b as SingletonList, c as Lockfile, U as UniqueNames, d as BrowserSingleton, e as LeafPredicate, f as Primitive, F as FieldHandle, D as DeclSource, R as Row, g as Primitive$1, h as SingletonDef } from './engine-
|
|
2
|
-
export { i as AbsenceHandle, j as BranchInput, k as CLIENT_MOUNT_KEY, l as CLIENT_SEED_KEY, m as ConditionInput, n as ConditionPredicate, o as ConditionedBranch, p as CountCondition, q as DuplicateEntityName, E as Engine, r as EngineError, s as EngineImpls, t as EngineRead, u as EntityDef, v as EntityHandle, w as EntityImpl, x as FieldOptions, y as Fields, H as Handle, N as NamedBranch, z as Selection, I as SingletonConfig, J as SingletonImpl, K as SingletonValue, M as WithinMatcher, O as and, Q as branch, T as changed, V as
|
|
1
|
+
import { C as Capture, S as Step, P as PredicateInput, L as Locator, B as Binding, A as AnyBinding, G as GivenItem, W as Workflow, a as EntityList, b as SingletonList, c as Lockfile, U as UniqueNames, d as BrowserSingleton, e as LeafPredicate, f as Primitive, F as FieldHandle, D as DeclSource, R as Row, g as Primitive$1, h as SingletonDef } from './engine-D-X3F_hc.js';
|
|
2
|
+
export { i as AbsenceHandle, j as BranchInput, k as CLIENT_MOUNT_KEY, l as CLIENT_SEED_KEY, m as ConditionInput, n as ConditionPredicate, o as ConditionedBranch, p as CountCondition, q as DuplicateEntityName, E as Engine, r as EngineError, s as EngineImpls, t as EngineRead, u as EntityDef, v as EntityHandle, w as EntityImpl, x as FieldOptions, y as Fields, H as Handle, N as NamedBranch, z as Selection, I as SingletonConfig, J as SingletonImpl, K as SingletonValue, M as WithinMatcher, O as and, Q as branch, T as changed, V as checked, X as count, Y as createEngine, Z as disabled, _ as enabled, $ as entity, a0 as field, a1 as focused, a2 as id, a3 as key, a4 as not, a5 as singleton, a6 as text, a7 as v, a8 as value, a9 as visible, aa as when, ab as within } from './engine-D-X3F_hc.js';
|
|
3
3
|
import 'neverthrow';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -98,6 +98,9 @@ function enabled(locator) {
|
|
|
98
98
|
function focused(locator) {
|
|
99
99
|
return leaf({ kind: "focused", locator, wait: void 0 });
|
|
100
100
|
}
|
|
101
|
+
function checked(locator) {
|
|
102
|
+
return leaf({ kind: "checked", locator, wait: void 0 });
|
|
103
|
+
}
|
|
101
104
|
function value(locator, binding) {
|
|
102
105
|
return leaf({ kind: "value", locator, value: binding, wait: void 0 });
|
|
103
106
|
}
|
|
@@ -125,9 +128,9 @@ function count(entity2) {
|
|
|
125
128
|
};
|
|
126
129
|
}
|
|
127
130
|
function branch(name) {
|
|
128
|
-
const close = (condition) => (
|
|
129
|
-
const resolved = toPredicate(consequence);
|
|
130
|
-
if (containsWhen(
|
|
131
|
+
const close = (condition) => (...consequences) => {
|
|
132
|
+
const resolved = consequences.map((consequence) => toPredicate(consequence));
|
|
133
|
+
if (resolved.some((predicate) => containsWhen(predicate))) {
|
|
131
134
|
throw new Error(
|
|
132
135
|
`branch "${name}" nests a when() inside its consequence \u2014 whens are one level deep; split the scenario into another workflow`
|
|
133
136
|
);
|
|
@@ -270,7 +273,6 @@ function field(options) {
|
|
|
270
273
|
spec: {
|
|
271
274
|
consistency: options.consistency ?? "strict",
|
|
272
275
|
optional: options.optional ?? false,
|
|
273
|
-
stable: options.stable ?? true,
|
|
274
276
|
type: options.value.primitive
|
|
275
277
|
},
|
|
276
278
|
valueSpace: options.value
|
|
@@ -280,7 +282,7 @@ function id() {
|
|
|
280
282
|
return {
|
|
281
283
|
idKind: "surrogate",
|
|
282
284
|
prop: propBuilder({
|
|
283
|
-
spec: { consistency: "strict", optional: false,
|
|
285
|
+
spec: { consistency: "strict", optional: false, type: "string" },
|
|
284
286
|
valueSpace: void 0
|
|
285
287
|
})
|
|
286
288
|
};
|
|
@@ -292,7 +294,6 @@ function key(options) {
|
|
|
292
294
|
spec: {
|
|
293
295
|
consistency: "strict",
|
|
294
296
|
optional: false,
|
|
295
|
-
stable: true,
|
|
296
297
|
type: options.value.primitive
|
|
297
298
|
},
|
|
298
299
|
valueSpace: options.value
|
|
@@ -598,6 +599,20 @@ function stepBuilder(action, expected, captures) {
|
|
|
598
599
|
};
|
|
599
600
|
}
|
|
600
601
|
|
|
602
|
+
// src/coherence.ts
|
|
603
|
+
function assertEntityCoherence(entities) {
|
|
604
|
+
const counts = entities.reduce(
|
|
605
|
+
(acc, d) => new Map([...acc, [d.entity, (acc.get(d.entity) ?? 0) + 1]]),
|
|
606
|
+
/* @__PURE__ */ new Map()
|
|
607
|
+
);
|
|
608
|
+
const over = entities.find((d) => d.kind === "only" && (counts.get(d.entity) ?? 0) > 1);
|
|
609
|
+
if (over != null) {
|
|
610
|
+
throw new Error(
|
|
611
|
+
`entity "${over.entity}" is declared only() but seeded ${String(counts.get(over.entity) ?? 0)} times \u2014 only() means a single exclusive instance; use of() for multiple instances`
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
601
616
|
// src/finalize.ts
|
|
602
617
|
function finalize(body) {
|
|
603
618
|
const descriptors = [...new Set(body.given.map((item) => item.__entity))];
|
|
@@ -611,6 +626,7 @@ function finalize(body) {
|
|
|
611
626
|
)
|
|
612
627
|
);
|
|
613
628
|
assertNoMaybeRefs({ absences, entities, singletonStates });
|
|
629
|
+
assertEntityCoherence(entities);
|
|
614
630
|
const captures = body.steps.flatMap((builder) => builder.captures);
|
|
615
631
|
assertScopedConditions(body.steps, new Set(singletonStates.map((s) => s.singleton)));
|
|
616
632
|
const aliases = assignAliases([...entities, ...captures.map((c) => c.descriptor)]);
|
|
@@ -717,7 +733,9 @@ function assertPredicateScoped(predicate, given) {
|
|
|
717
733
|
);
|
|
718
734
|
}
|
|
719
735
|
});
|
|
720
|
-
|
|
736
|
+
row2.consequence.forEach((consequence) => {
|
|
737
|
+
assertPredicateScoped(consequence, given);
|
|
738
|
+
});
|
|
721
739
|
});
|
|
722
740
|
}
|
|
723
741
|
function conditionSingletons(predicate) {
|
|
@@ -812,7 +830,8 @@ function predicateBindings(predicate) {
|
|
|
812
830
|
case "visible":
|
|
813
831
|
case "disabled":
|
|
814
832
|
case "enabled":
|
|
815
|
-
case "focused":
|
|
833
|
+
case "focused":
|
|
834
|
+
case "checked": {
|
|
816
835
|
return locatorBindings(predicate.locator);
|
|
817
836
|
}
|
|
818
837
|
case "value":
|
|
@@ -839,7 +858,7 @@ function predicateBindings(predicate) {
|
|
|
839
858
|
case "when": {
|
|
840
859
|
return predicate.branches.flatMap((row2) => [
|
|
841
860
|
...row2.condition == null ? [] : predicateBindings(row2.condition),
|
|
842
|
-
...
|
|
861
|
+
...row2.consequence.flatMap((consequence) => predicateBindings(consequence))
|
|
843
862
|
]);
|
|
844
863
|
}
|
|
845
864
|
case "and": {
|
|
@@ -959,7 +978,8 @@ function resolvePredicate(predicate, ctx) {
|
|
|
959
978
|
case "visible":
|
|
960
979
|
case "disabled":
|
|
961
980
|
case "enabled":
|
|
962
|
-
case "focused":
|
|
981
|
+
case "focused":
|
|
982
|
+
case "checked": {
|
|
963
983
|
return { ...predicate, locator: resolveLocator(predicate.locator, ctx) };
|
|
964
984
|
}
|
|
965
985
|
case "value":
|
|
@@ -994,7 +1014,7 @@ function resolvePredicate(predicate, ctx) {
|
|
|
994
1014
|
...predicate,
|
|
995
1015
|
branches: predicate.branches.map((row2) => ({
|
|
996
1016
|
condition: row2.condition == null ? void 0 : resolveCondition(row2.condition, ctx),
|
|
997
|
-
consequence:
|
|
1017
|
+
consequence: row2.consequence.map((consequence) => resolvePredicate(consequence, ctx)),
|
|
998
1018
|
name: row2.name
|
|
999
1019
|
}))
|
|
1000
1020
|
};
|
|
@@ -1366,7 +1386,6 @@ var valueSpaceSchema = z.object({
|
|
|
1366
1386
|
var propSpecSchema = z.object({
|
|
1367
1387
|
consistency: consistencyClassSchema.default("strict"),
|
|
1368
1388
|
optional: z.boolean(),
|
|
1369
|
-
stable: z.boolean(),
|
|
1370
1389
|
type: primitiveTypeSchema,
|
|
1371
1390
|
valueSpace: z.string().min(1).optional()
|
|
1372
1391
|
});
|
|
@@ -1441,7 +1460,7 @@ var conditionSchema = z2.lazy(
|
|
|
1441
1460
|
var whenBranchSchema = z2.lazy(
|
|
1442
1461
|
() => z2.object({
|
|
1443
1462
|
condition: z2.union([conditionSchema, z2.undefined()]).optional().transform((value2) => value2),
|
|
1444
|
-
consequence: predicateSchema,
|
|
1463
|
+
consequence: z2.array(predicateSchema),
|
|
1445
1464
|
name: z2.string().min(1)
|
|
1446
1465
|
})
|
|
1447
1466
|
);
|
|
@@ -1451,6 +1470,7 @@ var predicateSchema = z2.lazy(
|
|
|
1451
1470
|
z2.object({ kind: z2.literal("disabled"), locator: locatorSchema, wait }),
|
|
1452
1471
|
z2.object({ kind: z2.literal("enabled"), locator: locatorSchema, wait }),
|
|
1453
1472
|
z2.object({ kind: z2.literal("focused"), locator: locatorSchema, wait }),
|
|
1473
|
+
z2.object({ kind: z2.literal("checked"), locator: locatorSchema, wait }),
|
|
1454
1474
|
z2.object({ kind: z2.literal("value"), locator: locatorSchema, value: stringValueSchema, wait }),
|
|
1455
1475
|
z2.object({ kind: z2.literal("text"), locator: locatorSchema, value: stringValueSchema, wait }),
|
|
1456
1476
|
singletonPredicateSchema,
|
|
@@ -1707,6 +1727,54 @@ function mountClientEngine(ripplo, impls, { enabled: enabled2 }) {
|
|
|
1707
1727
|
Reflect.set(globalThis, CLIENT_MOUNT_KEY, createClientEngine(ripplo, impls));
|
|
1708
1728
|
}
|
|
1709
1729
|
|
|
1730
|
+
// src/expand-refs.ts
|
|
1731
|
+
function usedRefHeads({
|
|
1732
|
+
singletons,
|
|
1733
|
+
steps,
|
|
1734
|
+
workflow: workflow2,
|
|
1735
|
+
world
|
|
1736
|
+
}) {
|
|
1737
|
+
const values = [
|
|
1738
|
+
...world.flatMap((setup) => Object.values(setup.set)),
|
|
1739
|
+
...workflow2.absent.flatMap((absence) => Object.values(absence.where)),
|
|
1740
|
+
...Object.values(singletons),
|
|
1741
|
+
...steps.flatMap((step) => stepRefValues(step))
|
|
1742
|
+
];
|
|
1743
|
+
return new Set(values.flatMap((value2) => refStrings(value2)).map((ref) => headOf(ref)));
|
|
1744
|
+
}
|
|
1745
|
+
function collectRefObjects(node) {
|
|
1746
|
+
if (Array.isArray(node)) {
|
|
1747
|
+
return node.flatMap((item) => collectRefObjects(item));
|
|
1748
|
+
}
|
|
1749
|
+
if (node == null || typeof node !== "object") {
|
|
1750
|
+
return [];
|
|
1751
|
+
}
|
|
1752
|
+
if ("ref" in node && typeof node.ref === "string" && Object.keys(node).length === 1) {
|
|
1753
|
+
return [node.ref];
|
|
1754
|
+
}
|
|
1755
|
+
return Object.values(node).flatMap((value2) => collectRefObjects(value2));
|
|
1756
|
+
}
|
|
1757
|
+
function isRefValue(value2) {
|
|
1758
|
+
return value2 != null && typeof value2 === "object" && "ref" in value2 ? value2.ref : void 0;
|
|
1759
|
+
}
|
|
1760
|
+
function headOf(ref) {
|
|
1761
|
+
const dot = ref.indexOf(".");
|
|
1762
|
+
return dot === -1 ? ref : ref.slice(0, dot);
|
|
1763
|
+
}
|
|
1764
|
+
function stepRefValues(step) {
|
|
1765
|
+
return collectRefObjects(step).map((ref) => ({ ref }));
|
|
1766
|
+
}
|
|
1767
|
+
function refStrings(value2) {
|
|
1768
|
+
const ref = isRefValue(value2);
|
|
1769
|
+
if (ref != null) {
|
|
1770
|
+
return [ref];
|
|
1771
|
+
}
|
|
1772
|
+
if (value2 != null && typeof value2 === "object" && "template" in value2) {
|
|
1773
|
+
return value2.template.flatMap((segment) => typeof segment === "string" ? [] : [segment.ref]);
|
|
1774
|
+
}
|
|
1775
|
+
return [];
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1710
1778
|
// src/expand.ts
|
|
1711
1779
|
var MAX_CANDIDATES = 4096;
|
|
1712
1780
|
function singletonValuesOf(singletons) {
|
|
@@ -1822,7 +1890,7 @@ function targetsIn(predicate) {
|
|
|
1822
1890
|
}
|
|
1823
1891
|
return predicate.branches.flatMap((row2, index) => [
|
|
1824
1892
|
{ index, name: row2.name, when: predicate },
|
|
1825
|
-
...
|
|
1893
|
+
...row2.consequence.flatMap((consequence) => targetsIn(consequence))
|
|
1826
1894
|
]);
|
|
1827
1895
|
}
|
|
1828
1896
|
function proposeCandidates(workflow2, options) {
|
|
@@ -1879,7 +1947,7 @@ function conditionLiteralsIn(predicate) {
|
|
|
1879
1947
|
}
|
|
1880
1948
|
return predicate.branches.flatMap((row2) => [
|
|
1881
1949
|
...row2.condition == null ? [] : singletonLiteralsInCondition(row2.condition),
|
|
1882
|
-
...
|
|
1950
|
+
...row2.consequence.flatMap((consequence) => conditionLiteralsIn(consequence))
|
|
1883
1951
|
]);
|
|
1884
1952
|
}
|
|
1885
1953
|
function singletonLiteralsInCondition(condition) {
|
|
@@ -1979,11 +2047,18 @@ function foldWhen(acc, when2, state) {
|
|
|
1979
2047
|
return acc;
|
|
1980
2048
|
}
|
|
1981
2049
|
const choices = new Map([...acc.choices, [when2, picked]]);
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
2050
|
+
return row2.consequence.reduce(
|
|
2051
|
+
(folded, consequence) => {
|
|
2052
|
+
if (folded == null) {
|
|
2053
|
+
return null;
|
|
2054
|
+
}
|
|
2055
|
+
if (consequence.kind === "when") {
|
|
2056
|
+
return foldWhen(folded, consequence, state);
|
|
2057
|
+
}
|
|
2058
|
+
return { choices: folded.choices, sets: { ...folded.sets, ...singletonSets([consequence]) } };
|
|
2059
|
+
},
|
|
2060
|
+
{ choices, sets: acc.sets }
|
|
2061
|
+
);
|
|
1987
2062
|
}
|
|
1988
2063
|
function pickBranch(when2, state) {
|
|
1989
2064
|
return when2.branches.reduce((picked, row2, index) => {
|
|
@@ -2030,9 +2105,6 @@ function compareValues(seeded, wanted) {
|
|
|
2030
2105
|
}
|
|
2031
2106
|
return sameSetValue(seeded, wanted);
|
|
2032
2107
|
}
|
|
2033
|
-
function isRefValue(value2) {
|
|
2034
|
-
return value2 != null && typeof value2 === "object" && "ref" in value2 ? value2.ref : void 0;
|
|
2035
|
-
}
|
|
2036
2108
|
function isTemplateValue(value2) {
|
|
2037
2109
|
return value2 != null && typeof value2 === "object" && "template" in value2;
|
|
2038
2110
|
}
|
|
@@ -2138,45 +2210,7 @@ function resolvePredicate2(predicate, choices) {
|
|
|
2138
2210
|
}
|
|
2139
2211
|
const picked = choices.get(predicate);
|
|
2140
2212
|
const row2 = picked == null ? void 0 : predicate.branches[picked];
|
|
2141
|
-
return row2 == null ? [] :
|
|
2142
|
-
}
|
|
2143
|
-
function usedRefHeads({ singletons, steps, workflow: workflow2, world }) {
|
|
2144
|
-
const values = [
|
|
2145
|
-
...world.flatMap((setup) => Object.values(setup.set)),
|
|
2146
|
-
...workflow2.absent.flatMap((absence) => Object.values(absence.where)),
|
|
2147
|
-
...Object.values(singletons),
|
|
2148
|
-
...steps.flatMap((step) => stepRefValues(step))
|
|
2149
|
-
];
|
|
2150
|
-
return new Set(values.flatMap((value2) => refStrings(value2)).map((ref) => headOf(ref)));
|
|
2151
|
-
}
|
|
2152
|
-
function stepRefValues(step) {
|
|
2153
|
-
return collectRefObjects(step).map((ref) => ({ ref }));
|
|
2154
|
-
}
|
|
2155
|
-
function collectRefObjects(node) {
|
|
2156
|
-
if (Array.isArray(node)) {
|
|
2157
|
-
return node.flatMap((item) => collectRefObjects(item));
|
|
2158
|
-
}
|
|
2159
|
-
if (node == null || typeof node !== "object") {
|
|
2160
|
-
return [];
|
|
2161
|
-
}
|
|
2162
|
-
if ("ref" in node && typeof node.ref === "string" && Object.keys(node).length === 1) {
|
|
2163
|
-
return [node.ref];
|
|
2164
|
-
}
|
|
2165
|
-
return Object.values(node).flatMap((value2) => collectRefObjects(value2));
|
|
2166
|
-
}
|
|
2167
|
-
function refStrings(value2) {
|
|
2168
|
-
const ref = isRefValue(value2);
|
|
2169
|
-
if (ref != null) {
|
|
2170
|
-
return [ref];
|
|
2171
|
-
}
|
|
2172
|
-
if (value2 != null && typeof value2 === "object" && "template" in value2) {
|
|
2173
|
-
return value2.template.flatMap((segment) => typeof segment === "string" ? [] : [segment.ref]);
|
|
2174
|
-
}
|
|
2175
|
-
return [];
|
|
2176
|
-
}
|
|
2177
|
-
function headOf(ref) {
|
|
2178
|
-
const dot = ref.indexOf(".");
|
|
2179
|
-
return dot === -1 ? ref : ref.slice(0, dot);
|
|
2213
|
+
return row2 == null ? [] : row2.consequence.flatMap((c) => resolvePredicate2(c, choices));
|
|
2180
2214
|
}
|
|
2181
2215
|
|
|
2182
2216
|
// src/build.ts
|
|
@@ -2292,6 +2326,7 @@ export {
|
|
|
2292
2326
|
changed,
|
|
2293
2327
|
check,
|
|
2294
2328
|
checkbox,
|
|
2329
|
+
checked,
|
|
2295
2330
|
clear,
|
|
2296
2331
|
click,
|
|
2297
2332
|
columnheader,
|
package/package.json
CHANGED