@etohq/workflows-input-schema-builder 0.0.1-next-20260318155517
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 +71 -0
- package/dist/__tests__/guardrails-date-and-array.spec.d.ts +2 -0
- package/dist/__tests__/guardrails-date-and-array.spec.d.ts.map +1 -0
- package/dist/__tests__/guardrails-date-and-array.spec.js +84 -0
- package/dist/__tests__/guardrails-date-and-array.spec.js.map +1 -0
- package/dist/__tests__/guardrails-equals-one-of-elements.spec.d.ts +2 -0
- package/dist/__tests__/guardrails-equals-one-of-elements.spec.d.ts.map +1 -0
- package/dist/__tests__/guardrails-equals-one-of-elements.spec.js +112 -0
- package/dist/__tests__/guardrails-equals-one-of-elements.spec.js.map +1 -0
- package/dist/__tests__/guardrails-operator-rhs.spec.d.ts +2 -0
- package/dist/__tests__/guardrails-operator-rhs.spec.d.ts.map +1 -0
- package/dist/__tests__/guardrails-operator-rhs.spec.js +91 -0
- package/dist/__tests__/guardrails-operator-rhs.spec.js.map +1 -0
- package/dist/__tests__/guardrails-operator-type-matrix.spec.d.ts +2 -0
- package/dist/__tests__/guardrails-operator-type-matrix.spec.d.ts.map +1 -0
- package/dist/__tests__/guardrails-operator-type-matrix.spec.js +102 -0
- package/dist/__tests__/guardrails-operator-type-matrix.spec.js.map +1 -0
- package/dist/__tests__/guardrails-operators.spec.d.ts +2 -0
- package/dist/__tests__/guardrails-operators.spec.d.ts.map +1 -0
- package/dist/__tests__/guardrails-operators.spec.js +117 -0
- package/dist/__tests__/guardrails-operators.spec.js.map +1 -0
- package/dist/__tests__/scope-field-compilation.spec.d.ts +2 -0
- package/dist/__tests__/scope-field-compilation.spec.d.ts.map +1 -0
- package/dist/__tests__/scope-field-compilation.spec.js +71 -0
- package/dist/__tests__/scope-field-compilation.spec.js.map +1 -0
- package/dist/compile.d.ts +14 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +232 -0
- package/dist/compile.js.map +1 -0
- package/dist/guardrails.d.ts +4 -0
- package/dist/guardrails.d.ts.map +1 -0
- package/dist/guardrails.js +483 -0
- package/dist/guardrails.js.map +1 -0
- package/dist/helpers-actions.d.ts +16 -0
- package/dist/helpers-actions.d.ts.map +1 -0
- package/dist/helpers-actions.js +40 -0
- package/dist/helpers-actions.js.map +1 -0
- package/dist/helpers.d.ts +37 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +49 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/model.d.ts +69 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +3 -0
- package/dist/model.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# @etohq/workflows-input-schema-builder
|
|
2
|
+
|
|
3
|
+
Builder/editor model for authoring `@etohq/workflows-input-schema`.
|
|
4
|
+
|
|
5
|
+
This package provides:
|
|
6
|
+
|
|
7
|
+
- A builder-friendly condition model (`ConditionGroup`, `SingleCondition`)
|
|
8
|
+
- Guardrails/validation for builder rules
|
|
9
|
+
- Compilation into canonical `RuleSpec` / `PredicateSpec`
|
|
10
|
+
|
|
11
|
+
## Key Design Rule
|
|
12
|
+
|
|
13
|
+
- Canonical runtime scope is **node-only** (`RuleSpec.scope = { node_id }`).
|
|
14
|
+
- Builder supports a convenience scope: `scope: { type: "field", field_key }` and compiles it into
|
|
15
|
+
`{ node_id }` using layout ownership (must be unambiguous).
|
|
16
|
+
|
|
17
|
+
## Example: Build Rules And Compile Into Schema
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import type { InputSchemaSpec } from "@etohq/workflows-input-schema"
|
|
21
|
+
import { validateBuilderRules } from "@etohq/workflows-input-schema-builder"
|
|
22
|
+
import { compileBuilderRulesIntoSchema } from "@etohq/workflows-input-schema-builder"
|
|
23
|
+
import {
|
|
24
|
+
createBuilderRule,
|
|
25
|
+
createConditionGroup,
|
|
26
|
+
createSingleCondition,
|
|
27
|
+
refField,
|
|
28
|
+
} from "@etohq/workflows-input-schema-builder"
|
|
29
|
+
|
|
30
|
+
const schema: InputSchemaSpec = {
|
|
31
|
+
id: "schema_1",
|
|
32
|
+
version: 1,
|
|
33
|
+
name: "Example",
|
|
34
|
+
fields: [{ key: "email", value_type: "string", required: false }],
|
|
35
|
+
layout: [
|
|
36
|
+
{ type: "section", id: "s1", children: [{ type: "field", field_key: "email" }] },
|
|
37
|
+
{ type: "ending", id: "done", title: { default: "Done" } },
|
|
38
|
+
],
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const builderRules = [
|
|
42
|
+
createBuilderRule({
|
|
43
|
+
id: "r1",
|
|
44
|
+
scope: { type: "field", field_key: "email" },
|
|
45
|
+
conditions: createConditionGroup({
|
|
46
|
+
id: "g1",
|
|
47
|
+
connector: "and",
|
|
48
|
+
conditions: [
|
|
49
|
+
createSingleCondition({
|
|
50
|
+
id: "c1",
|
|
51
|
+
left: { type: "ref", ref: refField("email") },
|
|
52
|
+
operator: "is_present",
|
|
53
|
+
right: null,
|
|
54
|
+
}),
|
|
55
|
+
],
|
|
56
|
+
}),
|
|
57
|
+
actions: [{ type: "end", ending_id: "done" }],
|
|
58
|
+
}),
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
const issues = validateBuilderRules(schema, builderRules)
|
|
62
|
+
if (issues.length) {
|
|
63
|
+
// show issues to the user
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const compiled = compileBuilderRulesIntoSchema(schema, builderRules)
|
|
67
|
+
if (compiled.ok) {
|
|
68
|
+
// compiled.value.rules is canonical RuleSpec[] (with scope node_id)
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails-date-and-array.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/guardrails-date-and-array.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const helpers_1 = require("../helpers");
|
|
4
|
+
const guardrails_1 = require("../guardrails");
|
|
5
|
+
function schema() {
|
|
6
|
+
return {
|
|
7
|
+
id: "schema_1",
|
|
8
|
+
version: 1,
|
|
9
|
+
name: "Test Schema",
|
|
10
|
+
fields: [
|
|
11
|
+
{ key: "dob", value_type: "date", required: false },
|
|
12
|
+
{ key: "tags", value_type: "array", required: false },
|
|
13
|
+
],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
describe("validateBuilderRules (date/array RHS typing)", () => {
|
|
17
|
+
test("date operators require date RHS (static string is rejected)", () => {
|
|
18
|
+
const rules = [
|
|
19
|
+
(0, helpers_1.createBuilderRule)({
|
|
20
|
+
id: "r1",
|
|
21
|
+
conditions: (0, helpers_1.createConditionGroup)({
|
|
22
|
+
id: "g1",
|
|
23
|
+
connector: "and",
|
|
24
|
+
conditions: [
|
|
25
|
+
(0, helpers_1.createSingleCondition)({
|
|
26
|
+
id: "c1",
|
|
27
|
+
left: { type: "ref", ref: (0, helpers_1.refField)("dob") },
|
|
28
|
+
operator: "is_before",
|
|
29
|
+
right: { type: "static", value: "2020-01-01" },
|
|
30
|
+
}),
|
|
31
|
+
],
|
|
32
|
+
}),
|
|
33
|
+
actions: [],
|
|
34
|
+
}),
|
|
35
|
+
];
|
|
36
|
+
const issues = (0, guardrails_1.validateBuilderRules)(schema(), rules);
|
|
37
|
+
expect(issues.some((i) => i.message.includes("requires a date right operand"))).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
test("date operators accept const date wrappers", () => {
|
|
40
|
+
const rules = [
|
|
41
|
+
(0, helpers_1.createBuilderRule)({
|
|
42
|
+
id: "r1",
|
|
43
|
+
conditions: (0, helpers_1.createConditionGroup)({
|
|
44
|
+
id: "g1",
|
|
45
|
+
connector: "and",
|
|
46
|
+
conditions: [
|
|
47
|
+
(0, helpers_1.createSingleCondition)({
|
|
48
|
+
id: "c1",
|
|
49
|
+
left: { type: "ref", ref: (0, helpers_1.refField)("dob") },
|
|
50
|
+
operator: "is_before",
|
|
51
|
+
right: { type: "ref", ref: (0, helpers_1.refConst)({ type: "date", value: "2020-01-01" }) },
|
|
52
|
+
}),
|
|
53
|
+
],
|
|
54
|
+
}),
|
|
55
|
+
actions: [],
|
|
56
|
+
}),
|
|
57
|
+
];
|
|
58
|
+
const issues = (0, guardrails_1.validateBuilderRules)(schema(), rules);
|
|
59
|
+
expect(issues.length).toBe(0);
|
|
60
|
+
});
|
|
61
|
+
test("array operators require array RHS", () => {
|
|
62
|
+
const rules = [
|
|
63
|
+
(0, helpers_1.createBuilderRule)({
|
|
64
|
+
id: "r1",
|
|
65
|
+
conditions: (0, helpers_1.createConditionGroup)({
|
|
66
|
+
id: "g1",
|
|
67
|
+
connector: "and",
|
|
68
|
+
conditions: [
|
|
69
|
+
(0, helpers_1.createSingleCondition)({
|
|
70
|
+
id: "c1",
|
|
71
|
+
left: { type: "ref", ref: (0, helpers_1.refField)("tags") },
|
|
72
|
+
operator: "includes_one_of",
|
|
73
|
+
right: { type: "static", value: "x" },
|
|
74
|
+
}),
|
|
75
|
+
],
|
|
76
|
+
}),
|
|
77
|
+
actions: [],
|
|
78
|
+
}),
|
|
79
|
+
];
|
|
80
|
+
const issues = (0, guardrails_1.validateBuilderRules)(schema(), rules);
|
|
81
|
+
expect(issues.some((i) => i.message.includes("requires an array right operand"))).toBe(true);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
//# sourceMappingURL=guardrails-date-and-array.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails-date-and-array.spec.js","sourceRoot":"","sources":["../../src/__tests__/guardrails-date-and-array.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails-equals-one-of-elements.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/guardrails-equals-one-of-elements.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const helpers_1 = require("../helpers");
|
|
4
|
+
const guardrails_1 = require("../guardrails");
|
|
5
|
+
function schema() {
|
|
6
|
+
return {
|
|
7
|
+
id: "schema_1",
|
|
8
|
+
version: 1,
|
|
9
|
+
name: "Test Schema",
|
|
10
|
+
fields: [
|
|
11
|
+
{ key: "n", value_type: "number", required: false },
|
|
12
|
+
{ key: "d", value_type: "date", required: false },
|
|
13
|
+
],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
describe("validateBuilderRules (equals_one_of element compatibility)", () => {
|
|
17
|
+
test("accepts number[] static RHS for number field", () => {
|
|
18
|
+
const rules = [
|
|
19
|
+
(0, helpers_1.createBuilderRule)({
|
|
20
|
+
id: "r1",
|
|
21
|
+
conditions: (0, helpers_1.createConditionGroup)({
|
|
22
|
+
id: "g1",
|
|
23
|
+
connector: "and",
|
|
24
|
+
conditions: [
|
|
25
|
+
(0, helpers_1.createSingleCondition)({
|
|
26
|
+
id: "c1",
|
|
27
|
+
left: { type: "ref", ref: (0, helpers_1.refField)("n") },
|
|
28
|
+
operator: "equals_one_of",
|
|
29
|
+
right: { type: "static", value: [1, 2, 3] },
|
|
30
|
+
}),
|
|
31
|
+
],
|
|
32
|
+
}),
|
|
33
|
+
actions: [],
|
|
34
|
+
}),
|
|
35
|
+
];
|
|
36
|
+
const issues = (0, guardrails_1.validateBuilderRules)(schema(), rules);
|
|
37
|
+
expect(issues.length).toBe(0);
|
|
38
|
+
});
|
|
39
|
+
test("rejects mismatched element types for static RHS", () => {
|
|
40
|
+
const rules = [
|
|
41
|
+
(0, helpers_1.createBuilderRule)({
|
|
42
|
+
id: "r1",
|
|
43
|
+
conditions: (0, helpers_1.createConditionGroup)({
|
|
44
|
+
id: "g1",
|
|
45
|
+
connector: "and",
|
|
46
|
+
conditions: [
|
|
47
|
+
(0, helpers_1.createSingleCondition)({
|
|
48
|
+
id: "c1",
|
|
49
|
+
left: { type: "ref", ref: (0, helpers_1.refField)("n") },
|
|
50
|
+
operator: "equals_one_of",
|
|
51
|
+
right: { type: "static", value: ["1", "2"] },
|
|
52
|
+
}),
|
|
53
|
+
],
|
|
54
|
+
}),
|
|
55
|
+
actions: [],
|
|
56
|
+
}),
|
|
57
|
+
];
|
|
58
|
+
const issues = (0, guardrails_1.validateBuilderRules)(schema(), rules);
|
|
59
|
+
expect(issues.some((i) => i.message.includes("element types must match left operand type"))).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
test("rejects date equals_one_of when RHS is a static array", () => {
|
|
62
|
+
const rules = [
|
|
63
|
+
(0, helpers_1.createBuilderRule)({
|
|
64
|
+
id: "r1",
|
|
65
|
+
conditions: (0, helpers_1.createConditionGroup)({
|
|
66
|
+
id: "g1",
|
|
67
|
+
connector: "and",
|
|
68
|
+
conditions: [
|
|
69
|
+
(0, helpers_1.createSingleCondition)({
|
|
70
|
+
id: "c1",
|
|
71
|
+
left: { type: "ref", ref: (0, helpers_1.refField)("d") },
|
|
72
|
+
operator: "equals_one_of",
|
|
73
|
+
right: { type: "static", value: ["2020-01-01"] },
|
|
74
|
+
}),
|
|
75
|
+
],
|
|
76
|
+
}),
|
|
77
|
+
actions: [],
|
|
78
|
+
}),
|
|
79
|
+
];
|
|
80
|
+
const issues = (0, guardrails_1.validateBuilderRules)(schema(), rules);
|
|
81
|
+
expect(issues.some((i) => i.message.includes("requires date values to be provided via const wrappers"))).toBe(true);
|
|
82
|
+
});
|
|
83
|
+
test("accepts date equals_one_of with const array of date wrappers", () => {
|
|
84
|
+
const rules = [
|
|
85
|
+
(0, helpers_1.createBuilderRule)({
|
|
86
|
+
id: "r1",
|
|
87
|
+
conditions: (0, helpers_1.createConditionGroup)({
|
|
88
|
+
id: "g1",
|
|
89
|
+
connector: "and",
|
|
90
|
+
conditions: [
|
|
91
|
+
(0, helpers_1.createSingleCondition)({
|
|
92
|
+
id: "c1",
|
|
93
|
+
left: { type: "ref", ref: (0, helpers_1.refField)("d") },
|
|
94
|
+
operator: "equals_one_of",
|
|
95
|
+
right: {
|
|
96
|
+
type: "ref",
|
|
97
|
+
ref: (0, helpers_1.refConst)({
|
|
98
|
+
type: "array",
|
|
99
|
+
value: [{ type: "date", value: "2020-01-01" }],
|
|
100
|
+
}),
|
|
101
|
+
},
|
|
102
|
+
}),
|
|
103
|
+
],
|
|
104
|
+
}),
|
|
105
|
+
actions: [],
|
|
106
|
+
}),
|
|
107
|
+
];
|
|
108
|
+
const issues = (0, guardrails_1.validateBuilderRules)(schema(), rules);
|
|
109
|
+
expect(issues.length).toBe(0);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
//# sourceMappingURL=guardrails-equals-one-of-elements.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails-equals-one-of-elements.spec.js","sourceRoot":"","sources":["../../src/__tests__/guardrails-equals-one-of-elements.spec.ts"],"names":[],"mappings":";;AACA,wCAA+G;AAC/G,8CAAoD;AAEpD,SAAS,MAAM;IACb,OAAO;QACL,EAAE,EAAE,UAAU;QACd,OAAO,EAAE,CAAC;QACV,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE;YACN,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE;YACnD,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;SAClD;KACF,CAAA;AACH,CAAC;AAED,QAAQ,CAAC,4DAA4D,EAAE,GAAG,EAAE;IAC1E,IAAI,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACxD,MAAM,KAAK,GAAG;YACZ,IAAA,2BAAiB,EAAC;gBAChB,EAAE,EAAE,IAAI;gBACR,UAAU,EAAE,IAAA,8BAAoB,EAAC;oBAC/B,EAAE,EAAE,IAAI;oBACR,SAAS,EAAE,KAAK;oBAChB,UAAU,EAAE;wBACV,IAAA,+BAAqB,EAAC;4BACpB,EAAE,EAAE,IAAI;4BACR,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAA,kBAAQ,EAAC,GAAG,CAAC,EAAE;4BACzC,QAAQ,EAAE,eAAe;4BACzB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;yBAC5C,CAAC;qBACH;iBACF,CAAC;gBACF,OAAO,EAAE,EAAE;aACZ,CAAC;SACH,CAAA;QAED,MAAM,MAAM,GAAG,IAAA,iCAAoB,EAAC,MAAM,EAAE,EAAE,KAAK,CAAC,CAAA;QACpD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC/B,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,iDAAiD,EAAE,GAAG,EAAE;QAC3D,MAAM,KAAK,GAAG;YACZ,IAAA,2BAAiB,EAAC;gBAChB,EAAE,EAAE,IAAI;gBACR,UAAU,EAAE,IAAA,8BAAoB,EAAC;oBAC/B,EAAE,EAAE,IAAI;oBACR,SAAS,EAAE,KAAK;oBAChB,UAAU,EAAE;wBACV,IAAA,+BAAqB,EAAC;4BACpB,EAAE,EAAE,IAAI;4BACR,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAA,kBAAQ,EAAC,GAAG,CAAC,EAAE;4BACzC,QAAQ,EAAE,eAAe;4BACzB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;yBAC7C,CAAC;qBACH;iBACF,CAAC;gBACF,OAAO,EAAE,EAAE;aACZ,CAAC;SACH,CAAA;QAED,MAAM,MAAM,GAAG,IAAA,iCAAoB,EAAC,MAAM,EAAE,EAAE,KAAK,CAAC,CAAA;QACpD,MAAM,CACJ,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,4CAA4C,CAAC,CAAC,CACrF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACd,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,uDAAuD,EAAE,GAAG,EAAE;QACjE,MAAM,KAAK,GAAG;YACZ,IAAA,2BAAiB,EAAC;gBAChB,EAAE,EAAE,IAAI;gBACR,UAAU,EAAE,IAAA,8BAAoB,EAAC;oBAC/B,EAAE,EAAE,IAAI;oBACR,SAAS,EAAE,KAAK;oBAChB,UAAU,EAAE;wBACV,IAAA,+BAAqB,EAAC;4BACpB,EAAE,EAAE,IAAI;4BACR,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAA,kBAAQ,EAAC,GAAG,CAAC,EAAE;4BACzC,QAAQ,EAAE,eAAe;4BACzB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,YAAY,CAAC,EAAE;yBACjD,CAAC;qBACH;iBACF,CAAC;gBACF,OAAO,EAAE,EAAE;aACZ,CAAC;SACH,CAAA;QAED,MAAM,MAAM,GAAG,IAAA,iCAAoB,EAAC,MAAM,EAAE,EAAE,KAAK,CAAC,CAAA;QACpD,MAAM,CACJ,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,wDAAwD,CAAC,CAAC,CACjG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACd,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACxE,MAAM,KAAK,GAAG;YACZ,IAAA,2BAAiB,EAAC;gBAChB,EAAE,EAAE,IAAI;gBACR,UAAU,EAAE,IAAA,8BAAoB,EAAC;oBAC/B,EAAE,EAAE,IAAI;oBACR,SAAS,EAAE,KAAK;oBAChB,UAAU,EAAE;wBACV,IAAA,+BAAqB,EAAC;4BACpB,EAAE,EAAE,IAAI;4BACR,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAA,kBAAQ,EAAC,GAAG,CAAC,EAAE;4BACzC,QAAQ,EAAE,eAAe;4BACzB,KAAK,EAAE;gCACL,IAAI,EAAE,KAAK;gCACX,GAAG,EAAE,IAAA,kBAAQ,EAAC;oCACZ,IAAI,EAAE,OAAO;oCACb,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;iCAC/C,CAAC;6BACH;yBACF,CAAC;qBACH;iBACF,CAAC;gBACF,OAAO,EAAE,EAAE;aACZ,CAAC;SACH,CAAA;QAED,MAAM,MAAM,GAAG,IAAA,iCAAoB,EAAC,MAAM,EAAE,EAAE,KAAK,CAAC,CAAA;QACpD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC/B,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails-operator-rhs.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/guardrails-operator-rhs.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const helpers_1 = require("../helpers");
|
|
4
|
+
const guardrails_1 = require("../guardrails");
|
|
5
|
+
function schema() {
|
|
6
|
+
return {
|
|
7
|
+
id: "schema_1",
|
|
8
|
+
version: 1,
|
|
9
|
+
name: "Test Schema",
|
|
10
|
+
fields: [{ key: "name", value_type: "string", required: false }],
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
const OPERATORS_WITHOUT_RIGHT = [
|
|
14
|
+
"is_submitted",
|
|
15
|
+
"is_skipped",
|
|
16
|
+
"is_clicked",
|
|
17
|
+
"is_accepted",
|
|
18
|
+
"is_booked",
|
|
19
|
+
"is_partially_submitted",
|
|
20
|
+
"is_completely_submitted",
|
|
21
|
+
"is_empty",
|
|
22
|
+
"is_present",
|
|
23
|
+
];
|
|
24
|
+
const OPERATORS_WITH_RIGHT = [
|
|
25
|
+
"equals",
|
|
26
|
+
"does_not_equal",
|
|
27
|
+
"contains",
|
|
28
|
+
"does_not_contain",
|
|
29
|
+
"starts_with",
|
|
30
|
+
"does_not_start_with",
|
|
31
|
+
"ends_with",
|
|
32
|
+
"does_not_end_with",
|
|
33
|
+
"is_greater_than",
|
|
34
|
+
"is_less_than",
|
|
35
|
+
"is_greater_than_or_equal",
|
|
36
|
+
"is_less_than_or_equal",
|
|
37
|
+
"equals_one_of",
|
|
38
|
+
"includes_all_of",
|
|
39
|
+
"includes_one_of",
|
|
40
|
+
"does_not_include_one_of",
|
|
41
|
+
"does_not_include_all_of",
|
|
42
|
+
"is_before",
|
|
43
|
+
"is_after",
|
|
44
|
+
];
|
|
45
|
+
describe("validateBuilderRules (RHS presence rules)", () => {
|
|
46
|
+
test.each(OPERATORS_WITHOUT_RIGHT)("%s rejects an explicit right operand", (op) => {
|
|
47
|
+
const rules = [
|
|
48
|
+
(0, helpers_1.createBuilderRule)({
|
|
49
|
+
id: "r1",
|
|
50
|
+
conditions: (0, helpers_1.createConditionGroup)({
|
|
51
|
+
id: "g1",
|
|
52
|
+
connector: "and",
|
|
53
|
+
conditions: [
|
|
54
|
+
(0, helpers_1.createSingleCondition)({
|
|
55
|
+
id: "c1",
|
|
56
|
+
left: { type: "ref", ref: (0, helpers_1.refField)("name") },
|
|
57
|
+
operator: op,
|
|
58
|
+
right: { type: "static", value: "x" },
|
|
59
|
+
}),
|
|
60
|
+
],
|
|
61
|
+
}),
|
|
62
|
+
actions: [],
|
|
63
|
+
}),
|
|
64
|
+
];
|
|
65
|
+
const issues = (0, guardrails_1.validateBuilderRules)(schema(), rules);
|
|
66
|
+
expect(issues.some((i) => i.message.includes("must not be present"))).toBe(true);
|
|
67
|
+
});
|
|
68
|
+
test.each(OPERATORS_WITH_RIGHT)("%s requires a right operand", (op) => {
|
|
69
|
+
const rules = [
|
|
70
|
+
(0, helpers_1.createBuilderRule)({
|
|
71
|
+
id: "r1",
|
|
72
|
+
conditions: (0, helpers_1.createConditionGroup)({
|
|
73
|
+
id: "g1",
|
|
74
|
+
connector: "and",
|
|
75
|
+
conditions: [
|
|
76
|
+
(0, helpers_1.createSingleCondition)({
|
|
77
|
+
id: "c1",
|
|
78
|
+
left: { type: "ref", ref: (0, helpers_1.refField)("name") },
|
|
79
|
+
operator: op,
|
|
80
|
+
right: null,
|
|
81
|
+
}),
|
|
82
|
+
],
|
|
83
|
+
}),
|
|
84
|
+
actions: [],
|
|
85
|
+
}),
|
|
86
|
+
];
|
|
87
|
+
const issues = (0, guardrails_1.validateBuilderRules)(schema(), rules);
|
|
88
|
+
expect(issues.some((i) => i.message.includes("Right operand is required"))).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
//# sourceMappingURL=guardrails-operator-rhs.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails-operator-rhs.spec.js","sourceRoot":"","sources":["../../src/__tests__/guardrails-operator-rhs.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails-operator-type-matrix.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/guardrails-operator-type-matrix.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const helpers_1 = require("../helpers");
|
|
4
|
+
const guardrails_1 = require("../guardrails");
|
|
5
|
+
function schema() {
|
|
6
|
+
return {
|
|
7
|
+
id: "schema_1",
|
|
8
|
+
version: 1,
|
|
9
|
+
name: "Test Schema",
|
|
10
|
+
fields: [
|
|
11
|
+
{ key: "s", value_type: "string", required: false },
|
|
12
|
+
{ key: "n", value_type: "number", required: false },
|
|
13
|
+
{ key: "d", value_type: "date", required: false },
|
|
14
|
+
{ key: "a", value_type: "array", required: false },
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function validateSingle(params) {
|
|
19
|
+
const rules = [
|
|
20
|
+
(0, helpers_1.createBuilderRule)({
|
|
21
|
+
id: "r1",
|
|
22
|
+
conditions: (0, helpers_1.createConditionGroup)({
|
|
23
|
+
id: "g1",
|
|
24
|
+
connector: "and",
|
|
25
|
+
conditions: [
|
|
26
|
+
(0, helpers_1.createSingleCondition)({
|
|
27
|
+
id: "c1",
|
|
28
|
+
left: { type: "ref", ref: (0, helpers_1.refField)(params.leftField) },
|
|
29
|
+
operator: params.operator,
|
|
30
|
+
right: params.right,
|
|
31
|
+
}),
|
|
32
|
+
],
|
|
33
|
+
}),
|
|
34
|
+
actions: [],
|
|
35
|
+
}),
|
|
36
|
+
];
|
|
37
|
+
return (0, guardrails_1.validateBuilderRules)(schema(), rules);
|
|
38
|
+
}
|
|
39
|
+
const STRING_ONLY = [
|
|
40
|
+
"contains",
|
|
41
|
+
"does_not_contain",
|
|
42
|
+
"starts_with",
|
|
43
|
+
"does_not_start_with",
|
|
44
|
+
"ends_with",
|
|
45
|
+
"does_not_end_with",
|
|
46
|
+
];
|
|
47
|
+
const NUMBER_ONLY = [
|
|
48
|
+
"is_greater_than",
|
|
49
|
+
"is_less_than",
|
|
50
|
+
"is_greater_than_or_equal",
|
|
51
|
+
"is_less_than_or_equal",
|
|
52
|
+
];
|
|
53
|
+
const DATE_ONLY = ["is_before", "is_after"];
|
|
54
|
+
const ARRAY_ONLY = [
|
|
55
|
+
"includes_all_of",
|
|
56
|
+
"includes_one_of",
|
|
57
|
+
"does_not_include_one_of",
|
|
58
|
+
"does_not_include_all_of",
|
|
59
|
+
];
|
|
60
|
+
describe("validateBuilderRules (operator/type matrix)", () => {
|
|
61
|
+
test.each(STRING_ONLY)("%s rejects non-string left operand", (op) => {
|
|
62
|
+
const issues = validateSingle({
|
|
63
|
+
leftField: "n",
|
|
64
|
+
operator: op,
|
|
65
|
+
right: { type: "static", value: "x" },
|
|
66
|
+
});
|
|
67
|
+
expect(issues.some((i) => i.message.includes("string-like operands"))).toBe(true);
|
|
68
|
+
});
|
|
69
|
+
test.each(NUMBER_ONLY)("%s rejects non-number left operand", (op) => {
|
|
70
|
+
const issues = validateSingle({
|
|
71
|
+
leftField: "s",
|
|
72
|
+
operator: op,
|
|
73
|
+
right: { type: "static", value: 1 },
|
|
74
|
+
});
|
|
75
|
+
expect(issues.some((i) => i.message.includes("only valid for number operands"))).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
test.each(DATE_ONLY)("%s rejects non-date left operand", (op) => {
|
|
78
|
+
const issues = validateSingle({
|
|
79
|
+
leftField: "s",
|
|
80
|
+
operator: op,
|
|
81
|
+
right: { type: "ref", ref: (0, helpers_1.refConst)({ type: "date", value: "2020-01-01" }) },
|
|
82
|
+
});
|
|
83
|
+
expect(issues.some((i) => i.message.includes("only valid for date operands"))).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
test.each(ARRAY_ONLY)("%s rejects non-array left operand", (op) => {
|
|
86
|
+
const issues = validateSingle({
|
|
87
|
+
leftField: "s",
|
|
88
|
+
operator: op,
|
|
89
|
+
right: { type: "static", value: ["x"] },
|
|
90
|
+
});
|
|
91
|
+
expect(issues.some((i) => i.message.includes("only valid for array operands"))).toBe(true);
|
|
92
|
+
});
|
|
93
|
+
test.each(ARRAY_ONLY)("%s accepts array left/right operands", (op) => {
|
|
94
|
+
const issues = validateSingle({
|
|
95
|
+
leftField: "a",
|
|
96
|
+
operator: op,
|
|
97
|
+
right: { type: "static", value: ["x"] },
|
|
98
|
+
});
|
|
99
|
+
expect(issues.length).toBe(0);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
//# sourceMappingURL=guardrails-operator-type-matrix.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails-operator-type-matrix.spec.js","sourceRoot":"","sources":["../../src/__tests__/guardrails-operator-type-matrix.spec.ts"],"names":[],"mappings":";;AACA,wCAA+G;AAC/G,8CAAoD;AAEpD,SAAS,MAAM;IACb,OAAO;QACL,EAAE,EAAE,UAAU;QACd,OAAO,EAAE,CAAC;QACV,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE;YACN,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE;YACnD,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE;YACnD,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;YACjD,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;SACnD;KACF,CAAA;AACH,CAAC;AAED,SAAS,cAAc,CAAC,MAOvB;IACC,MAAM,KAAK,GAAG;QACZ,IAAA,2BAAiB,EAAC;YAChB,EAAE,EAAE,IAAI;YACR,UAAU,EAAE,IAAA,8BAAoB,EAAC;gBAC/B,EAAE,EAAE,IAAI;gBACR,SAAS,EAAE,KAAK;gBAChB,UAAU,EAAE;oBACV,IAAA,+BAAqB,EAAC;wBACpB,EAAE,EAAE,IAAI;wBACR,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAA,kBAAQ,EAAC,MAAM,CAAC,SAAS,CAAC,EAAE;wBACtD,QAAQ,EAAE,MAAM,CAAC,QAAQ;wBACzB,KAAK,EAAE,MAAM,CAAC,KAAK;qBACpB,CAAC;iBACH;aACF,CAAC;YACF,OAAO,EAAE,EAAE;SACZ,CAAC;KACH,CAAA;IACD,OAAO,IAAA,iCAAoB,EAAC,MAAM,EAAE,EAAE,KAAK,CAAC,CAAA;AAC9C,CAAC;AAED,MAAM,WAAW,GAAqC;IACpD,UAAU;IACV,kBAAkB;IAClB,aAAa;IACb,qBAAqB;IACrB,WAAW;IACX,mBAAmB;CACpB,CAAA;AAED,MAAM,WAAW,GAAqC;IACpD,iBAAiB;IACjB,cAAc;IACd,0BAA0B;IAC1B,uBAAuB;CACxB,CAAA;AAED,MAAM,SAAS,GAAqC,CAAC,WAAW,EAAE,UAAU,CAAC,CAAA;AAE7E,MAAM,UAAU,GAAqC;IACnD,iBAAiB;IACjB,iBAAiB;IACjB,yBAAyB;IACzB,yBAAyB;CAC1B,CAAA;AAED,QAAQ,CAAC,6CAA6C,EAAE,GAAG,EAAE;IAC3D,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,oCAAoC,EAAE,CAAC,EAAE,EAAE,EAAE;QAClE,MAAM,MAAM,GAAG,cAAc,CAAC;YAC5B,SAAS,EAAE,GAAG;YACd,QAAQ,EAAE,EAAE;YACZ,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;SACtC,CAAC,CAAA;QACF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACnF,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,oCAAoC,EAAE,CAAC,EAAE,EAAE,EAAE;QAClE,MAAM,MAAM,GAAG,cAAc,CAAC;YAC5B,SAAS,EAAE,GAAG;YACd,QAAQ,EAAE,EAAE;YACZ,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE;SACpC,CAAC,CAAA;QACF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC7F,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,kCAAkC,EAAE,CAAC,EAAE,EAAE,EAAE;QAC9D,MAAM,MAAM,GAAG,cAAc,CAAC;YAC5B,SAAS,EAAE,GAAG;YACd,QAAQ,EAAE,EAAE;YACZ,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAA,kBAAQ,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,EAAE;SAC7E,CAAC,CAAA;QACF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3F,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,mCAAmC,EAAE,CAAC,EAAE,EAAE,EAAE;QAChE,MAAM,MAAM,GAAG,cAAc,CAAC;YAC5B,SAAS,EAAE,GAAG;YACd,QAAQ,EAAE,EAAE;YACZ,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE;SACxC,CAAC,CAAA;QACF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,+BAA+B,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC5F,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,sCAAsC,EAAE,CAAC,EAAE,EAAE,EAAE;QACnE,MAAM,MAAM,GAAG,cAAc,CAAC;YAC5B,SAAS,EAAE,GAAG;YACd,QAAQ,EAAE,EAAE;YACZ,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE;SACxC,CAAC,CAAA;QACF,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC/B,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails-operators.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/guardrails-operators.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const helpers_1 = require("../helpers");
|
|
4
|
+
const guardrails_1 = require("../guardrails");
|
|
5
|
+
function baseSchema() {
|
|
6
|
+
return {
|
|
7
|
+
id: "schema_1",
|
|
8
|
+
version: 1,
|
|
9
|
+
name: "Test Schema",
|
|
10
|
+
fields: [
|
|
11
|
+
{ key: "name", value_type: "string", required: false },
|
|
12
|
+
{ key: "age", value_type: "number", required: false },
|
|
13
|
+
{ key: "tags", value_type: "array", required: false },
|
|
14
|
+
{ key: "dob", value_type: "date", required: false },
|
|
15
|
+
],
|
|
16
|
+
variables: [
|
|
17
|
+
{ id: "v_num", name: "score", value_type: "number", default_value: 0 },
|
|
18
|
+
{ id: "v_txt", name: "note", value_type: "text", default_value: "" },
|
|
19
|
+
],
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
describe("validateBuilderRules (operator/type guardrails)", () => {
|
|
23
|
+
test("rejects string-only operator on number field", () => {
|
|
24
|
+
const schema = baseSchema();
|
|
25
|
+
const rules = [
|
|
26
|
+
(0, helpers_1.createBuilderRule)({
|
|
27
|
+
id: "r1",
|
|
28
|
+
conditions: (0, helpers_1.createConditionGroup)({
|
|
29
|
+
id: "g1",
|
|
30
|
+
connector: "and",
|
|
31
|
+
conditions: [
|
|
32
|
+
(0, helpers_1.createSingleCondition)({
|
|
33
|
+
id: "c1",
|
|
34
|
+
left: { type: "ref", ref: (0, helpers_1.refField)("age") },
|
|
35
|
+
operator: "contains",
|
|
36
|
+
right: { type: "static", value: "1" },
|
|
37
|
+
}),
|
|
38
|
+
],
|
|
39
|
+
}),
|
|
40
|
+
actions: [],
|
|
41
|
+
}),
|
|
42
|
+
];
|
|
43
|
+
const issues = (0, guardrails_1.validateBuilderRules)(schema, rules);
|
|
44
|
+
expect(issues.some((i) => i.message.includes("string-like operands"))).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
test("requires equals_one_of RHS to be an array", () => {
|
|
47
|
+
const schema = baseSchema();
|
|
48
|
+
const rules = [
|
|
49
|
+
(0, helpers_1.createBuilderRule)({
|
|
50
|
+
id: "r1",
|
|
51
|
+
conditions: (0, helpers_1.createConditionGroup)({
|
|
52
|
+
id: "g1",
|
|
53
|
+
connector: "and",
|
|
54
|
+
conditions: [
|
|
55
|
+
(0, helpers_1.createSingleCondition)({
|
|
56
|
+
id: "c1",
|
|
57
|
+
left: { type: "ref", ref: (0, helpers_1.refField)("name") },
|
|
58
|
+
operator: "equals_one_of",
|
|
59
|
+
right: { type: "static", value: "bob" },
|
|
60
|
+
}),
|
|
61
|
+
],
|
|
62
|
+
}),
|
|
63
|
+
actions: [],
|
|
64
|
+
}),
|
|
65
|
+
];
|
|
66
|
+
const issues = (0, guardrails_1.validateBuilderRules)(schema, rules);
|
|
67
|
+
expect(issues.some((i) => i.message.includes('Operator "equals_one_of" requires an array right operand') &&
|
|
68
|
+
(i.path?.join(".") ?? "").includes("right"))).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
test("interaction operators require left to be a field ref", () => {
|
|
71
|
+
const schema = baseSchema();
|
|
72
|
+
const rules = [
|
|
73
|
+
(0, helpers_1.createBuilderRule)({
|
|
74
|
+
id: "r1",
|
|
75
|
+
conditions: (0, helpers_1.createConditionGroup)({
|
|
76
|
+
id: "g1",
|
|
77
|
+
connector: "and",
|
|
78
|
+
conditions: [
|
|
79
|
+
(0, helpers_1.createSingleCondition)({
|
|
80
|
+
id: "c1",
|
|
81
|
+
left: { type: "ref", ref: (0, helpers_1.refHiddenField)("hidden") },
|
|
82
|
+
operator: "is_clicked",
|
|
83
|
+
right: null,
|
|
84
|
+
}),
|
|
85
|
+
],
|
|
86
|
+
}),
|
|
87
|
+
actions: [],
|
|
88
|
+
}),
|
|
89
|
+
];
|
|
90
|
+
const issues = (0, guardrails_1.validateBuilderRules)(schema, rules);
|
|
91
|
+
expect(issues.some((i) => i.message.includes('requires left operand to be a field reference'))).toBe(true);
|
|
92
|
+
});
|
|
93
|
+
test("rejects non-string operator for hidden fields", () => {
|
|
94
|
+
const schema = baseSchema();
|
|
95
|
+
const rules = [
|
|
96
|
+
(0, helpers_1.createBuilderRule)({
|
|
97
|
+
id: "r1",
|
|
98
|
+
conditions: (0, helpers_1.createConditionGroup)({
|
|
99
|
+
id: "g1",
|
|
100
|
+
connector: "and",
|
|
101
|
+
conditions: [
|
|
102
|
+
(0, helpers_1.createSingleCondition)({
|
|
103
|
+
id: "c1",
|
|
104
|
+
left: { type: "ref", ref: (0, helpers_1.refHiddenField)("hidden") },
|
|
105
|
+
operator: "is_greater_than",
|
|
106
|
+
right: { type: "static", value: 1 },
|
|
107
|
+
}),
|
|
108
|
+
],
|
|
109
|
+
}),
|
|
110
|
+
actions: [],
|
|
111
|
+
}),
|
|
112
|
+
];
|
|
113
|
+
const issues = (0, guardrails_1.validateBuilderRules)(schema, rules);
|
|
114
|
+
expect(issues.some((i) => i.message.includes("not valid for hidden fields"))).toBe(true);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
//# sourceMappingURL=guardrails-operators.spec.js.map
|