@media-quest/builder 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/public-api.d.mts +35 -11
  2. package/dist/public-api.d.ts +35 -11
  3. package/dist/public-api.js +455 -47
  4. package/dist/public-api.mjs +427 -37
  5. package/package.json +3 -4
  6. package/src/Builder-option.ts +51 -52
  7. package/src/Builder-schema.ts +1 -0
  8. package/src/public-api.ts +3 -0
  9. package/src/rulebuilder/Builder-rule.spec.ts +266 -182
  10. package/src/rulebuilder/Builder-rule.ts +106 -67
  11. package/src/rulebuilder/Rule2.ts +87 -0
  12. package/src/rulebuilder/RuleBuilder-test-utils.ts +250 -239
  13. package/src/rulebuilder/RuleVariable.ts +13 -9
  14. package/src/rulebuilder/SingleSelectItem.ts +118 -118
  15. package/src/rulebuilder/{Builder-condition-group.ts → condition/Builder-condition-group.ts} +42 -33
  16. package/src/rulebuilder/condition/Builder-condition.spec.ts +185 -0
  17. package/src/rulebuilder/condition/Builder-condition.ts +208 -0
  18. package/src/rulebuilder/index.ts +11 -11
  19. package/src/rulebuilder/jump-to-action-manager.ts +26 -26
  20. package/src/rulebuilder/page-action-manager.ts +23 -13
  21. package/src/rulebuilder/tag-action-manager.ts +23 -13
  22. package/src/theme/default-theme-compiler.ts +26 -1
  23. package/src/rulebuilder/Builder-condition.spec.ts +0 -169
  24. package/src/rulebuilder/Builder-condition.ts +0 -186
  25. /package/src/rulebuilder/{Builder-condition-group.spec.ts → condition/Builder-condition-group.spec.ts} +0 -0
  26. /package/src/rulebuilder/{Builder-operator.spec.ts → condition/Builder-operator.spec.ts} +0 -0
  27. /package/src/rulebuilder/{Builder-operator.ts → condition/Builder-operator.ts} +0 -0
@@ -1,135 +1,135 @@
1
1
  import { BuilderVariable, BuilderVariableOption } from "./RuleVariable";
2
- import { BuilderOperator } from "./Builder-operator";
2
+ import { BuilderOperator } from "./condition/Builder-operator";
3
3
  import { JumpToPageAction } from "./RuleAction";
4
4
 
5
5
  export abstract class SingleSelectItem<T> {
6
- private readonly _selectLabel;
7
- private readonly _toolTip;
8
- private readonly _searchString;
9
- get selectLabel(): string {
10
- return this._selectLabel;
11
- }
12
- get tooltip() {
13
- return this._toolTip;
14
- }
15
-
16
- get searchString() {
17
- return this._searchString;
18
- }
19
-
20
- protected constructor(readonly data: T) {
21
- this._selectLabel = this.getSelectLabel();
22
- this._toolTip = this.getTooltip();
23
- this._searchString = this.getSearchString();
24
- }
25
- protected abstract getSelectLabel(): string;
26
- protected abstract getTooltip(): string;
27
- protected abstract getSearchString(): string;
6
+ private readonly _selectLabel;
7
+ private readonly _toolTip;
8
+ private readonly _searchString;
9
+ get selectLabel(): string {
10
+ return this._selectLabel;
11
+ }
12
+ get tooltip() {
13
+ return this._toolTip;
14
+ }
15
+
16
+ get searchString() {
17
+ return this._searchString;
18
+ }
19
+
20
+ protected constructor(readonly data: T) {
21
+ this._selectLabel = this.getSelectLabel();
22
+ this._toolTip = this.getTooltip();
23
+ this._searchString = this.getSearchString();
24
+ }
25
+ protected abstract getSelectLabel(): string;
26
+ protected abstract getTooltip(): string;
27
+ protected abstract getSearchString(): string;
28
28
  }
29
29
 
