@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,86 +1,66 @@
1
- import {
2
- BuilderCondition,
3
- type BuilderConditionDto
4
- } from './Builder-condition';
1
+ import { BuilderCondition, type BuilderConditionDto } from "./condition/Builder-condition";
5
2
  import {
6
3
  BuilderConditionGroup,
7
4
  type BuilderConditionGroupDto,
8
- type ConditionGroupType
9
- } from './Builder-condition-group';
10
- import type { RuleInput } from './RuleInput';
11
- import { BuilderObject } from '../BuilderObject';
12
- import { TagActionManager } from './tag-action-manager';
13
- import { PageActionManager } from './page-action-manager';
14
- import { JumpToActionManager } from './jump-to-action-manager';
5
+ type ConditionGroupType,
6
+ } from "./condition/Builder-condition-group";
7
+ import type { RuleInput } from "./RuleInput";
8
+ import { BuilderObject } from "../BuilderObject";
9
+ import { TagActionManager } from "./tag-action-manager";
10
+ import { PageActionManager } from "./page-action-manager";
11
+ import { JumpToActionManager } from "./jump-to-action-manager";
12
+ import { Condition, DUtil, PageQueCommand, PageQueRules, Rule } from "@media-quest/engine";
13
+ import { ExcludeByPageAction, ExcludeByTagAction, JumpToPageAction } from "./RuleAction";
14
+ import { RuleBuilderTestUtils } from "./RuleBuilder-test-utils";
15
+ import jumpToPageAction = RuleBuilderTestUtils.jumpToPageAction;
15
16
 
16
17
  export interface BuilderRuleDto {
17
18
  readonly type: ConditionGroupType;
18
19
  readonly name: string;
19
- readonly conditions: ReadonlyArray<
20
- BuilderConditionDto | BuilderConditionGroupDto
21
- >;
20
+ readonly conditions: ReadonlyArray<BuilderConditionDto | BuilderConditionGroupDto>;
22
21
  readonly excludeTags: ReadonlyArray<string>;
23
22
  readonly excludePages: ReadonlyArray<string>;
24
23
  readonly jumpToPage: string | false;
25
24
  }
