@media-quest/builder 0.0.22 → 0.0.24
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 +1 -1
- package/src/Builder-option.ts +66 -66
- package/src/Builder-page.spec.ts +320 -320
- package/src/Builder-page.ts +257 -257
- package/src/Builder-question.spec.ts +68 -68
- package/src/Builder-question.ts +101 -101
- package/src/Builder-schema.spec.ts +51 -0
- package/src/Builder-schema.ts +47 -15
- package/src/Builder-text.spec.ts +24 -24
- package/src/Builder-text.ts +57 -57
- package/src/BuilderMainImageDto.ts +7 -7
- package/src/BuilderMainText.ts +81 -81
- package/src/BuilderMainVideoDto.ts +10 -10
- package/src/BuilderObject.ts +61 -61
- package/src/BuilderTag.ts +97 -97
- package/src/builder-compiler.ts +14 -0
- package/src/codebook.ts +72 -72
- package/src/media-files.ts +28 -28
- package/src/primitives/page-prefix.ts +58 -58
- package/src/primitives/prefix.spec.ts +5 -5
- package/src/primitives/schema-prefix.ts +52 -52
- package/src/primitives/varID.ts +11 -11
- package/src/public-api.ts +3 -1
- package/src/rulebuilder/Builder-rule.spec.ts +322 -322
- package/src/rulebuilder/Builder-rule.ts +190 -190
- package/src/rulebuilder/RuleAction.ts +106 -106
- package/src/rulebuilder/RuleBuilder-test-utils.ts +316 -316
- package/src/rulebuilder/RuleInput.ts +44 -44
- package/src/rulebuilder/RuleVariable.ts +49 -49
- package/src/rulebuilder/SingleSelectItem.ts +135 -135
- package/src/rulebuilder/condition/Builder-condition-group.spec.ts +47 -47
- package/src/rulebuilder/condition/Builder-condition-group.ts +118 -118
- package/src/rulebuilder/condition/Builder-condition.spec.ts +195 -195
- package/src/rulebuilder/condition/Builder-condition.ts +208 -208
- package/src/rulebuilder/condition/Builder-operator.spec.ts +9 -9
- package/src/rulebuilder/condition/Builder-operator.ts +31 -31
- package/src/rulebuilder/index.ts +22 -22
- package/src/rulebuilder/jump-to-action-manager.ts +33 -33
- package/src/rulebuilder/multi-select-item.ts +73 -73
- package/src/rulebuilder/page-action-manager.ts +31 -31
- package/src/rulebuilder/rule2/Rule2.ts +211 -211
- package/src/rulebuilder/tag-action-manager.spec.ts +44 -44
- package/src/rulebuilder/tag-action-manager.ts +28 -28
- package/src/schema-config.ts +25 -25
- package/src/theme/AbstractThemeCompiler.ts +7 -7
- package/src/theme/IDefaultTheme.ts +226 -226
- package/src/theme/css-theme.ts +7 -7
- package/src/theme/default-theme-compiler.ts +358 -358
- package/src/theme/icon-urls.ts +29 -29
- package/src/theme/theme-utils.ts +57 -57
- package/src/theme/theme1.spec.ts +52 -52
- package/src/variable/mq-variable.spec.ts +146 -0
- package/src/{mq-variable.ts → variable/mq-variable.ts} +8 -1
- package/src/variable/sum-score.ts +138 -0
- package/tsconfig.json +15 -15
- package/tsconfig.tsbuildinfo +1 -1
package/src/BuilderMainText.ts
CHANGED
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
import { BuilderObject } from "./BuilderObject";
|
|
2
|
-
import { AudioFile } from "./media-files";
|
|
3
|
-
|
|
4
|
-
export interface BuilderMainTextDto {
|
|
5
|
-
text: string;
|
|
6
|
-
audioFile: AudioFile | false;
|
|
7
|
-
autoplay: boolean;
|
|
8
|
-
autoplayDelay: number;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export class BuilderMainText extends BuilderObject<"builder-main-text", BuilderMainTextDto> {
|
|
12
|
-
readonly objectType: "builder-main-text" = "builder-main-text";
|
|
13
|
-
autoplay = false;
|
|
14
|
-
private _audioFile: AudioFile | false = false;
|
|
15
|
-
autoplayDelay = 0;
|
|
16
|
-
|
|
17
|
-
text = "";
|
|
18
|
-
|
|
19
|
-
private constructor(dto: BuilderMainTextDto) {
|
|
20
|
-
super(dto);
|
|
21
|
-
this._audioFile = dto.audioFile ?? false;
|
|
22
|
-
this.autoplay = dto.autoplay ?? false;
|
|
23
|
-
this.autoplayDelay = dto.autoplayDelay ?? 0;
|
|
24
|
-
this.text = dto.text ?? "";
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
get autoplayDelayInSeconds() {
|
|
28
|
-
const delay = this.autoplayDelay;
|
|
29
|
-
const s = delay / 1000;
|
|
30
|
-
const formatted = s.toFixed(1);
|
|
31
|
-
return formatted;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
get durationTag() {
|
|
35
|
-
if (!this.audioFile) return "";
|
|
36
|
-
// console.log(this.audioFile.duration);
|
|
37
|
-
const dur = this.audioFile.duration.toFixed(1);
|
|
38
|
-
return "dur " + dur + " s";
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
static fromJson(dto: BuilderMainTextDto): BuilderMainText {
|
|
42
|
-
const mainText = new BuilderMainText(dto);
|
|
43
|
-
return mainText;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
static create = () => {
|
|
47
|
-
const dto: BuilderMainTextDto = {
|
|
48
|
-
autoplay: false,
|
|
49
|
-
autoplayDelay: 0,
|
|
50
|
-
audioFile: false,
|
|
51
|
-
text: "",
|
|
52
|
-
};
|
|
53
|
-
return new BuilderMainText(dto);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
clone(): BuilderMainTextDto {
|
|
57
|
-
const dto = this.toJson();
|
|
58
|
-
const clone = JSON.parse(JSON.stringify(dto));
|
|
59
|
-
return clone;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
toJson(): BuilderMainTextDto {
|
|
63
|
-
const dto: BuilderMainTextDto = {
|
|
64
|
-
text: this.text,
|
|
65
|
-
audioFile: this.audioFile,
|
|
66
|
-
autoplay: this.autoplay,
|
|
67
|
-
autoplayDelay: this.autoplayDelay,
|
|
68
|
-
};
|
|
69
|
-
return dto;
|
|
70
|
-
}
|
|
71
|
-
get audioFile(): AudioFile | false {
|
|
72
|
-
return this._audioFile;
|
|
73
|
-
}
|
|
74
|
-
set audioFile(audioFile: AudioFile | false) {
|
|
75
|
-
if (audioFile === false) {
|
|
76
|
-
this.autoplayDelay = 0;
|
|
77
|
-
this.autoplay = false;
|
|
78
|
-
}
|
|
79
|
-
this._audioFile = audioFile;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
1
|
+
import { BuilderObject } from "./BuilderObject";
|
|
2
|
+
import { AudioFile } from "./media-files";
|
|
3
|
+
|
|
4
|
+
export interface BuilderMainTextDto {
|
|
5
|
+
text: string;
|
|
6
|
+
audioFile: AudioFile | false;
|
|
7
|
+
autoplay: boolean;
|
|
8
|
+
autoplayDelay: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class BuilderMainText extends BuilderObject<"builder-main-text", BuilderMainTextDto> {
|
|
12
|
+
readonly objectType: "builder-main-text" = "builder-main-text";
|
|
13
|
+
autoplay = false;
|
|
14
|
+
private _audioFile: AudioFile | false = false;
|
|
15
|
+
autoplayDelay = 0;
|
|
16
|
+
|
|
17
|
+
text = "";
|
|
18
|
+
|
|
19
|
+
private constructor(dto: BuilderMainTextDto) {
|
|
20
|
+
super(dto);
|
|
21
|
+
this._audioFile = dto.audioFile ?? false;
|
|
22
|
+
this.autoplay = dto.autoplay ?? false;
|
|
23
|
+
this.autoplayDelay = dto.autoplayDelay ?? 0;
|
|
24
|
+
this.text = dto.text ?? "";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get autoplayDelayInSeconds() {
|
|
28
|
+
const delay = this.autoplayDelay;
|
|
29
|
+
const s = delay / 1000;
|
|
30
|
+
const formatted = s.toFixed(1);
|
|
31
|
+
return formatted;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get durationTag() {
|
|
35
|
+
if (!this.audioFile) return "";
|
|
36
|
+
// console.log(this.audioFile.duration);
|
|
37
|
+
const dur = this.audioFile.duration.toFixed(1);
|
|
38
|
+
return "dur " + dur + " s";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static fromJson(dto: BuilderMainTextDto): BuilderMainText {
|
|
42
|
+
const mainText = new BuilderMainText(dto);
|
|
43
|
+
return mainText;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static create = () => {
|
|
47
|
+
const dto: BuilderMainTextDto = {
|
|
48
|
+
autoplay: false,
|
|
49
|
+
autoplayDelay: 0,
|
|
50
|
+
audioFile: false,
|
|
51
|
+
text: "",
|
|
52
|
+
};
|
|
53
|
+
return new BuilderMainText(dto);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
clone(): BuilderMainTextDto {
|
|
57
|
+
const dto = this.toJson();
|
|
58
|
+
const clone = JSON.parse(JSON.stringify(dto));
|
|
59
|
+
return clone;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
toJson(): BuilderMainTextDto {
|
|
63
|
+
const dto: BuilderMainTextDto = {
|
|
64
|
+
text: this.text,
|
|
65
|
+
audioFile: this.audioFile,
|
|
66
|
+
autoplay: this.autoplay,
|
|
67
|
+
autoplayDelay: this.autoplayDelay,
|
|
68
|
+
};
|
|
69
|
+
return dto;
|
|
70
|
+
}
|
|
71
|
+
get audioFile(): AudioFile | false {
|
|
72
|
+
return this._audioFile;
|
|
73
|
+
}
|
|
74
|
+
set audioFile(audioFile: AudioFile | false) {
|
|
75
|
+
if (audioFile === false) {
|
|
76
|
+
this.autoplayDelay = 0;
|
|
77
|
+
this.autoplay = false;
|
|
78
|
+
}
|
|
79
|
+
this._audioFile = audioFile;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { VideoFile } from "./media-files";
|
|
2
|
-
|
|
3
|
-
export interface BuilderMainVideoDto {
|
|
4
|
-
readonly kind: "main-video";
|
|
5
|
-
readonly file: VideoFile;
|
|
6
|
-
mode: "autoplay" | "required" | "optional" | "gif-mode";
|
|
7
|
-
preDelay: number;
|
|
8
|
-
volume: number;
|
|
9
|
-
controls: boolean;
|
|
10
|
-
}
|
|
1
|
+
import { VideoFile } from "./media-files";
|
|
2
|
+
|
|
3
|
+
export interface BuilderMainVideoDto {
|
|
4
|
+
readonly kind: "main-video";
|
|
5
|
+
readonly file: VideoFile;
|
|
6
|
+
mode: "autoplay" | "required" | "optional" | "gif-mode";
|
|
7
|
+
preDelay: number;
|
|
8
|
+
volume: number;
|
|
9
|
+
controls: boolean;
|
|
10
|
+
}
|
package/src/BuilderObject.ts
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
import { DUtil } from "@media-quest/engine";
|
|
2
|
-
|
|
3
|
-
const U = DUtil;
|
|
4
|
-
/**
|
|
5
|
-
* Builder objects are complex objects that are embedded inside
|
|
6
|
-
* a Builder-schema, and needs to be serialized to json. Often these objects
|
|
7
|
-
* are used in collections, and that is why most of them need an id.
|
|
8
|
-
*/
|
|
9
|
-
type BuilderObjectType =
|
|
10
|
-
| "builder-page"
|
|
11
|
-
| "builder-question-option"
|
|
12
|
-
| "builder-question"
|
|
13
|
-
| "builder-main-text"
|
|
14
|
-
| "builder-text"
|
|
15
|
-
| "builder-rule"
|
|
16
|
-
| "builder-tag"
|
|
17
|
-
| "builder-condition"
|
|
18
|
-
| "builder-variable"
|
|
19
|
-
| "builder-condition-group";
|
|
20
|
-
|
|
21
|
-
export namespace BuilderObjectId {
|
|
22
|
-
export type QuestionOptionID = string & { __OPTION__ID__: true };
|
|
23
|
-
export type QuestionID = string & { __QUESTION__ID__: true };
|
|
24
|
-
export type TextID = string & { __TEXT__ID__: true };
|
|
25
|
-
export type MainTextID = string & { __MAIN__TEXT__ID__: true };
|
|
26
|
-
export type TagId = string & { __TAG__ID__: true };
|
|
27
|
-
export const createTagId = (): TagId => {
|
|
28
|
-
return createId("builder-tag") as TagId;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export const mainTextId = (): MainTextID => {
|
|
32
|
-
return createId("builder-main-text") as MainTextID;
|
|
33
|
-
};
|
|
34
|
-
export const textId = (): TextID => {
|
|
35
|
-
return createId("builder-text") as TextID;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export const questionOptionId = (): QuestionOptionID => {
|
|
39
|
-
return createId("builder-question-option") as QuestionOptionID;
|
|
40
|
-
};
|
|
41
|
-
export const questionId = (): QuestionID => {
|
|
42
|
-
return createId("builder-question") as QuestionID;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const createId = (type: BuilderObjectType): string => {
|
|
46
|
-
const id = U.randomString(24);
|
|
47
|
-
return type + "-" + id;
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export abstract class BuilderObject<T extends BuilderObjectType, Dto extends {}> {
|
|
52
|
-
// abstract readonly id: string;
|
|
53
|
-
abstract readonly objectType: T;
|
|
54
|
-
abstract toJson(): Dto;
|
|
55
|
-
abstract clone(): Dto;
|
|
56
|
-
protected readonly originalDto: Dto;
|
|
57
|
-
protected constructor(dto: Dto) {
|
|
58
|
-
this.originalDto = dto;
|
|
59
|
-
// this.objectId = dto.objectId;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
1
|
+
import { DUtil } from "@media-quest/engine";
|
|
2
|
+
|
|
3
|
+
const U = DUtil;
|
|
4
|
+
/**
|
|
5
|
+
* Builder objects are complex objects that are embedded inside
|
|
6
|
+
* a Builder-schema, and needs to be serialized to json. Often these objects
|
|
7
|
+
* are used in collections, and that is why most of them need an id.
|
|
8
|
+
*/
|
|
9
|
+
type BuilderObjectType =
|
|
10
|
+
| "builder-page"
|
|
11
|
+
| "builder-question-option"
|
|
12
|
+
| "builder-question"
|
|
13
|
+
| "builder-main-text"
|
|
14
|
+
| "builder-text"
|
|
15
|
+
| "builder-rule"
|
|
16
|
+
| "builder-tag"
|
|
17
|
+
| "builder-condition"
|
|
18
|
+
| "builder-variable"
|
|
19
|
+
| "builder-condition-group";
|
|
20
|
+
|
|
21
|
+
export namespace BuilderObjectId {
|
|
22
|
+
export type QuestionOptionID = string & { __OPTION__ID__: true };
|
|
23
|
+
export type QuestionID = string & { __QUESTION__ID__: true };
|
|
24
|
+
export type TextID = string & { __TEXT__ID__: true };
|
|
25
|
+
export type MainTextID = string & { __MAIN__TEXT__ID__: true };
|
|
26
|
+
export type TagId = string & { __TAG__ID__: true };
|
|
27
|
+
export const createTagId = (): TagId => {
|
|
28
|
+
return createId("builder-tag") as TagId;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const mainTextId = (): MainTextID => {
|
|
32
|
+
return createId("builder-main-text") as MainTextID;
|
|
33
|
+
};
|
|
34
|
+
export const textId = (): TextID => {
|
|
35
|
+
return createId("builder-text") as TextID;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const questionOptionId = (): QuestionOptionID => {
|
|
39
|
+
return createId("builder-question-option") as QuestionOptionID;
|
|
40
|
+
};
|
|
41
|
+
export const questionId = (): QuestionID => {
|
|
42
|
+
return createId("builder-question") as QuestionID;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const createId = (type: BuilderObjectType): string => {
|
|
46
|
+
const id = U.randomString(24);
|
|
47
|
+
return type + "-" + id;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export abstract class BuilderObject<T extends BuilderObjectType, Dto extends {}> {
|
|
52
|
+
// abstract readonly id: string;
|
|
53
|
+
abstract readonly objectType: T;
|
|
54
|
+
abstract toJson(): Dto;
|
|
55
|
+
abstract clone(): Dto;
|
|
56
|
+
protected readonly originalDto: Dto;
|
|
57
|
+
protected constructor(dto: Dto) {
|
|
58
|
+
this.originalDto = dto;
|
|
59
|
+
// this.objectId = dto.objectId;
|
|
60
|
+
}
|
|
61
|
+
}
|
package/src/BuilderTag.ts
CHANGED
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
import { BuilderObjectId, BuilderObject } from './BuilderObject';
|
|
2
|
-
|
|
3
|
-
export interface BuilderTagDto {
|
|
4
|
-
readonly id: BuilderObjectId.TagId;
|
|
5
|
-
readonly tag: string;
|
|
6
|
-
readonly description: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export class BuilderTag extends BuilderObject<'builder-tag', BuilderTagDto> {
|
|
10
|
-
readonly objectType: 'builder-tag' = 'builder-tag';
|
|
11
|
-
readonly id: BuilderObjectId.TagId;
|
|
12
|
-
tagText = '';
|
|
13
|
-
tagDescription = '';
|
|
14
|
-
public static readonly MAX_LENGTH = 20;
|
|
15
|
-
public static readonly MIN_LENGTH = 1;
|
|
16
|
-
|
|
17
|
-
public static readonly create = (tag: string, description: string = '') => {
|
|
18
|
-
const id = BuilderObjectId.createTagId();
|
|
19
|
-
const dto: BuilderTagDto = {
|
|
20
|
-
id,
|
|
21
|
-
tag,
|
|
22
|
-
description
|
|
23
|
-
};
|
|
24
|
-
return new BuilderTag(dto);
|
|
25
|
-
};
|
|
26
|
-
public static readonly fromDto = (dto: BuilderTagDto) => {
|
|
27
|
-
return new BuilderTag(dto);
|
|
28
|
-
};
|
|
29
|
-
protected constructor(dto: BuilderTagDto) {
|
|
30
|
-
const id = dto.id ?? BuilderObjectId.createTagId();
|
|
31
|
-
const withId = { ...dto, id };
|
|
32
|
-
super(withId);
|
|
33
|
-
this.id = id;
|
|
34
|
-
this.tagText = dto.tag ?? '';
|
|
35
|
-
this.tagDescription = dto.description ?? '';
|
|
36
|
-
}
|
|
37
|
-
clone(): BuilderTagDto {
|
|
38
|
-
return this.toJson();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
toJson(): BuilderTagDto {
|
|
42
|
-
return { tag: this.tagText, description: this.tagDescription, id: this.id };
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export class TagCollection implements Iterable<BuilderTag> {
|
|
47
|
-
private readonly _tags = new Set<BuilderTag>();
|
|
48
|
-
public static readonly create = () => {
|
|
49
|
-
return new TagCollection([]);
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
[Symbol.iterator]() {
|
|
53
|
-
const list = [...this._tags];
|
|
54
|
-
return list[Symbol.iterator]();
|
|
55
|
-
}
|
|
56
|
-
private constructor(initialTags: ReadonlyArray<BuilderTag>) {
|
|
57
|
-
initialTags.forEach(tag => {
|
|
58
|
-
this._tags.add(tag);
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
init(tags: ReadonlyArray<BuilderTagDto>) {
|
|
63
|
-
const dtoList: ReadonlyArray<BuilderTagDto> = Array.isArray(tags)
|
|
64
|
-
? tags
|
|
65
|
-
: [];
|
|
66
|
-
const all = dtoList.map(BuilderTag.fromDto);
|
|
67
|
-
all.forEach(tag => {
|
|
68
|
-
this._tags.add(tag);
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
add(tag: BuilderTag) {
|
|
73
|
-
this._tags.add(tag);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Delete this tag from collection;
|
|
78
|
-
* @param tag
|
|
79
|
-
*/
|
|
80
|
-
delete(tag: BuilderTag) {
|
|
81
|
-
this._tags.delete(tag);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
toJson(): ReadonlyArray<BuilderTagDto> {
|
|
85
|
-
const list = [...this._tags];
|
|
86
|
-
const dtoList = list.map(t => t.toJson());
|
|
87
|
-
return dtoList;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
deleteAll(tags: Iterable<BuilderTag>) {
|
|
91
|
-
const l = tags[Symbol.iterator]();
|
|
92
|
-
const asList = [...tags];
|
|
93
|
-
asList.forEach(t => {
|
|
94
|
-
this.delete(t);
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
}
|
|
1
|
+
import { BuilderObjectId, BuilderObject } from './BuilderObject';
|
|
2
|
+
|
|
3
|
+
export interface BuilderTagDto {
|
|
4
|
+
readonly id: BuilderObjectId.TagId;
|
|
5
|
+
readonly tag: string;
|
|
6
|
+
readonly description: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class BuilderTag extends BuilderObject<'builder-tag', BuilderTagDto> {
|
|
10
|
+
readonly objectType: 'builder-tag' = 'builder-tag';
|
|
11
|
+
readonly id: BuilderObjectId.TagId;
|
|
12
|
+
tagText = '';
|
|
13
|
+
tagDescription = '';
|
|
14
|
+
public static readonly MAX_LENGTH = 20;
|
|
15
|
+
public static readonly MIN_LENGTH = 1;
|
|
16
|
+
|
|
17
|
+
public static readonly create = (tag: string, description: string = '') => {
|
|
18
|
+
const id = BuilderObjectId.createTagId();
|
|
19
|
+
const dto: BuilderTagDto = {
|
|
20
|
+
id,
|
|
21
|
+
tag,
|
|
22
|
+
description
|
|
23
|
+
};
|
|
24
|
+
return new BuilderTag(dto);
|
|
25
|
+
};
|
|
26
|
+
public static readonly fromDto = (dto: BuilderTagDto) => {
|
|
27
|
+
return new BuilderTag(dto);
|
|
28
|
+
};
|
|
29
|
+
protected constructor(dto: BuilderTagDto) {
|
|
30
|
+
const id = dto.id ?? BuilderObjectId.createTagId();
|
|
31
|
+
const withId = { ...dto, id };
|
|
32
|
+
super(withId);
|
|
33
|
+
this.id = id;
|
|
34
|
+
this.tagText = dto.tag ?? '';
|
|
35
|
+
this.tagDescription = dto.description ?? '';
|
|
36
|
+
}
|
|
37
|
+
clone(): BuilderTagDto {
|
|
38
|
+
return this.toJson();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
toJson(): BuilderTagDto {
|
|
42
|
+
return { tag: this.tagText, description: this.tagDescription, id: this.id };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class TagCollection implements Iterable<BuilderTag> {
|
|
47
|
+
private readonly _tags = new Set<BuilderTag>();
|
|
48
|
+
public static readonly create = () => {
|
|
49
|
+
return new TagCollection([]);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
[Symbol.iterator]() {
|
|
53
|
+
const list = [...this._tags];
|
|
54
|
+
return list[Symbol.iterator]();
|
|
55
|
+
}
|
|
56
|
+
private constructor(initialTags: ReadonlyArray<BuilderTag>) {
|
|
57
|
+
initialTags.forEach(tag => {
|
|
58
|
+
this._tags.add(tag);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
init(tags: ReadonlyArray<BuilderTagDto>) {
|
|
63
|
+
const dtoList: ReadonlyArray<BuilderTagDto> = Array.isArray(tags)
|
|
64
|
+
? tags
|
|
65
|
+
: [];
|
|
66
|
+
const all = dtoList.map(BuilderTag.fromDto);
|
|
67
|
+
all.forEach(tag => {
|
|
68
|
+
this._tags.add(tag);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
add(tag: BuilderTag) {
|
|
73
|
+
this._tags.add(tag);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Delete this tag from collection;
|
|
78
|
+
* @param tag
|
|
79
|
+
*/
|
|
80
|
+
delete(tag: BuilderTag) {
|
|
81
|
+
this._tags.delete(tag);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
toJson(): ReadonlyArray<BuilderTagDto> {
|
|
85
|
+
const list = [...this._tags];
|
|
86
|
+
const dtoList = list.map(t => t.toJson());
|
|
87
|
+
return dtoList;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
deleteAll(tags: Iterable<BuilderTag>) {
|
|
91
|
+
const l = tags[Symbol.iterator]();
|
|
92
|
+
const asList = [...tags];
|
|
93
|
+
asList.forEach(t => {
|
|
94
|
+
this.delete(t);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SchemaDto } from "@media-quest/engine";
|
|
2
|
+
import { Codebook } from "./codebook";
|
|
3
|
+
import { SchemaConfig } from "./schema-config";
|
|
4
|
+
|
|
5
|
+
export interface CompilerOutput {
|
|
6
|
+
schema: SchemaDto;
|
|
7
|
+
codebook: Codebook;
|
|
8
|
+
schemaConfig: SchemaConfig;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface CompilerOption {
|
|
12
|
+
blockAutoplayQuestion: boolean;
|
|
13
|
+
blockAutoplayVideo: boolean;
|
|
14
|
+
}
|
package/src/codebook.ts
CHANGED
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
import { BuilderPageDto } from "./Builder-page";
|
|
2
|
-
import { BuilderSchemaDto } from "./Builder-schema";
|
|
3
|
-
import { PageVariable, PredefinedVariable } from "./mq-variable";
|
|
4
|
-
|
|
5
|
-
export interface Codebook {
|
|
6
|
-
readonly predefinedVariables: ReadonlyArray<PredefinedVariable>;
|
|
7
|
-
readonly pageVariables: ReadonlyArray<PageVariable>;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const fromPage = (
|
|
11
|
-
page: BuilderPageDto,
|
|
12
|
-
pagePosition: number,
|
|
13
|
-
modulePrefix: string,
|
|
14
|
-
): PageVariable[] => {
|
|
15
|
-
const variables: PageVariable[] = [];
|
|
16
|
-
|
|
17
|
-
if (page._type !== "question") {
|
|
18
|
-
// TODO Implement form field variables
|
|
19
|
-
return [];
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const options: PageVariable["options"] = page.defaultQuestion.options.map((o) => {
|
|
23
|
-
return { value: o.value, label: o.label };
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const variable: PageVariable = {
|
|
27
|
-
kind: "numeric-variable",
|
|
28
|
-
label: page.mainText.text,
|
|
29
|
-
options,
|
|
30
|
-
modulePrefix,
|
|
31
|
-
origin: "question",
|
|
32
|
-
pageId: page.id,
|
|
33
|
-
pagePosition,
|
|
34
|
-
pagePrefix: page.prefix,
|
|
35
|
-
varId: modulePrefix + "_" + page.prefix,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
variables.push(variable);
|
|
39
|
-
|
|
40
|
-
return variables;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Converts a list of pages into a list of question-variables
|
|
45
|
-
* @param pages
|
|
46
|
-
* @param modulePrefix
|
|
47
|
-
*/
|
|
48
|
-
const getPageVariablesFromPages = (
|
|
49
|
-
pages: BuilderPageDto[],
|
|
50
|
-
modulePrefix: string,
|
|
51
|
-
): PageVariable[] => {
|
|
52
|
-
const variables: PageVariable[] = [];
|
|
53
|
-
pages.forEach((page, index) => {
|
|
54
|
-
const pageVariables = fromPage(page, index, modulePrefix);
|
|
55
|
-
variables.push(...pageVariables);
|
|
56
|
-
});
|
|
57
|
-
return variables;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const fromSchema = (schema: BuilderSchemaDto): Codebook => {
|
|
61
|
-
const modulePrefix = schema.prefix;
|
|
62
|
-
const pageVariables = getPageVariablesFromPages(schema.pages, modulePrefix);
|
|
63
|
-
const vs = schema.predefinedVariables;
|
|
64
|
-
const predefinedVariables: PredefinedVariable[] = vs ? [...vs] : [];
|
|
65
|
-
return { pageVariables, predefinedVariables };
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export const _CodeBook = {
|
|
69
|
-
fromSchema,
|
|
70
|
-
} as const;
|
|
71
|
-
|
|
72
|
-
export const CodeBook = Object.freeze(_CodeBook);
|
|
1
|
+
import { BuilderPageDto } from "./Builder-page";
|
|
2
|
+
import { BuilderSchemaDto } from "./Builder-schema";
|
|
3
|
+
import { PageVariable, PredefinedVariable } from "./variable/mq-variable";
|
|
4
|
+
|
|
5
|
+
export interface Codebook {
|
|
6
|
+
readonly predefinedVariables: ReadonlyArray<PredefinedVariable>;
|
|
7
|
+
readonly pageVariables: ReadonlyArray<PageVariable>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const fromPage = (
|
|
11
|
+
page: BuilderPageDto,
|
|
12
|
+
pagePosition: number,
|
|
13
|
+
modulePrefix: string,
|
|
14
|
+
): PageVariable[] => {
|
|
15
|
+
const variables: PageVariable[] = [];
|
|
16
|
+
|
|
17
|
+
if (page._type !== "question") {
|
|
18
|
+
// TODO Implement form field variables
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const options: PageVariable["options"] = page.defaultQuestion.options.map((o) => {
|
|
23
|
+
return { value: o.value, label: o.label };
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const variable: PageVariable = {
|
|
27
|
+
kind: "numeric-variable",
|
|
28
|
+
label: page.mainText.text,
|
|
29
|
+
options,
|
|
30
|
+
modulePrefix,
|
|
31
|
+
origin: "question",
|
|
32
|
+
pageId: page.id,
|
|
33
|
+
pagePosition,
|
|
34
|
+
pagePrefix: page.prefix,
|
|
35
|
+
varId: modulePrefix + "_" + page.prefix,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
variables.push(variable);
|
|
39
|
+
|
|
40
|
+
return variables;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Converts a list of pages into a list of question-variables
|
|
45
|
+
* @param pages
|
|
46
|
+
* @param modulePrefix
|
|
47
|
+
*/
|
|
48
|
+
const getPageVariablesFromPages = (
|
|
49
|
+
pages: BuilderPageDto[],
|
|
50
|
+
modulePrefix: string,
|
|
51
|
+
): PageVariable[] => {
|
|
52
|
+
const variables: PageVariable[] = [];
|
|
53
|
+
pages.forEach((page, index) => {
|
|
54
|
+
const pageVariables = fromPage(page, index, modulePrefix);
|
|
55
|
+
variables.push(...pageVariables);
|
|
56
|
+
});
|
|
57
|
+
return variables;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const fromSchema = (schema: BuilderSchemaDto): Codebook => {
|
|
61
|
+
const modulePrefix = schema.prefix;
|
|
62
|
+
const pageVariables = getPageVariablesFromPages(schema.pages, modulePrefix);
|
|
63
|
+
const vs = schema.predefinedVariables;
|
|
64
|
+
const predefinedVariables: PredefinedVariable[] = vs ? [...vs] : [];
|
|
65
|
+
return { pageVariables, predefinedVariables };
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const _CodeBook = {
|
|
69
|
+
fromSchema,
|
|
70
|
+
} as const;
|
|
71
|
+
|
|
72
|
+
export const CodeBook = Object.freeze(_CodeBook);
|