30
30
  export class RuleVariableSelectItem extends SingleSelectItem<BuilderVariable> {
31
- public static create = (data: BuilderVariable) => {
32
- return new RuleVariableSelectItem(data);
33
- };
34
- readonly options: ReadonlyArray<RuleOptionSelectItem>;
35
- constructor(readonly data: BuilderVariable) {
36
- super(data);
37
- this.options = data.options.map(RuleOptionSelectItem.create);
38
- }
39
-
40
- protected getSearchString(): string {
41
- return this.data.varId + this.data.label;
42
- }
43
-
44
- getSelectLabel(): string {
45
- return this.data.varId;
46
- }
47
-
48
- getTooltip(): string {
49
- return this.data.label;
50
- }
31
+ public static create = (data: BuilderVariable) => {
32
+ return new RuleVariableSelectItem(data);
33
+ };
34
+ readonly options: ReadonlyArray<RuleOptionSelectItem>;
35
+ constructor(readonly data: BuilderVariable) {
36
+ super(data);
37
+ this.options = data.options.map(RuleOptionSelectItem.create);
38
+ }
39
+
40
+ protected getSearchString(): string {
41
+ return this.data.varId + this.data.label;
42
+ }
43
+
44
+ getSelectLabel(): string {
45
+ return this.data.varId;
46
+ }
47
+
48
+ getTooltip(): string {
49
+ return this.data.label;
50
+ }
51
51
  }
52
52
 
53
53
  export class RuleOptionSelectItem extends SingleSelectItem<BuilderVariableOption> {
54
- public static create = (option: BuilderVariableOption) => {
55
- return new RuleOptionSelectItem(option);
56
- };
57
- private constructor(option: BuilderVariableOption) {
58
- super(option);
59
- }
60
- protected getSearchString(): string {
61
- return "";
62
- }
63
-
64
- protected getSelectLabel(): string {
65
- return this.data.label + "(" + this.data.value + ")";
66
- }
67
-
68
- protected getTooltip(): string {
69
- return "";
70
- }
54
+ public static create = (option: BuilderVariableOption) => {
55
+ return new RuleOptionSelectItem(option);
56
+ };
57
+ private constructor(option: BuilderVariableOption) {
58
+ super(option);
59
+ }
60
+ protected getSearchString(): string {
61
+ return "";
62
+ }
63
+
64
+ protected getSelectLabel(): string {
65
+ return this.data.label + "(" + this.data.value + ")";
66
+ }
67
+
68
+ protected getTooltip(): string {
69
+ return "";
70
+ }
71
71
  }
72
72
 
73
73
  export class OperatorSelectItem extends SingleSelectItem<BuilderOperator | ""> {
74
- public static readonly EQ = new OperatorSelectItem("equal");
75
- public static readonly NOT_EQ = new OperatorSelectItem("notEqual");
76
- public static readonly fromSymbol = (
77
- symbol: BuilderOperator | Omit<string, BuilderOperator>
78
- ): OperatorSelectItem | false => {
79
- if (symbol === "equal") {
80
- return OperatorSelectItem.EQ;
81
- }
82
- if (symbol === "notEqual") {
83
- return OperatorSelectItem.NOT_EQ;
84
- }
85
- return false;
86
- };
87
- private constructor(operator: BuilderOperator) {
88
- super(operator);
89
- }
90
-
91
- protected getSearchString(): string {
92
- return "";
93
- }
94
-
95
- protected getSelectLabel(): string {
96
- const operator = this.data;
97
- if (operator === "equal") {
98
- return "Equals";
99
- }
100
- if (operator === "notEqual") {
101
- return "Not equals";
102
- }
103
- return "";
104
- }
105
-
106
- protected getTooltip(): string {
107
- const operator = this.data;
108
- if (operator === "equal") {
109
- return "Equals";
110
- }
111
- if (operator === "notEqual") {
112
- return "Not equals";
113
- }
114
- return "";
115
- }
74
+ public static readonly EQ = new OperatorSelectItem("equal");
75
+ public static readonly NOT_EQ = new OperatorSelectItem("notEqual");
76
+ public static readonly fromSymbol = (
77
+ symbol: BuilderOperator | Omit<string, BuilderOperator>,
78
+ ): OperatorSelectItem | false => {
79
+ if (symbol === "equal") {
80
+ return OperatorSelectItem.EQ;
81
+ }
82
+ if (symbol === "notEqual") {
83
+ return OperatorSelectItem.NOT_EQ;
84
+ }
85
+ return false;
86
+ };
87
+ private constructor(operator: BuilderOperator) {
88
+ super(operator);
89
+ }
90
+
91
+ protected getSearchString(): string {
92
+ return "";
93
+ }
94
+
95
+ protected getSelectLabel(): string {
96
+ const operator = this.data;
97
+ if (operator === "equal") {
98
+ return "Equals";
99
+ }
100
+ if (operator === "notEqual") {
101
+ return "Not equals";
102
+ }
103
+ return "";
104
+ }
105
+
106
+ protected getTooltip(): string {
107
+ const operator = this.data;
108
+ if (operator === "equal") {
109
+ return "Equals";
110
+ }
111
+ if (operator === "notEqual") {
112
+ return "Not equals";
113
+ }
114
+ return "";
115
+ }
116
116
  }
