@media-quest/builder 0.0.3 → 0.0.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@media-quest/builder",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Builder library for Media-quest schemas",
5
5
  "main": "dist/public-api.js",
6
6
  "module": "dist/public-api.mjs",
@@ -9,10 +9,10 @@
9
9
  "scripts": {
10
10
  "check": "tsc --watch --noEmit",
11
11
  "clean": "rimraf dist",
12
- "build": "npm run clean && tsup src/public-api.ts --format cjs,esm --dts",
12
+ "build": "npm run clean && tsup src/public-api.ts --sourcemap inline --format cjs,esm --dts",
13
13
  "prepublishOnly": "npm run build"
14
14
  },
15
15
  "dependencies": {
16
- "@media-quest/engine": "0.0.3"
16
+ "@media-quest/engine": "0.0.5"
17
17
  }
18
18
  }
@@ -4,64 +4,63 @@ import { DefaultTheme } from "./theme/IDefaultTheme";
4
4
  import { AudioFile } from "./media-files";
5
5
 
6
6
  export interface BuilderOptionDto {
7
- readonly id: BuilderObjectId.QuestionOptionID;
8
- readonly value: number;
9
- readonly label: string;
10
- readonly labelAudio?: AudioFile;
11
- // readonly theme: BuilderPageTheme['nextButtonTheme'];
7
+ readonly id: BuilderObjectId.QuestionOptionID;
8
+ readonly value: number;
9
+ readonly label: string;
10
+ readonly labelAudio?: AudioFile;
12
11
  }
13
12
 
14
13
  export class BuilderOption extends BuilderObject<"builder-question-option", BuilderOptionDto> {
15
- readonly objectType = "builder-question-option";
16
- theme: BuilderOptionTheme = DefaultTheme.responseButtons;
14
+ readonly objectType = "builder-question-option";
15
+ theme: BuilderOptionTheme = DefaultTheme.responseButtons;
17
16
 
18
- id: BuilderObjectId.QuestionOptionID;
19
- value: number;
20
- label = "";
21
- private _labelAudioFile: AudioFile | false = false;
22
- get labelAudioFile() {
23
- return this._labelAudioFile;
24
- }
25
- set labelAudioFile(audioFile: AudioFile | false) {
26
- this._labelAudioFile = audioFile;
27
- }
17
+ id: BuilderObjectId.QuestionOptionID;
18
+ value: number;
19
+ label = "";
20
+ private _labelAudioFile: AudioFile | false = false;
21
+ get labelAudioFile() {
22
+ return this._labelAudioFile;
23
+ }
24
+ set labelAudioFile(audioFile: AudioFile | false) {
25
+ this._labelAudioFile = audioFile;
26
+ }
28
27
 
29
- private constructor(dto: BuilderOptionDto) {
30
- super(dto);
31
- this.id = dto.id;
32
- this.value = dto.value;
33
- this.label = dto.label;
34
- // this.theme = dto.theme;
35
- }
36
- public static create(value: number, label: string) {
37
- const id = BuilderObjectId.questionOptionId();
38
- const dto: BuilderOptionDto = {
39
- id,
40
- value,
41
- label,
42
- };
43
- const instance = new BuilderOption(dto);
44
- return instance;
45
- }
28
+ private constructor(dto: BuilderOptionDto) {
29
+ super(dto);
30
+ this.id = dto.id;
31
+ this.value = dto.value;
32
+ this.label = dto.label;
33
+ // this.theme = dto.theme;
34
+ }
35
+ public static create(value: number, label: string) {
36
+ const id = BuilderObjectId.questionOptionId();
37
+ const dto: BuilderOptionDto = {
38
+ id,
39
+ value,
40
+ label,
41
+ };
42
+ const instance = new BuilderOption(dto);
43
+ return instance;
44
+ }
46
45
 
47
- public static fromJson(dto: BuilderOptionDto) {
48
- const instance = new BuilderOption(dto);
49
- return instance;
50
- }
46
+ public static fromJson(dto: BuilderOptionDto) {
47
+ const instance = new BuilderOption(dto);
48
+ return instance;
49
+ }
51
50
 
52
- toJson(): BuilderOptionDto {
53
- const dto: BuilderOptionDto = {
54
- id: this.id,
55
- value: this.value,
56
- label: this.label,
57
- };
58
- return dto;
59
- }
51
+ toJson(): BuilderOptionDto {
52
+ const dto: BuilderOptionDto = {
53
+ id: this.id,
54
+ value: this.value,
55
+ label: this.label,
56
+ };
57
+ return dto;
58
+ }
60
59
 
61
- clone(): BuilderOptionDto {
62
- const cloneId = BuilderObjectId.questionOptionId();
63
- const dto = this.toJson();
64
- const cloneDto: BuilderOptionDto = { ...dto, id: cloneId };
65
- return cloneDto;
66
- }
60
+ clone(): BuilderOptionDto {
61
+ const cloneId = BuilderObjectId.questionOptionId();
62
+ const dto = this.toJson();
63
+ const cloneDto: BuilderOptionDto = { ...dto, id: cloneId };
64
+ return cloneDto;
65
+ }
67
66
  }