26
- export class BuilderRule extends BuilderObject<'builder-rule', BuilderRuleDto> {
27
- readonly objectType: 'builder-rule' = 'builder-rule';
28
- private _type: ConditionGroupType = 'all';
29
- public name = 'Rule name';
25
+ export class BuilderRule extends BuilderObject<"builder-rule", BuilderRuleDto> {
26
+ readonly objectType: "builder-rule" = "builder-rule";
27
+ private _type: ConditionGroupType = "all";
28
+ public name = "Rule name";
30
29
  // public countNumber = 1;
31
- private readonly _conditions: Array<
32
- BuilderCondition | BuilderConditionGroup
33
- > = [];
30
+ private readonly _conditions: Array<BuilderCondition | BuilderConditionGroup> = [];
34
31
 
35
- private _tagActionManager: TagActionManager;
32
+ private readonly _tagActionManager: TagActionManager;
36
33
  private _pageActionManager: PageActionManager;
37
34
  readonly jumpToActionManager: JumpToActionManager;
38
- public static readonly fromDto = (
39
- dto: BuilderRuleDto,
40
- input: RuleInput
41
- ): BuilderRule => {
35
+ public static readonly fromDto = (dto: BuilderRuleDto, input: RuleInput): BuilderRule => {
42
36
  return new BuilderRule(dto, input);
43
37
  };
44
38
 
45
39
  protected constructor(
46
40
  private readonly dto: BuilderRuleDto,
47
- private readonly _ruleInput: RuleInput
41
+ private readonly _ruleInput: RuleInput,
48
42
  ) {
49
43
  super(dto);
50
44
  const conditionInput = this._ruleInput.getConditionInput();
51
- this.name = dto.name ?? '';
52
- this._type = dto.type ?? 'any';
53
- this._conditions = dto.conditions.reduce<
54
- Array<BuilderCondition | BuilderConditionGroup>
55
- >((acc, curr) => {
56
- if (curr.kind === 'condition') {
45
+ this.name = dto.name ?? "";
46
+ this._type = dto.type ?? "any";
47
+ this._conditions = dto.conditions.reduce<Array<BuilderCondition | BuilderConditionGroup>>((acc, curr) => {
48
+ if (curr.kind === "condition") {
57
49
  const condition = BuilderCondition.fromDto(curr, conditionInput);
58
50
  acc.push(condition);
59
51
  }
60
- if (curr.kind === 'condition-group') {
61
- const conditionGroup = BuilderConditionGroup.fromDto(
62
- curr,
63
- conditionInput
64
- );
52
+ if (curr.kind === "condition-group") {
53
+ const conditionGroup = BuilderConditionGroup.fromDto(curr, conditionInput);
65
54
  acc.push(conditionGroup);
66
55
  }
67
56
  return acc;
68
57
  }, []);
69
58
  // TODO CHECK WITH CURRENT OPTIONS.
70
- this._pageActionManager = new PageActionManager(
71
- _ruleInput.excludeByPageIdActions,
72
- dto.excludePages
73
- );
59
+ this._pageActionManager = new PageActionManager(_ruleInput.excludeByPageIdActions, dto.excludePages);
74
60
  // this.excludeByPageIdDtoList.push(...dto.excludePages);
75
- this._tagActionManager = new TagActionManager(
76
- _ruleInput.excludeByTagActions,
77
- dto.excludeTags
78
- );
79
-
80
- this.jumpToActionManager = new JumpToActionManager(
81
- _ruleInput.jumpToPageActions,
82
- dto.jumpToPage
83
- );
61
+ this._tagActionManager = new TagActionManager(_ruleInput.excludeByTagActions, dto.excludeTags);
62
+
63
+ this.jumpToActionManager = new JumpToActionManager(_ruleInput.jumpToPageActions, dto.jumpToPage);
84
64
  }
85
65
 
86
66
  get conditions(): ReadonlyArray<BuilderConditionGroup | BuilderCondition> {
@@ -109,9 +89,7 @@ export class BuilderRule extends BuilderObject<'builder-rule', BuilderRuleDto> {
109
89
  return this._type;
110
90
  }
111
91
 
112
- deleteCondition(
113
- condition: BuilderCondition | BuilderConditionGroup
114
- ): boolean {
92
+ deleteCondition(condition: BuilderCondition | BuilderConditionGroup): boolean {
115
93
  const index = this._conditions.indexOf(condition);
116
94
  if (index < 0) {
117
95
  return false;
@@ -121,24 +99,19 @@ export class BuilderRule extends BuilderObject<'builder-rule', BuilderRuleDto> {
121
99
  }
122
100
 
123
101
  addCondition(): BuilderCondition {
124
- const condition = BuilderCondition.create(
125
- this._ruleInput.getConditionInput()
126
- );
102
+ const condition = BuilderCondition.create(this._ruleInput.getConditionInput());
127
103
  this._conditions.push(condition);
128
104
  return condition;
129
105
  }
130
106
 
131
107
  addConditionGroup(): BuilderConditionGroup {
132
108
  const dto: BuilderConditionGroupDto = {
133
- kind: 'condition-group',
134
- name: '',
135
- type: 'all',
136
- conditions: []
109
+ kind: "condition-group",
110
+ name: "",
111
+ type: "all",
112
+ conditions: [],
137
113
  };
138
- const newGroup = BuilderConditionGroup.fromDto(
139
- dto,
140
- this._ruleInput.questionVars
141
- );
114
+ const newGroup = BuilderConditionGroup.fromDto(dto, this._ruleInput.questionVars);
142
115
  this._conditions.push(newGroup);
143
116
  return newGroup;
144
117
  }
@@ -148,7 +121,7 @@ export class BuilderRule extends BuilderObject<'builder-rule', BuilderRuleDto> {
148
121
  }
149
122
 
150
123
  toJson(): BuilderRuleDto {
151
- const conditions = this._conditions.map(c => c.toJson());
124
+ const conditions = this._conditions.map((c) => c.toJson());
152
125
  const excludePages = this._pageActionManager.getCurrentSelection();
153
126
  const excludeTags = this._tagActionManager.getCurrentSelection();
154
127
  const jumpToPage = this.jumpToActionManager.getSelectedPageId();
@@ -158,8 +131,74 @@ export class BuilderRule extends BuilderObject<'builder-rule', BuilderRuleDto> {
158
131
  conditions,
159
132
  excludePages,
160
133
  jumpToPage,
161
- excludeTags
134
+ excludeTags,
162
135
  };
163
136
  return dto;
164
137
  }
138
+ toEngineRule(): PageQueRules {
139
+ const conditions: Condition[] = [];
140
+ this._conditions.forEach((c) => {
141
+ if (c) {
142
+ if (c instanceof BuilderCondition) {
143
+ const simpleCondition = c.toEngineCondition();
144
+ if (simpleCondition) {
145
+ conditions.push(simpleCondition);
146
+ }
147
+ }
148
+ if (c instanceof BuilderConditionGroup) {
149
+ const complexCondition = c.toEngineConditionComplex();
150
+ if (complexCondition) conditions.push(complexCondition);
151
+ }
152
+ }
153
+ });
154
+ let all: Condition[] = [];
155
+ let some: Condition[] = [];
156
+
157
+ if (this.type === "all") {
158
+ all = [...conditions];
159
+ }
160
+ const pageQueCommands: Array<PageQueCommand> = [];
161
+ const maybeJumpToPage = this.jumpToActionManager.selected;
162
+ if (maybeJumpToPage) {
163
+ const jumpCommand: PageQueCommand = {
164
+ kind: "PAGE_QUE_JUMP_TO_PAGE_COMMAND",
165
+ target: "PAGE_QUE",
166
+ targetId: "PAGE_QUE",
167
+ payload: { pageId: maybeJumpToPage.data.pageId },
168
+ };
169
+ pageQueCommands.push(jumpCommand);
170
+ }
171
+
172
+ const excludePageByIdList = this._pageActionManager.getEngineAction().map((a) => a.pageId);
173
+ if (excludePageByIdList.length) {
174
+ const command: PageQueCommand = {
175
+ kind: "PAGE_QUE_EXCLUDE_BY_PAGE_ID_COMMAND",
176
+ target: "PAGE_QUE",
177
+ targetId: "PAGE_QUE",
178
+ payload: { pageIds: [...excludePageByIdList] },
179
+ };
180
+ pageQueCommands.push(command);
181
+ }
182
+ const excludeTags = this._tagActionManager.getEngineActions().map((tagA) => tagA.tag);
183
+ if (excludeTags.length) {
184
+ const excludeTagsCommand: PageQueCommand = {
185
+ kind: "PAGE_QUE_EXCLUDE_BY_TAG_COMMAND",
186
+ target: "PAGE_QUE",
187
+ targetId: "PAGE_QUE",
188
+ payload: { tagIds: [...excludeTags] },
189
+ };
190
+ pageQueCommands.push(excludeTagsCommand);
191
+ }
192
+
193
+ const id = DUtil.randomObjectId();
194
+ const rule: PageQueRules = {
195
+ id: "",
196
+ description: this.name,
197
+ all,
198
+ some,
199
+ onFailure: [],
200
+ onSuccess: pageQueCommands,
201
+ };
202
+ return rule;
203
+ }
165
204
  }
@@ -0,0 +1,87 @@
1
+ import { BuilderVariableType } from "./RuleVariable";
2
+ import { BuilderOperator } from "./condition/Builder-operator";
3
+ import { BuilderConditionDto } from "./condition/Builder-condition";
4
+
5
+ type ConditionType = "all" | "any" | "";
6
+
7
+ type SolveResultType = "TRUE" | "FALSE" | "NOT_ENOUGH_DATA" | "ERROR";
8
+
9
+ type SolveErrorReason =
10
+ | "INVALID_FACT_TYPE"
11
+ | "INVALID_OPERATOR"
12
+ | "INVALID_VALUE"
13
+ | "INVALID_VARIABLE"
14
+ | "UNIMPLEMENTED_VARIABLE_TYPE"
15
+ | "UNIMPLEMENTED_OPERATOR";
16
+
17
+ type IsTrue = { readonly type: "IS_TRUE" };
18
+ type IsFalse = { readonly type: "IS_FALSE" };
19
+ type IsMissingFacts = { readonly type: "MISSING_FACTS"; readonly missingVariables: ReadonlyArray<string> };
20
+ type HasError = {
21
+ readonly type: "HAS_ERROR";
22
+ readonly reason: SolveErrorReason;
23
+ readonly data: Record<string, string>;
24
+ };
25
+ export type SolveResult = IsFalse | IsTrue | IsMissingFacts | HasError;
26
+
27
+ export interface Fact2 {
28
+ readonly variableType: "numeric";
29
+ readonly value: number;
30
+ readonly valueLabel: string;
31
+ readonly variableId: string;
32
+ readonly variableLabel: string;
33
+ }
34
+
35
+ class FactCollection {
36
+ constructor(private readonly facts: ReadonlyArray<Fact2>) {}
37
+ byId(variableId: string): Fact2 | false {
38
+ const result = this.facts.find((fact) => fact.variableId === variableId);
39
+ if (!result) {
40
+ return false;
41
+ }
42
+ return result;
43
+ }
44
+ }
45
+ interface Solvable {
46
+ isTrue(facts: FactCollection): boolean;
47
+ solve(facts: FactCollection): SolveResult;
48
+ }
49
+ interface IsValid {
50
+ isValid(): boolean;
51
+ }
52
+ export class Condition implements Solvable, IsValid {
53
+ constructor(private readonly dto: BuilderConditionDto) {}
54
+ isTrue(facts: FactCollection): boolean {
55
+ const op = this.dto.operator;
56
+ if (!BuilderOperator.is(op)) {
57
+ return false;
58
+ }
59
+
60
+ const fact = facts.byId(this.dto.variableId);
61
+
62
+ if (!fact) {
63
+ return false;
64
+ }
65
+
66
+ if (fact.variableType !== "numeric" && typeof fact.value !== "number") {
67
+ return false;
68
+ }
69
+
70
+ return false;
71
+ }
72
+ isValid(): boolean {
73
+ return false;
74
+ }
75
+
76
+ solve(facts: FactCollection): SolveResult {
77
+ return { type: "HAS_ERROR", reason: "UNIMPLEMENTED_VARIABLE_TYPE", data: {} }; // TODO
78
+ }
79
+ }
80
+ export class ConditionGroup {}
81
+ export class Rule2 {
82
+ private _count = -1;
83
+ constructor(
84
+ private readonly dto: any,
85
+ private readonly _ruleInput: any,
86
+ ) {}
87
+ }