@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.
- package/dist/public-api.d.mts +35 -11
- package/dist/public-api.d.ts +35 -11
- package/dist/public-api.js +455 -47
- package/dist/public-api.mjs +427 -37
- package/package.json +3 -4
- package/src/Builder-option.ts +51 -52
- package/src/Builder-schema.ts +1 -0
- package/src/public-api.ts +3 -0
- package/src/rulebuilder/Builder-rule.spec.ts +266 -182
- package/src/rulebuilder/Builder-rule.ts +106 -67
- package/src/rulebuilder/Rule2.ts +87 -0
- package/src/rulebuilder/RuleBuilder-test-utils.ts +250 -239
- package/src/rulebuilder/RuleVariable.ts +13 -9
- package/src/rulebuilder/SingleSelectItem.ts +118 -118
- package/src/rulebuilder/{Builder-condition-group.ts → condition/Builder-condition-group.ts} +42 -33
- package/src/rulebuilder/condition/Builder-condition.spec.ts +185 -0
- package/src/rulebuilder/condition/Builder-condition.ts +208 -0
- package/src/rulebuilder/index.ts +11 -11
- package/src/rulebuilder/jump-to-action-manager.ts +26 -26
- package/src/rulebuilder/page-action-manager.ts +23 -13
- package/src/rulebuilder/tag-action-manager.ts +23 -13
- package/src/theme/default-theme-compiler.ts +26 -1
- package/src/rulebuilder/Builder-condition.spec.ts +0 -169
- package/src/rulebuilder/Builder-condition.ts +0 -186
- /package/src/rulebuilder/{Builder-condition-group.spec.ts → condition/Builder-condition-group.spec.ts} +0 -0
- /package/src/rulebuilder/{Builder-operator.spec.ts → condition/Builder-operator.spec.ts} +0 -0
- /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
|
|
10
|
-
import type { RuleInput } from
|
|
11
|
-
import { BuilderObject } from
|
|
12
|
-
import { TagActionManager } from
|
|
13
|
-
import { PageActionManager } from
|
|
14
|
-
import { JumpToActionManager } from
|
|
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<
|
|
27
|
-
readonly objectType:
|
|
28
|
-
private _type: ConditionGroupType =
|
|
29
|
-
public 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 ??
|
|
53
|
-
this._conditions = dto.conditions.reduce<
|
|
54
|
-
|
|
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 ===
|
|
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
|
-
|
|
77
|
-
|
|
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:
|
|
134
|
-
name:
|
|
135
|
-
type:
|
|
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
|
+
}
|