@@ -135,6 +135,7 @@ export class BuilderSchema {
135
135
  input,
136
136
  );
137
137
  this._rules.push(rule);
138
+ return rule;
138
139
  }
139
140
  deleteRule(rule: BuilderRule) {
140
141
  this._rules = this._rules.filter((r) => r !== rule);
@@ -191,17 +192,16 @@ export class BuilderSchema {
191
192
  this.pages.forEach((page, index) => {
192
193
  const pageVariables = page.getQuestionVariables(prefix, index);
193
194
  qVars.push(...pageVariables);
194
- const pageId = page.prefix;
195
195
  const mainText = page.mainText.text;
196
196
  const jumpAction: JumpToPageAction = {
197
197
  kind: "jump-to-page",
198
- pageId: pageId,
198
+ pageId: page.id,
199
199
  pageNumber: index,
200
200
  mainText: page.mainText.text,
201
201
  };
202
202
  const excludePageAction: ExcludeByPageAction = {
203
203
  kind: "exclude-by-pageId",
204
- pageId,
204
+ pageId: page.id,
205
205
  pageNumber: index,
206
206
  mainText,
207
207
  };
@@ -2,6 +2,8 @@ import { BuilderRule, type BuilderRuleDto } from "./Builder-rule";
2
2
  import { RuleBuilderTestUtils as U } from "./RuleBuilder-test-utils";
3
3
  import { RuleInput } from "./RuleInput";
4
4
  import type { BuilderConditionGroupDto } from "./condition/Builder-condition-group";
5
+ import { BuilderConditionDto } from "./condition/Builder-condition";
6
+ import { Condition } from "@media-quest/engine";
5
7
 
6
8
  const { createBuilderVariables_A_H } = U;
7
9
  let questionVariables = createBuilderVariables_A_H();
@@ -9,23 +11,27 @@ const createDto = (): {
9
11
  ruleInput: RuleInput;
10
12
  builderRuleDto: BuilderRuleDto;
11
13
  } => {
12
- const v1 = U.createRuleVariable("v1", 2);
14
+ const v1 = U.createRuleVariable("v1", 1);
13
15
  const v2 = U.createRuleVariable("v2", 2);
14
- const v3 = U.createRuleVariable("v3", 2);
15
- const v4 = U.createRuleVariable("v4", 2);
16
- const vg1 = U.createRuleVariable("vg1", 2);
17
- const vg2 = U.createRuleVariable("vg2", 2);
18
- const vg3 = U.createRuleVariable("vg3", 2);
19
- const vg4 = U.createRuleVariable("vg4", 2);
16
+ const v3 = U.createRuleVariable("v3", 3);
17
+ const v4 = U.createRuleVariable("v4", 4);
18
+ const vg1 = U.createRuleVariable("vg1", 5);
19
+ const vg2 = U.createRuleVariable("vg2", 6);
20
+ const vg3 = U.createRuleVariable("vg3", 7);
21
+ const vg4 = U.createRuleVariable("vg4", 8);
20
22
  const variableList = [v1, v2, v3, v4, vg1, vg2, vg3, vg4];
21
23
  const tagAction1 = U.excludeByTagAction("tag1");
22
24
  const tagAction2 = U.excludeByTagAction("tag2");
23
25
  const tagAction3 = U.excludeByTagAction("tag3");
24
26
  const tagAction4 = U.excludeByTagAction("tag4");
25
- const pageAction1 = U.excludeByPageIdAction(v1.varId);
26
- const pageAction2 = U.excludeByPageIdAction(v2.varId);
27
- const pageAction3 = U.excludeByPageIdAction(v3.varId);
28
- const pageAction4 = U.excludeByPageIdAction(v4.varId);
27
+ const pageAction1 = U.excludeByPageIdAction(v1.varId, v1.pageNumber);
28
+ const pageAction2 = U.excludeByPageIdAction(v2.varId, v2.pageNumber);
29
+ const pageAction3 = U.excludeByPageIdAction(v3.varId, v3.pageNumber);
30
+ const pageAction4 = U.excludeByPageIdAction(v4.varId, v4.pageNumber);
31
+ const jumpToPageAction1 = U.jumpToPageAction(v1.varId, v1.pageNumber);
32
+ const jumpToPageAction2 = U.jumpToPageAction(v2.varId, v2.pageNumber);
33
+ const jumpToPageAction3 = U.jumpToPageAction(v3.varId, v3.pageNumber);
34
+ const jumpToPageAction4 = U.jumpToPageAction(v4.varId, v1.pageNumber);
29
35
 
30
36
  // const pageAction =
31
37
  // const excludeByTagList = [];
@@ -34,7 +40,7 @@ const createDto = (): {
34
40
  [],
35
41
  [pageAction1, pageAction2, pageAction3, pageAction4],
36
42
  [tagAction1, tagAction2, tagAction3, tagAction4],
37
- [],
43
+ [jumpToPageAction1, jumpToPageAction2, jumpToPageAction3, jumpToPageAction4],
38
44
  );
39
45
  const c1 = U.createConditionDto(v1);
40
46
  const c2 = U.createConditionDto(v2);
@@ -73,6 +79,7 @@ let dto: BuilderRuleDto = {
73
79
 
74
80
  const excludeByTagActionList = U.excludeByTagActionList();
75
81
  const pageActions = questionVariables.map((q) => U.excludeByPageIdAction(q.varId, q.pageNumber));
82
+
76
83
  let ruleInput = new RuleInput(questionVariables, [], [...pageActions], excludeByTagActionList, []);
77
84
 
78
85
  let rule: BuilderRule = BuilderRule.fromDto(dto, ruleInput);
@@ -204,4 +211,81 @@ describe("Builder Rule", () => {
204
211
  expect(ruleInput.excludeByTagActions.length).toStrictEqual(10);
205
212
  expect(ruleInput.excludeByTagActions.length).toStrictEqual(10);
206
213
  });
214
+
215
+ test("toEngineRuleWorks: ", () => {
216
+ const input = createDto().ruleInput;
217
+ const v1 = input.questionVars[0];
218
+ const v2 = input.questionVars[1];
219
+ const tag1 = input.excludeByTagActions[0];
220
+ const pageAction1 = input.excludeByPageIdActions[0];
221
+
222
+ const c1: BuilderConditionDto = {
223
+ kind: "condition",
224
+ name: "condition 1",
225
+ variableId: v1.varId,
226
+ operator: "equal",
227
+ value: v1.options[0].value,
228
+ };
229
+ const c2: BuilderConditionDto = {
230
+ name: "nested-condition",
231
+ kind: "condition",
232
+ value: v2.options[0].value,
233
+ operator: "equal",
234
+ variableId: v2.varId,
235
+ };
236
+ const conditionGroupANY: BuilderConditionGroupDto = {
237
+ kind: "condition-group",
238
+ conditions: [c1, c2],
239
+ name: "or-condition",
240
+ type: "any",
241
+ };
242
+
243
+ const conditionGroupALL: BuilderConditionGroupDto = {
244
+ kind: "condition-group",
245
+ conditions: [c2],
246
+ name: "condition group ALL - in testing.",
247
+ type: "all",
248
+ };
249
+
250
+ const dtoWithOneCondition: BuilderRuleDto = {
251
+ type: "all",
252
+ name: "dto-with-one-condition",
253
+ excludePages: [pageAction1.pageId],
254
+ excludeTags: [tag1.tag],
255
+ jumpToPage: v1.varId,
256
+ conditions: [c1, conditionGroupALL, conditionGroupANY],
257
+ };
258
+
259
+ const actionCount =
260
+ dtoWithOneCondition.excludeTags.length +
261
+ dtoWithOneCondition.excludePages.length +
262
+ (dtoWithOneCondition.jumpToPage ? 1 : 0);
263
+
264
+ const rule = BuilderRule.fromDto(dtoWithOneCondition, input);
265
+ const engineRule = rule.toEngineRule();
266
+
267
+ // console.log(rule);
268
+ expect(engineRule.all.length).toBe(3);
269
+ expect(engineRule.some.length).toBe(0);
270
+
271
+ const simple1 = engineRule.all.find(
272
+ (c) => c.kind === "numeric-condition" && c.referenceId === c1.variableId,
273
+ ) as Condition.Numeric;
274
+ const complex1 = engineRule.all.find(
275
+ (c) => c.kind === "complex-condition" && c.all.length === 1,
276
+ ) as Condition.Complex;
277
+
278
+ const complexChild1 = complex1.all[0] as Condition.Numeric;
279
+ expect(simple1).toBeTruthy();
280
+ expect(simple1.operator === "eq").toBeTruthy();
281
+ expect(simple1.value === c1.value).toBeTruthy();
282
+ expect(simple1.referenceLabel).toBe(v1.label);
283
+ expect(complex1).toBeTruthy();
284
+ expect(complexChild1).toBeTruthy();
285
+ expect(complexChild1.referenceId).toBe(c2.variableId);
286
+ expect(complexChild1.value).toBe(c2.value);
287
+ expect(complexChild1.referenceLabel).toBe(v2.label);
288
+ expect(complexChild1.operator === "eq").toBeTruthy();
289
+ expect(engineRule.onSuccess.length).toBe(actionCount);
290
+ });
207
291
  });
@@ -9,6 +9,7 @@ import { BuilderObject } from "../BuilderObject";
9
9
  import { TagActionManager } from "./tag-action-manager";
10
10
  import { PageActionManager } from "./page-action-manager";
11
11
  import { JumpToActionManager } from "./jump-to-action-manager";
12
+ import { Condition, PageQueCommand, PageQueRules } from "@media-quest/engine";
12
13
 
13
14
  export interface BuilderRuleDto {
14
15
  readonly type: ConditionGroupType;
@@ -25,7 +26,7 @@ export class BuilderRule extends BuilderObject<"builder-rule", BuilderRuleDto> {
25
26
  // public countNumber = 1;
26
27
  private readonly _conditions: Array<BuilderCondition | BuilderConditionGroup> = [];
27
28
 
28
- private _tagActionManager: TagActionManager;
29
+ private readonly _tagActionManager: TagActionManager;
29
30
  private _pageActionManager: PageActionManager;
30
31
  readonly jumpToActionManager: JumpToActionManager;
31
32
  public static readonly fromDto = (dto: BuilderRuleDto, input: RuleInput): BuilderRule => {
@@ -131,4 +132,68 @@ export class BuilderRule extends BuilderObject<"builder-rule", BuilderRuleDto> {
131
132
  };
132
133
  return dto;
133
134
  }
135
+ toEngineRule(modulePrefix: string): PageQueRules {
136
+ const conditions: Condition[] = [];
137
+ this._conditions.forEach((c) => {
138
+ if (c) {
139
+ if (c instanceof BuilderCondition) {
140
+ const simpleCondition = c.toEngineCondition(modulePrefix);
141
+ if (simpleCondition) {
142
+ conditions.push(simpleCondition);
143
+ }
144
+ }
145
+ if (c instanceof BuilderConditionGroup) {
146
+ const complexCondition = c.toEngineConditionComplex(modulePrefix);
147
+ if (complexCondition) conditions.push(complexCondition);
148
+ }
149
+ }
150
+ });
151
+ let all: Condition[] = [];
152
+ let some: Condition[] = [];
153
+
154
+ if (this.type === "all") {
155
+ all = [...conditions];
156
+ }
157
+ const pageQueCommands: Array<PageQueCommand> = [];
158
+ const maybeJumpToPage = this.jumpToActionManager.selected;
159
+ if (maybeJumpToPage) {
160
+ const jumpCommand: PageQueCommand = {
161
+ kind: "PAGE_QUE_JUMP_TO_PAGE_COMMAND",
162
+ target: "PAGE_QUE",
163
+ targetId: "PAGE_QUE",
164
+ payload: { pageId: maybeJumpToPage.data.pageId },
165
+ };
166
+ pageQueCommands.push(jumpCommand);
167
+ }
168
+
169
+ const excludePageByIdList = this._pageActionManager.getEngineAction().map((a) => a.pageId);
170
+ if (excludePageByIdList.length) {
171
+ const command: PageQueCommand = {
172
+ kind: "PAGE_QUE_EXCLUDE_BY_PAGE_ID_COMMAND",
173
+ target: "PAGE_QUE",
174
+ targetId: "PAGE_QUE",
175
+ payload: { pageIds: [...excludePageByIdList] },
176
+ };
177
+ pageQueCommands.push(command);
178
+ }
179
+ const excludeTags = this._tagActionManager.getEngineActions().map((tagA) => tagA.tag);
180
+ if (excludeTags.length) {
181
+ const excludeTagsCommand: PageQueCommand = {
182
+ kind: "PAGE_QUE_EXCLUDE_BY_TAG_COMMAND",
183
+ target: "PAGE_QUE",
184
+ targetId: "PAGE_QUE",
185
+ payload: { tagIds: [...excludeTags] },
186
+ };
187
+ pageQueCommands.push(excludeTagsCommand);
188
+ }
189
+
190
+ const rule: PageQueRules = {
191
+ description: this.name,
192
+ all,
193
+ some,
194
+ onFailure: [],
195
+ onSuccess: pageQueCommands,
196
+ };
197
+ return rule;
198
+ }
134
199
  }
@@ -4,7 +4,7 @@ import type { BuilderRuleDto } from "./Builder-rule";
4
4
  import type { BuilderConditionGroupDto } from "./condition/Builder-condition-group";
5
5
  import type { BuilderConditionDto } from "./condition/Builder-condition";
6
6
  import type { BuilderOperator } from "./condition/Builder-operator";
7
- import type { ExcludeByPageAction, ExcludeByTagAction } from "./RuleAction";
7
+ import type { ExcludeByPageAction, ExcludeByTagAction, JumpToPageAction } from "./RuleAction";
8
8
  import { ExcludeByPageIdSelectItem, ExcludeByTagSelectItem } from "./multi-select-item";
9
9
 
10
10
  export namespace RuleBuilderTestUtils {
@@ -24,7 +24,8 @@ export namespace RuleBuilderTestUtils {
24
24
  };
25
25
  return action;
26
26
  };
27
- export const excludeByPageIdAction = (pageId: string, pageNumber = 1) => {
27
+
28
+ export const excludeByPageIdAction = (pageId: string, pageNumber: number) => {
28
29
  const action: ExcludeByPageAction = {
29
30
  kind: "exclude-by-pageId",
30
31
  mainText: "",
@@ -33,6 +34,16 @@ export namespace RuleBuilderTestUtils {
33
34
  };
34
35
  return action;
35
36
  };
37
+ export const jumpToPageAction = (pageId: string, pageNumber: number) => {
38
+ const action: JumpToPageAction = {
39
+ kind: "jump-to-page",
40
+ mainText: "TEXT: " + pageId,
41
+ pageId,
42
+ pageNumber,
43
+ };
44
+ return action;
45
+ };
46
+
36
47
  export const excludeByTagActionList = () => {
37
48
  const list = [
38
49
  excludeByTagAction("tag1"),
@@ -1,38 +1,42 @@
1
1
  const BuilderVariableType = {
2
2
  numericWithOptions: true,
3
+ numeric: true,
3
4
  numericRange: true,
4
5
  text: true,
5
6
  date: true,
6
7
  dateRange: true,
7
8
  time: true,
8
9
  duration: true,
9
- boolean: true
10
+ boolean: true,
10
11
  } as const;
11
12
 
12
- type BuilderVariableType = keyof typeof BuilderVariableType;
13
+ export type BuilderVariableType = keyof typeof BuilderVariableType;
13
14
 
14
15
  export class BuilderVariableOption {
15
- constructor(readonly label: string, readonly value: number) {}
16
+ constructor(
17
+ readonly label: string,
18
+ readonly value: number,
19
+ ) {}
16
20
  }
17
21
 
18
22
  export class QuestionVariable {
19
- readonly kind: 'question-variable' = 'question-variable';
20
- readonly dataType: BuilderVariableType = 'numericWithOptions';
23
+ readonly kind: "question-variable" = "question-variable";
24
+ readonly dataType: BuilderVariableType = "numericWithOptions";
21
25
  constructor(
22
26
  readonly varId: string,
23
27
  readonly label: string,
24
28
  readonly options: ReadonlyArray<BuilderVariableOption>,
25
- readonly pageNumber: number
29
+ readonly pageNumber: number,
26
30
  ) {}
27
31
  }
28
32
 
29
33
  export class CustomVariable {
30
- readonly kind: 'configuration-variable' = 'configuration-variable';
31
- readonly dataType: BuilderVariableType = 'numericWithOptions';
34
+ readonly kind: "configuration-variable" = "configuration-variable";
35
+ readonly dataType: BuilderVariableType = "numericWithOptions";
32
36
  constructor(
33
37
  readonly varId: string,
34
38
  readonly label: string,
35
- readonly options: ReadonlyArray<BuilderVariableOption>
39
+ readonly options: ReadonlyArray<BuilderVariableOption>,
36
40
  ) {}
37
41
  }
38
42
 
@@ -1,18 +1,19 @@
1
1
  import { BuilderCondition, type BuilderConditionDto } from "./Builder-condition";
2
2
  import { BuilderObject } from "../../BuilderObject";
3
3
  import type { BuilderVariable } from "../RuleVariable";
4
+ import { Condition } from "@media-quest/engine";
4
5
 
5
6
  const ConditionGroupType = {
6
7
  all: true,
7
8
  any: true,
8
9
  count: true,
9
- range: true,
10
10
  };
11
11
 
12
12
  export type ConditionGroupType = keyof typeof ConditionGroupType;
13
13
  export interface BuilderConditionGroupDto {
14
14
  readonly kind: "condition-group";
15
15
  readonly name: string;
16
+ readonly count?: number;
16
17
  readonly type: ConditionGroupType;
17
18
  readonly conditions: ReadonlyArray<BuilderConditionDto>;
18
19
  }
@@ -80,6 +81,32 @@ export class BuilderConditionGroup extends BuilderObject<"builder-condition-grou
80
81
  kind: "condition-group",
81
82
  };
82
83
  }
84
+
85
+ toEngineConditionComplex(modulePrefix: string): 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(modulePrefix);
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
+ }
83
110
  get type(): ConditionGroupType {
84
111
  return this._type;
85
112
  }
@@ -166,4 +166,20 @@ describe("Builder Operator", () => {
166
166
  expect(c.value).toBe(false);
167
167
  expect(c.validate().isValid).toBe(false);
168
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
+ });
169
185
  });
@@ -2,6 +2,7 @@ import { BuilderObject } from "../../BuilderObject";
2
2
  import { BuilderOperator } from "./Builder-operator";
3
3
  import type { BuilderVariable, BuilderVariableOption } from "../RuleVariable";
4
4
  import { OperatorSelectItem, RuleOptionSelectItem, RuleVariableSelectItem } from "../SingleSelectItem";
5
+ import { Condition } from "@media-quest/engine";
5
6
  export interface BuilderConditionDto {
6
7
  readonly kind: "condition";
7
8
  readonly operator: BuilderOperator | "";
@@ -102,6 +103,27 @@ export class BuilderCondition extends BuilderObject<"builder-condition", Builder
102
103
  return { isValid: true };
103
104
  }
104
105
 
106
+ toEngineCondition(modulePrefix: string): Condition.Simple | false {
107
+ const val = this.value;
108
+ const op = this._operator;
109
+ const v = this._variable;
110
+ if (!val) return false;
111
+ if (!op) return false;
112
+ if (!v) return false;
113
+ if (op === "equal") {
114
+ const engineCondition: Condition.Simple = {
115
+ kind: "numeric-condition",
116
+ value: val.value,
117
+ valueLabel: val.label,
118
+ referenceId: modulePrefix + "_" + v.varId,
119
+ referenceLabel: v.label,
120
+ operator: "eq",
121
+ };
122
+ return engineCondition;
123
+ }
124
+ return false;
125
+ }
126
+
105
127
  private findVariableInUniverse(variableId: string): BuilderVariable | false {
106
128
  const v = this._variableList.find((v) => v.varId === variableId);
107
129
  return v ?? false;
@@ -16,14 +16,14 @@ const BuilderOperatorSymbols = {
16
16
  empty: true,
17
17
  notEmpty: true,
18
18
  startsWith: true,
19
- endsWith: true
19
+ endsWith: true,
20
20
  } as const;
21
21
 
22
22
  export type BuilderOperator = keyof typeof BuilderOperatorSymbols;
23
23
 
24
24
  export namespace BuilderOperator {
25
- export const is = (symbol: string): symbol is BuilderOperator => {
26
- if (typeof symbol !== 'string') {
25
+ export const is = (symbol?: string): symbol is BuilderOperator => {
26
+ if (typeof symbol !== "string") {
27
27
  return false;
28
28
  }
29
29
  return Object.keys(BuilderOperatorSymbols).includes(symbol);
@@ -2,32 +2,32 @@ import type { RuleInput } from "./RuleInput";
2
2
  import { JumpToPageSelectItem } from "./SingleSelectItem";
3
3
 
4
4
  export class JumpToActionManager {
5
- readonly options: ReadonlyArray<JumpToPageSelectItem>;
6
- private _selected: JumpToPageSelectItem | false;
7
- constructor(
8
- private readonly validOptions: RuleInput["_jumpActions"],
9
- private readonly initialSelection: string | false | undefined
10
- ) {
11
- this.options = validOptions.map(JumpToPageSelectItem.create);
12
- this._selected = this.findSelected(initialSelection);
5
+ readonly options: ReadonlyArray<JumpToPageSelectItem>;
6
+ private _selected: JumpToPageSelectItem | false;
7
+ constructor(
8
+ private readonly validOptions: RuleInput["_jumpActions"],
9
+ private readonly initialSelection: string | false | undefined,
10
+ ) {
11
+ this.options = validOptions.map(JumpToPageSelectItem.create);
12
+ this._selected = this.findSelected(initialSelection);
13
+ }
14
+ get selected(): JumpToPageSelectItem | false {
15
+ return this._selected;
16
+ }
17
+ set selected(selected: JumpToPageSelectItem | false) {
18
+ this._selected = this.findSelected(selected);
19
+ }
20
+ getSelectedPageId(): string | false {
21
+ return this._selected ? this._selected.data.pageId : false;
22
+ }
23
+ private findSelected(value: unknown): JumpToPageSelectItem | false {
24
+ if (!value) return false;
25
+ if (value instanceof JumpToPageSelectItem) {
26
+ return this.options.find((v) => v === value) || false;
13
27
  }
14
- get selected(): JumpToPageSelectItem | false {
15
- return this._selected;
16
- }
17
- set selected(selected: JumpToPageSelectItem | false) {
18
- this._selected = this.findSelected(selected);
19
- }
20
- getSelectedPageId(): string | false {
21
- return this._selected ? this._selected.data.pageId : false;
22
- }
23
- private findSelected(value: unknown): JumpToPageSelectItem | false {
24
- if (!value) return false;
25
- if (value instanceof JumpToPageSelectItem) {
26
- return this.options.find((v) => v === value) || false;
27
- }
28
- if (typeof value === "string") {
29
- return this.options.find((v) => v.data.pageId === value) || false;
30
- }
31
- return false;
28
+ if (typeof value === "string") {
29
+ return this.options.find((v) => v.data.pageId === value) || false;
32
30
  }
31
+ return false;
32
+ }
33
33
  }