117
117
 
118
118
  export class JumpToPageSelectItem extends SingleSelectItem<JumpToPageAction> {
119
- public static readonly create = (pageData: JumpToPageAction) => new JumpToPageSelectItem(pageData);
120
- protected constructor(pageData: JumpToPageAction) {
121
- super(pageData);
122
- }
123
-
124
- protected getSearchString(): string {
125
- return this.data.pageId + this.data.mainText;
126
- }
127
-
128
- protected getSelectLabel(): string {
129
- return this.data.pageId + " (" + this.data.pageNumber + ")";
130
- }
131
-
132
- protected getTooltip(): string {
133
- return this.data.mainText;
134
- }
119
+ public static readonly create = (pageData: JumpToPageAction) => new JumpToPageSelectItem(pageData);
120
+ protected constructor(pageData: JumpToPageAction) {
121
+ super(pageData);
122
+ }
123
+
124
+ protected getSearchString(): string {
125
+ return this.data.pageId + this.data.mainText;
126
+ }
127
+
128
+ protected getSelectLabel(): string {
129
+ return this.data.pageId + " (" + this.data.pageNumber + ")";
130
+ }
131
+
132
+ protected getTooltip(): string {
133
+ return this.data.mainText;
134
+ }
135
135
  }
@@ -1,62 +1,47 @@
1
- import {
2
- BuilderCondition,
3
- type BuilderConditionDto
4
- } from './Builder-condition';
5
- import { BuilderObject } from '../BuilderObject';
6
- import type { BuilderVariable } from './RuleVariable';
1
+ import { BuilderCondition, type BuilderConditionDto } from "./Builder-condition";
2
+ import { BuilderObject } from "../../BuilderObject";
3
+ import type { BuilderVariable } from "../RuleVariable";
4
+ import { Condition } from "@media-quest/engine";
7
5
 
8
6
  const ConditionGroupType = {
9
7
  all: true,
10
8
  any: true,
11
9
  count: true,
12
- range: true
10
+ range: true,
13
11
  };
14
12
 
15
13
  export type ConditionGroupType = keyof typeof ConditionGroupType;
16
14
  export interface BuilderConditionGroupDto {
17
- readonly kind: 'condition-group';
15
+ readonly kind: "condition-group";
18
16
  readonly name: string;
19
17
  readonly type: ConditionGroupType;
20
18
  readonly conditions: ReadonlyArray<BuilderConditionDto>;
21
19
  }
22
20
 
23
- export class BuilderConditionGroup extends BuilderObject<
24
- 'builder-condition-group',
25
- BuilderConditionGroupDto
26
- > {
27
- static readonly isConditionGroupType = (
28
- value: string | symbol
29
- ): value is ConditionGroupType => {
30
- if (typeof value !== 'string') {
21
+ export class BuilderConditionGroup extends BuilderObject<"builder-condition-group", BuilderConditionGroupDto> {
22
+ static readonly isConditionGroupType = (value: string | symbol): value is ConditionGroupType => {
23
+ if (typeof value !== "string") {
31
24
  return false;
32
25
  }
33
26
  const validValues = Object.keys(ConditionGroupType);
34
27
  return validValues.includes(value);
35
28
  };
36
29
 
37
- readonly objectType: 'builder-condition-group' = 'builder-condition-group';
30
+ readonly objectType: "builder-condition-group" = "builder-condition-group";
38
31
  private _type: ConditionGroupType;
39
- name = '';
32
+ name = "";
40
33
  private readonly _conditions: Array<BuilderCondition>;
41
34
  private readonly _variableList: ReadonlyArray<BuilderVariable>;
42
35
 
43
- public static readonly fromDto = (
44
- dto: BuilderConditionGroupDto,
45
- variableList: ReadonlyArray<BuilderVariable>
46
- ) => {
36
+ public static readonly fromDto = (dto: BuilderConditionGroupDto, variableList: ReadonlyArray<BuilderVariable>) => {
47
37
  return new BuilderConditionGroup(dto, variableList);
48
38
  };
49
- protected constructor(
50
- dto: BuilderConditionGroupDto,
51
- variableList: ReadonlyArray<BuilderVariable>
52
- ) {
39
+ protected constructor(dto: BuilderConditionGroupDto, variableList: ReadonlyArray<BuilderVariable>) {
53
40
  super(dto);
54
41
  this.name = dto.name;
55
42
  this._type = dto.type;
56
43
  const conditionList = Array.isArray(dto.conditions) ? dto.conditions : [];
57
- this._conditions = conditionList.map(dto =>
58
- BuilderCondition.fromDto(dto, variableList)
59
- );
44
+ this._conditions = conditionList.map((dto) => BuilderCondition.fromDto(dto, variableList));
60
45
  this._variableList = variableList;
61
46
  }
62
47
  get conditions(): ReadonlyArray<BuilderCondition> {
@@ -88,16 +73,40 @@ export class BuilderConditionGroup extends BuilderObject<
88
73
  }
89
74
 
90
75
  toJson(): BuilderConditionGroupDto {
91
- const conditions: ReadonlyArray<BuilderConditionDto> = [
92
- ...this._conditions.map(c => c.toJson())
93
- ];
76
+ const conditions: ReadonlyArray<BuilderConditionDto> = [...this._conditions.map((c) => c.toJson())];
94
77
  return {
95
78
  name: this.name,
96
79
  conditions,
97
80
  type: this._type,
98
- kind: 'condition-group'
81
+ kind: "condition-group",
99
82
  };
100
83
  }
84
+
85
+ toEngineConditionComplex(): Condition.Complex | false {
86
+ const comp: Condition.Complex = {
87
+ kind: "complex-condition",
88
+ all: [],
89
+ some: [],
90
+ name: "",
91
+ };
92
+ const conditions: Condition.Simple[] = [];
93
+ this.conditions.forEach((c) => {
94
+ const maybeSimple = c.toEngineCondition();
95
+ if (maybeSimple) {
96
+ conditions.push(maybeSimple);
97
+ }
98
+ });
99
+ if (this._type === "all") {
100
+ return { ...comp, all: conditions };
101
+ }
102
+ if (this._type === "any") {
103
+ return { ...comp, some: conditions };
104
+ }
105
+
106
+ console.log("INVALID COMPLEX CONDITION. TODO IMPLEMENT range, and count.");
107
+
108
+ return false;
109
+ }
101
110
  get type(): ConditionGroupType {
102
111
  return this._type;
103
112
  }
@@ -0,0 +1,185 @@
1
+ import { BuilderCondition, type BuilderConditionDto } from "./Builder-condition";
2
+ import { RuleBuilderTestUtils } from "../RuleBuilder-test-utils";
3
+ import type { BuilderVariable, BuilderVariableOption } from "../RuleVariable";
4
+ import { QuestionVariable } from "../RuleVariable";
5
+
6
+ let condition = BuilderCondition.create([]);
7
+
8
+ beforeEach(() => {
9
+ condition = BuilderCondition.create([]);
10
+ });
11
+
12
+ describe("Builder Operator", () => {
13
+ test("Can create", () => {
14
+ expect(condition).toBeInstanceOf(BuilderCondition);
15
+ });
16
+ test("Can resolve dto from Variables in universe.", () => {
17
+ const vs = RuleBuilderTestUtils.createBuilderVariables_A_H();
18
+ const a = vs[0];
19
+ const dto: BuilderConditionDto = {
20
+ kind: "condition",
21
+ name: "a",
22
+ variableId: a.varId,
23
+ operator: "equal",
24
+ value: 1,
25
+ };
26
+ const c = BuilderCondition.fromDto(dto, vs);
27
+ // c.setVariableList(vs);
28
+ expect(c.operatorsSelectItems.length).toBe(2);
29
+ expect(c.operator === "equal").toBe(true);
30
+ expect(c.value).toBeTruthy();
31
+ });
32
+ test("Can not resolve value if invalid value", () => {
33
+ const vs = RuleBuilderTestUtils.createBuilderVariables_A_H();
34
+ const a = vs[0];
35
+ const dto: BuilderConditionDto = {
36
+ kind: "condition",
37
+ name: "a",
38
+ variableId: a.varId,
39
+ operator: "equal",
40
+ value: 8,
41
+ };
42
+ const c = BuilderCondition.fromDto(dto, vs);
43
+ expect(c.operatorsSelectItems.length).toBe(2);
44
+ expect(c.value).toBe(false);
45
+ // expect(match).toBe(false);
46
+ });
47
+ test("Will nullify dto if not matchedFrom is called", () => {
48
+ const vs = RuleBuilderTestUtils.createBuilderVariables_A_H();
49
+ const a = vs[0];
50
+ const dto: BuilderConditionDto = {
51
+ kind: "condition",
52
+ name: "a",
53
+ variableId: a.varId,
54
+ operator: "equal",
55
+ value: 0,
56
+ };
57
+ const c = BuilderCondition.fromDto(dto, []);
58
+ expect(c.operatorsSelectItems.length).toBe(0);
59
+ expect(c.toJson().name).toBe(dto.name);
60
+ expect(c.toJson().value).toBe("");
61
+ expect(c.toJson().operator).toBe("");
62
+ expect(c.toJson().variableId).toBe("");
63
+ // expect(match).toBe(false);
64
+ });
65
+ test("Will not nullify if created with valid universe", () => {
66
+ const vs = RuleBuilderTestUtils.createBuilderVariables_A_H();
67
+ const a = vs[0];
68
+ const dto: BuilderConditionDto = {
69
+ kind: "condition",
70
+ name: "a",
71
+ variableId: a.varId,
72
+ operator: "equal",
73
+ value: 0,
74
+ };
75
+ const c = BuilderCondition.fromDto(dto, vs);
76
+ expect(c.variable).toBeInstanceOf(QuestionVariable);
77
+ expect(c.operator === "equal").toBe(true);
78
+ const value = c.value as BuilderVariableOption;
79
+ expect(value.value).toBe(0);
80
+ expect(value.label).toBe("Nei");
81
+ expect(c.variable).toBe(a);
82
+ });
83
+ test("Condition is valid, when in sync with universe.", () => {
84
+ const vs = RuleBuilderTestUtils.createBuilderVariables_A_H();
85
+ const a = vs[0];
86
+ const dto: BuilderConditionDto = {
87
+ kind: "condition",
88
+
89
+ name: "name of a",
90
+ variableId: a.varId,
91
+ operator: "equal",
92
+ value: 0,
93
+ };
94
+ const c = BuilderCondition.fromDto(dto, vs);
95
+ expect(c.variable).toBeInstanceOf(QuestionVariable);
96
+ expect(c.operator === "equal").toBe(true);
97
+ const value = c.value as BuilderVariableOption;
98
+ expect(value.value).toBe(0);
99
+ expect(value.label).toBe("Nei");
100
+ expect(c.validate().isValid).toBe(true);
101
+ });
102
+ test("Condition is invalid, when not matched against universe", () => {
103
+ const dto: BuilderConditionDto = {
104
+ kind: "condition",
105
+ name: "name of a",
106
+ variableId: "a",
107
+ operator: "equal",
108
+ value: 0,
109
+ };
110
+ const c = BuilderCondition.fromDto(dto, []);
111
+ expect(c.validate().isValid).toBe(false);
112
+ });
113
+ test("Condition is invalid, when variable dont exist in universe.", () => {
114
+ const universe = RuleBuilderTestUtils.createBuilderVariables_A_H();
115
+ const dto: BuilderConditionDto = {
116
+ kind: "condition",
117
+ name: "invalid variable name in dto",
118
+ variableId: "kkk",
119
+ operator: "equal",
120
+ value: 9,
121
+ };
122
+ const c = BuilderCondition.fromDto(dto, universe);
123
+ expect(c.variable).toBe(false);
124
+ expect(c.validate().isValid).toBe(false);
125
+ });
126
+ test("Condition is invalid if not all set, when variable dont exist in universe.", () => {
127
+ const universe = RuleBuilderTestUtils.createBuilderVariables_A_H();
128
+ const dto: BuilderConditionDto = {
129
+ kind: "condition",
130
+ name: "invalid variable name in dto",
131
+ variableId: "kkk",
132
+ operator: "equal",
133
+ value: 9,
134
+ };
135
+ const c = BuilderCondition.fromDto(dto, universe);
136
+ expect(c.variable).toBe(false);
137
+ expect(c.validate().isValid).toBe(false);
138
+ });
139
+ test("Condition is invalid if operator is not set", () => {
140
+ const universe = RuleBuilderTestUtils.createBuilderVariables_A_H();
141
+ const dto: BuilderConditionDto = {
142
+ kind: "condition",
143
+ name: "invalid variable name in dto",
144
+ variableId: "a",
145
+ operator: "",
146
+ value: 1,
147
+ };
148
+ const c = BuilderCondition.fromDto(dto, universe);
149
+ expect(c.variable).toBeInstanceOf(QuestionVariable);
150
+ expect(c.validate().isValid).toBe(false);
151
+ expect(c.value).toBe(false);
152
+ });
153
+ test("Condition is invalid if value (from dto) is not found in variable", () => {
154
+ const universe = RuleBuilderTestUtils.createBuilderVariables_A_H();
155
+ const dto: BuilderConditionDto = {
156
+ kind: "condition",
157
+ name: "invalid variable name in dto",
158
+ variableId: "a",
159
+ operator: "equal",
160
+ value: 7,
161
+ };
162
+ const c = BuilderCondition.fromDto(dto, universe);
163
+ expect(c.variable).toBeInstanceOf(QuestionVariable);
164
+ expect(c.operator).toBe("equal");
165
+ expect(c.operatorsSelectItems.length).toBe(BuilderCondition.NUMBER_OPERATORS.length);
166
+ expect(c.value).toBe(false);
167
+ expect(c.validate().isValid).toBe(false);
168
+ });
169
+ test("toEngineConditionWorks", () => {
170
+ const universe = RuleBuilderTestUtils.createBuilderVariables_A_H();
171
+ const dto: BuilderConditionDto = {
172
+ kind: "condition",
173
+ name: "invalid variable name in dto",
174
+ variableId: "a",
175
+ operator: "equal",
176
+ value: 7,
177
+ };
178
+ const c = BuilderCondition.fromDto(dto, universe);
179
+ expect(c.variable).toBeInstanceOf(QuestionVariable);
180
+ expect(c.operator).toBe("equal");
181
+ expect(c.operatorsSelectItems.length).toBe(BuilderCondition.NUMBER_OPERATORS.length);
182
+ expect(c.value).toBe(false);
183
+ expect(c.validate().isValid).toBe(false);
184
+ });
185
+ });