@case-framework/survey-core 0.2.0 → 0.4.0
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/build/editor.d.mts +52 -12
- package/build/editor.d.mts.map +1 -1
- package/build/editor.mjs +223 -48
- package/build/editor.mjs.map +1 -1
- package/build/index.d.mts +80 -50
- package/build/index.d.mts.map +1 -1
- package/build/index.mjs +235 -169
- package/build/index.mjs.map +1 -1
- package/build/package.json +8 -8
- package/build/{survey-D3sMutUV.d.mts → survey-DShEOjyz.d.mts} +389 -82
- package/build/survey-DShEOjyz.d.mts.map +1 -0
- package/build/{survey-DQmpzihl.mjs → survey-yXdl8xkf.mjs} +479 -48
- package/build/survey-yXdl8xkf.mjs.map +1 -0
- package/package.json +8 -8
- package/build/survey-D3sMutUV.d.mts.map +0 -1
- package/build/survey-DQmpzihl.mjs.map +0 -1
package/build/index.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { $ as generateId, A as DurationUnits, B as ConstExpression, C as ReservedSurveyItemTypes, D as deserializeSurveyItemPrefill, E as SurveyItemPrefillTargetType, F as TemplateDefTypes, G as FunctionExpression, H as ContextVariableType, I as deserializeTemplateValue, J as ReferenceUsageType, K as FunctionExpressionNames, L as deserializeTemplateValues, M as ValueType, N as assertResponseValue, O as prefillTargetsEqual, P as isResponseValue, Q as generateCodingKey, R as serializeTemplateValue, S as SurveyItemKey, T as SurveyItemPrefillApplyMode, U as Expression, V as ContextVariableExpression, W as ExpressionType, X as ValueReferenceMethod, Y as ValueReference, Z as createSeededRandom, _ as toItemTypeDefinitionRegistry, a as getContentPlainText, b as builtInItemCoreRegistry, c as hasRenderableRichTextContent, d as SurveyTranslations, et as shuffleArray, f as validateLocale, g as createItemTypeDefinitionRegistry, h as createItemCore, i as getAssetUsagesFromContent, j as NumberPrecision, k as serializeSurveyItemPrefill, l as isContentEmpty, m as createFullRegistry, n as ContentType, nt as structuredCloneMethod, o as getPlainTextFromRichTextContent, p as CURRENT_SURVEY_SCHEMA, q as ResponseVariableExpression, r as createRichTextContent, s as hasRenderableRichTextBlock, t as Survey, tt as shuffleIndices, u as SurveyItemTranslations, v as GroupItemCore, w as SurveyItemCore, x as isBuiltInItemType, y as PageBreakItemCore, z as serializeTemplateValues } from "./survey-yXdl8xkf.mjs";
|
|
2
2
|
import { format } from "date-fns";
|
|
3
3
|
import { enUS } from "date-fns/locale";
|
|
4
|
-
|
|
5
4
|
//#region src/to_mirgrate/data_types/legacy-types.ts
|
|
6
5
|
const isLegacyItemGroupComponent = (item) => {
|
|
7
6
|
const items = item.items;
|
|
@@ -11,7 +10,6 @@ const isLegacySurveyGroupItem = (item) => {
|
|
|
11
10
|
const items = item.items;
|
|
12
11
|
return items !== void 0 && items.length > 0;
|
|
13
12
|
};
|
|
14
|
-
|
|
15
13
|
//#endregion
|
|
16
14
|
//#region src/survey/responses/item-response.ts
|
|
17
15
|
/**
|
|
@@ -36,6 +34,9 @@ var SurveyItemResponse = class SurveyItemResponse {
|
|
|
36
34
|
};
|
|
37
35
|
}
|
|
38
36
|
static deserialize(json) {
|
|
37
|
+
if (!json || typeof json !== "object" || Array.isArray(json)) throw new Error("Invalid survey item response payload");
|
|
38
|
+
if (typeof json.itemId !== "string" || json.itemId.trim().length === 0) throw new Error("Survey item response is missing a valid itemId");
|
|
39
|
+
if (typeof json.itemType !== "string" || json.itemType.trim().length === 0) throw new Error("Survey item response is missing a valid itemType");
|
|
39
40
|
const newResponse = new SurveyItemResponse({
|
|
40
41
|
itemId: json.itemId,
|
|
41
42
|
itemType: json.itemType
|
|
@@ -57,16 +58,26 @@ var ResponseItem = class ResponseItem {
|
|
|
57
58
|
else this._slots.delete(slotId);
|
|
58
59
|
}
|
|
59
60
|
serialize() {
|
|
60
|
-
|
|
61
|
+
if (this._slots.size === 0) return;
|
|
62
|
+
return { slots: Object.fromEntries(this._slots.entries()) };
|
|
63
|
+
}
|
|
64
|
+
isEmpty() {
|
|
65
|
+
return this._slots.size === 0;
|
|
61
66
|
}
|
|
62
67
|
clone() {
|
|
63
68
|
return new ResponseItem(Array.from(this._slots.entries()));
|
|
64
69
|
}
|
|
65
70
|
static deserialize(json) {
|
|
66
|
-
|
|
71
|
+
if (!json || typeof json !== "object" || Array.isArray(json)) throw new Error("Invalid response item payload");
|
|
72
|
+
const { slots } = json;
|
|
73
|
+
if (!slots || typeof slots !== "object" || Array.isArray(slots)) throw new Error("Invalid response slots payload");
|
|
74
|
+
return new ResponseItem(Object.entries(slots).map(([slotId, slotResponse]) => {
|
|
75
|
+
if (slotId.trim().length === 0) throw new Error("Response slot id cannot be empty");
|
|
76
|
+
assertResponseValue(slotResponse, `response.slots.${slotId}`);
|
|
77
|
+
return [slotId, slotResponse];
|
|
78
|
+
}));
|
|
67
79
|
}
|
|
68
80
|
};
|
|
69
|
-
|
|
70
81
|
//#endregion
|
|
71
82
|
//#region src/survey/responses/response-meta.ts
|
|
72
83
|
const SurveyEventTypes = {
|
|
@@ -75,9 +86,9 @@ const SurveyEventTypes = {
|
|
|
75
86
|
responeChanged: "responeChanged",
|
|
76
87
|
languageChanged: "languageChanged"
|
|
77
88
|
};
|
|
78
|
-
|
|
79
89
|
//#endregion
|
|
80
90
|
//#region src/survey/responses/survey-response.ts
|
|
91
|
+
const SURVEY_RESPONSE_SCHEMA_VERSION = 1;
|
|
81
92
|
/**
|
|
82
93
|
* SurveyResponse to store the responses of a survey.
|
|
83
94
|
*/
|
|
@@ -98,58 +109,49 @@ var SurveyResponse = class SurveyResponse {
|
|
|
98
109
|
this.events = [];
|
|
99
110
|
}
|
|
100
111
|
serialize() {
|
|
112
|
+
const items = Object.fromEntries(Array.from(this.responses.entries()).flatMap(([itemId, response]) => {
|
|
113
|
+
const serialized = response.serialize();
|
|
114
|
+
if (!serialized.response && !serialized.meta) return [];
|
|
115
|
+
return [[itemId, serialized]];
|
|
116
|
+
}));
|
|
101
117
|
return {
|
|
118
|
+
schemaVersion: 1,
|
|
102
119
|
key: this.key,
|
|
103
120
|
participantId: this.participantId,
|
|
104
121
|
submittedAt: this.submittedAt,
|
|
105
122
|
versionId: this.versionId,
|
|
106
|
-
|
|
123
|
+
items,
|
|
107
124
|
events: this.events,
|
|
108
125
|
context: this.context
|
|
109
126
|
};
|
|
110
127
|
}
|
|
111
128
|
static deserialize(json) {
|
|
129
|
+
if (!json || typeof json !== "object" || Array.isArray(json)) throw new Error("Invalid survey response payload");
|
|
130
|
+
if (json.schemaVersion !== 1) throw new Error(`Unsupported survey response schema version: ${String(json.schemaVersion)}`);
|
|
131
|
+
if (typeof json.key !== "string" || json.key.trim().length === 0) throw new Error("Survey response is missing a valid key");
|
|
132
|
+
if (typeof json.versionId !== "string" || json.versionId.trim().length === 0) throw new Error("Survey response is missing a valid versionId");
|
|
133
|
+
if (!json.items || typeof json.items !== "object" || Array.isArray(json.items)) throw new Error("Survey response is missing a valid items object");
|
|
112
134
|
const response = new SurveyResponse(json.key, json.versionId);
|
|
113
135
|
response.participantId = json.participantId;
|
|
114
136
|
response.submittedAt = json.submittedAt;
|
|
115
|
-
response.responses = new Map(json.
|
|
137
|
+
response.responses = new Map(Object.entries(json.items).map(([itemId, itemResponse]) => {
|
|
138
|
+
const deserialized = SurveyItemResponse.deserialize(itemResponse);
|
|
139
|
+
if (deserialized.itemId !== itemId) throw new Error(`Survey response item key mismatch for '${itemId}'`);
|
|
140
|
+
return [itemId, deserialized];
|
|
141
|
+
}));
|
|
116
142
|
response.events = json.events ?? [];
|
|
117
143
|
response.versionId = json.versionId;
|
|
118
144
|
response.key = json.key;
|
|
119
|
-
|
|
145
|
+
if (json.context) {
|
|
146
|
+
if (typeof json.context !== "object" || Array.isArray(json.context)) throw new Error("Survey response context must be an object");
|
|
147
|
+
response.context = Object.fromEntries(Object.entries(json.context).map(([contextKey, value]) => {
|
|
148
|
+
assertResponseValue(value, `context.${contextKey}`);
|
|
149
|
+
return [contextKey, value];
|
|
150
|
+
}));
|
|
151
|
+
}
|
|
120
152
|
return response;
|
|
121
153
|
}
|
|
122
154
|
};
|
|
123
|
-
|
|
124
|
-
//#endregion
|
|
125
|
-
//#region src/survey/responses/value-types.ts
|
|
126
|
-
const ValueType = {
|
|
127
|
-
string: "string",
|
|
128
|
-
duration: "duration",
|
|
129
|
-
reference: "reference",
|
|
130
|
-
number: "number",
|
|
131
|
-
boolean: "boolean",
|
|
132
|
-
date: "date",
|
|
133
|
-
stringArray: "string[]",
|
|
134
|
-
durationArray: "duration[]",
|
|
135
|
-
referenceArray: "reference[]",
|
|
136
|
-
numberArray: "number[]",
|
|
137
|
-
dateArray: "date[]"
|
|
138
|
-
};
|
|
139
|
-
const DurationUnits = {
|
|
140
|
-
seconds: "seconds",
|
|
141
|
-
minutes: "minutes",
|
|
142
|
-
hours: "hours",
|
|
143
|
-
days: "days",
|
|
144
|
-
weeks: "weeks",
|
|
145
|
-
months: "months",
|
|
146
|
-
years: "years"
|
|
147
|
-
};
|
|
148
|
-
const NumberPrecision = {
|
|
149
|
-
int: "int",
|
|
150
|
-
float: "float"
|
|
151
|
-
};
|
|
152
|
-
|
|
153
155
|
//#endregion
|
|
154
156
|
//#region src/survey/responses/utils.ts
|
|
155
157
|
const initValueForType = (returnType) => {
|
|
@@ -203,7 +205,6 @@ const initValueForType = (returnType) => {
|
|
|
203
205
|
default: throw new Error("Invalid return type: " + returnType);
|
|
204
206
|
}
|
|
205
207
|
};
|
|
206
|
-
|
|
207
208
|
//#endregion
|
|
208
209
|
//#region src/expressions/expression-evaluator.ts
|
|
209
210
|
var ExpressionEvaluator = class {
|
|
@@ -230,8 +231,8 @@ var ExpressionEvaluator = class {
|
|
|
230
231
|
evaluateResponseVariable(expression) {
|
|
231
232
|
const varRef = expression.responseVariableRef;
|
|
232
233
|
switch (varRef.name) {
|
|
233
|
-
case
|
|
234
|
-
case
|
|
234
|
+
case "get": return this.context?.responses[varRef.itemId]?.response?.get(varRef.slotId);
|
|
235
|
+
case "isDefined": return {
|
|
235
236
|
type: ValueType.boolean,
|
|
236
237
|
value: this.context?.responses[varRef.itemId]?.response?.get(varRef.slotId) !== void 0
|
|
237
238
|
};
|
|
@@ -240,20 +241,20 @@ var ExpressionEvaluator = class {
|
|
|
240
241
|
}
|
|
241
242
|
evaluateFunction(expression) {
|
|
242
243
|
switch (expression.functionName) {
|
|
243
|
-
case
|
|
244
|
-
case
|
|
245
|
-
case
|
|
246
|
-
case
|
|
247
|
-
case
|
|
248
|
-
case
|
|
249
|
-
case
|
|
250
|
-
case
|
|
251
|
-
case
|
|
252
|
-
case
|
|
253
|
-
case
|
|
254
|
-
case
|
|
255
|
-
case
|
|
256
|
-
case
|
|
244
|
+
case "and": return this.evaluateAnd(expression);
|
|
245
|
+
case "or": return this.evaluateOr(expression);
|
|
246
|
+
case "not": return this.evaluateNot(expression);
|
|
247
|
+
case "str_eq": return this.evaluateStrEq(expression);
|
|
248
|
+
case "eq": return this.evaluateEq(expression);
|
|
249
|
+
case "gt": return this.evaluateGt(expression);
|
|
250
|
+
case "gte": return this.evaluateGte(expression);
|
|
251
|
+
case "lt": return this.evaluateLt(expression);
|
|
252
|
+
case "lte": return this.evaluateLte(expression);
|
|
253
|
+
case "in_range": return this.evaluateInRange(expression);
|
|
254
|
+
case "sum": return this.evaluateSum(expression);
|
|
255
|
+
case "min": return this.evaluateMin(expression);
|
|
256
|
+
case "max": return this.evaluateMax(expression);
|
|
257
|
+
case "list_contains": return this.evaluateListContains(expression);
|
|
257
258
|
default: throw new Error(`Unsupported function: ${expression.functionName}`);
|
|
258
259
|
}
|
|
259
260
|
}
|
|
@@ -533,7 +534,16 @@ var ExpressionEvaluator = class {
|
|
|
533
534
|
});
|
|
534
535
|
}
|
|
535
536
|
};
|
|
536
|
-
|
|
537
|
+
//#endregion
|
|
538
|
+
//#region src/expressions/item-expression-registry.ts
|
|
539
|
+
function getItemExpressionDefinition(definitions, expressionId) {
|
|
540
|
+
return definitions?.find((definition) => definition.id === expressionId);
|
|
541
|
+
}
|
|
542
|
+
function buildItemExpression(item, definitions, expressionId, params) {
|
|
543
|
+
const definition = getItemExpressionDefinition(definitions, expressionId);
|
|
544
|
+
if (!definition) throw new Error(`Unknown item expression: ${expressionId}`);
|
|
545
|
+
return definition.buildExpression(item, params);
|
|
546
|
+
}
|
|
537
547
|
//#endregion
|
|
538
548
|
//#region src/expressions/editors/expression-editor.ts
|
|
539
549
|
var ExpressionEditor = class {
|
|
@@ -809,7 +819,7 @@ var AndExpressionEditor = class extends GroupExpressionEditor {
|
|
|
809
819
|
super(args, editorConfig);
|
|
810
820
|
}
|
|
811
821
|
getExpression() {
|
|
812
|
-
return new FunctionExpression(
|
|
822
|
+
return new FunctionExpression("and", this.args.map((arg) => arg.getExpression()), this._editorConfig);
|
|
813
823
|
}
|
|
814
824
|
};
|
|
815
825
|
var OrExpressionEditor = class extends GroupExpressionEditor {
|
|
@@ -819,7 +829,7 @@ var OrExpressionEditor = class extends GroupExpressionEditor {
|
|
|
819
829
|
super(args, editorConfig);
|
|
820
830
|
}
|
|
821
831
|
getExpression() {
|
|
822
|
-
return new FunctionExpression(
|
|
832
|
+
return new FunctionExpression("or", this.args.map((arg) => arg.getExpression()), this._editorConfig);
|
|
823
833
|
}
|
|
824
834
|
};
|
|
825
835
|
var StrListContainsExpressionEditor = class extends ExpressionEditor {
|
|
@@ -847,7 +857,7 @@ var StrListContainsExpressionEditor = class extends ExpressionEditor {
|
|
|
847
857
|
this._item = item;
|
|
848
858
|
}
|
|
849
859
|
getExpression() {
|
|
850
|
-
return new FunctionExpression(
|
|
860
|
+
return new FunctionExpression("list_contains", [this._list?.getExpression(), this._item?.getExpression()], this._editorConfig);
|
|
851
861
|
}
|
|
852
862
|
};
|
|
853
863
|
var StrEqExpressionEditor = class extends ExpressionEditor {
|
|
@@ -873,7 +883,7 @@ var StrEqExpressionEditor = class extends ExpressionEditor {
|
|
|
873
883
|
this._b = b;
|
|
874
884
|
}
|
|
875
885
|
getExpression() {
|
|
876
|
-
return new FunctionExpression(
|
|
886
|
+
return new FunctionExpression("str_eq", [this._a?.getExpression(), this._b?.getExpression()], this._editorConfig);
|
|
877
887
|
}
|
|
878
888
|
};
|
|
879
889
|
var EqExpressionEditor = class extends ExpressionEditor {
|
|
@@ -899,7 +909,7 @@ var EqExpressionEditor = class extends ExpressionEditor {
|
|
|
899
909
|
this._b = b;
|
|
900
910
|
}
|
|
901
911
|
getExpression() {
|
|
902
|
-
return new FunctionExpression(
|
|
912
|
+
return new FunctionExpression("eq", [this._a?.getExpression(), this._b?.getExpression()], this._editorConfig);
|
|
903
913
|
}
|
|
904
914
|
};
|
|
905
915
|
var GtExpressionEditor = class extends ExpressionEditor {
|
|
@@ -925,7 +935,7 @@ var GtExpressionEditor = class extends ExpressionEditor {
|
|
|
925
935
|
this._b = b;
|
|
926
936
|
}
|
|
927
937
|
getExpression() {
|
|
928
|
-
return new FunctionExpression(
|
|
938
|
+
return new FunctionExpression("gt", [this._a?.getExpression(), this._b?.getExpression()], this._editorConfig);
|
|
929
939
|
}
|
|
930
940
|
};
|
|
931
941
|
var GteExpressionEditor = class extends ExpressionEditor {
|
|
@@ -951,7 +961,7 @@ var GteExpressionEditor = class extends ExpressionEditor {
|
|
|
951
961
|
this._b = b;
|
|
952
962
|
}
|
|
953
963
|
getExpression() {
|
|
954
|
-
return new FunctionExpression(
|
|
964
|
+
return new FunctionExpression("gte", [this._a?.getExpression(), this._b?.getExpression()], this._editorConfig);
|
|
955
965
|
}
|
|
956
966
|
};
|
|
957
967
|
var LtExpressionEditor = class extends ExpressionEditor {
|
|
@@ -977,7 +987,7 @@ var LtExpressionEditor = class extends ExpressionEditor {
|
|
|
977
987
|
this._b = b;
|
|
978
988
|
}
|
|
979
989
|
getExpression() {
|
|
980
|
-
return new FunctionExpression(
|
|
990
|
+
return new FunctionExpression("lt", [this._a?.getExpression(), this._b?.getExpression()], this._editorConfig);
|
|
981
991
|
}
|
|
982
992
|
};
|
|
983
993
|
var LteExpressionEditor = class extends ExpressionEditor {
|
|
@@ -1003,7 +1013,7 @@ var LteExpressionEditor = class extends ExpressionEditor {
|
|
|
1003
1013
|
this._a = a;
|
|
1004
1014
|
}
|
|
1005
1015
|
getExpression() {
|
|
1006
|
-
return new FunctionExpression(
|
|
1016
|
+
return new FunctionExpression("lte", [this._a?.getExpression(), this._b?.getExpression()], this._editorConfig);
|
|
1007
1017
|
}
|
|
1008
1018
|
};
|
|
1009
1019
|
var InRangeExpressionEditor = class extends ExpressionEditor {
|
|
@@ -1021,7 +1031,7 @@ var InRangeExpressionEditor = class extends ExpressionEditor {
|
|
|
1021
1031
|
this._editorConfig = editorConfig;
|
|
1022
1032
|
}
|
|
1023
1033
|
getExpression() {
|
|
1024
|
-
return new FunctionExpression(
|
|
1034
|
+
return new FunctionExpression("in_range", [
|
|
1025
1035
|
this.value?.getExpression(),
|
|
1026
1036
|
this.min?.getExpression(),
|
|
1027
1037
|
this.max?.getExpression(),
|
|
@@ -1035,7 +1045,7 @@ var SumExpressionEditor = class extends GroupExpressionEditor {
|
|
|
1035
1045
|
super(args, editorConfig);
|
|
1036
1046
|
}
|
|
1037
1047
|
getExpression() {
|
|
1038
|
-
return new FunctionExpression(
|
|
1048
|
+
return new FunctionExpression("sum", this.args.map((arg) => arg.getExpression()), this._editorConfig);
|
|
1039
1049
|
}
|
|
1040
1050
|
};
|
|
1041
1051
|
var MinExpressionEditor = class extends GroupExpressionEditor {
|
|
@@ -1044,7 +1054,7 @@ var MinExpressionEditor = class extends GroupExpressionEditor {
|
|
|
1044
1054
|
super(args, editorConfig);
|
|
1045
1055
|
}
|
|
1046
1056
|
getExpression() {
|
|
1047
|
-
return new FunctionExpression(
|
|
1057
|
+
return new FunctionExpression("min", this.args.map((arg) => arg.getExpression()), this._editorConfig);
|
|
1048
1058
|
}
|
|
1049
1059
|
};
|
|
1050
1060
|
var MaxExpressionEditor = class extends GroupExpressionEditor {
|
|
@@ -1053,10 +1063,9 @@ var MaxExpressionEditor = class extends GroupExpressionEditor {
|
|
|
1053
1063
|
super(args, editorConfig);
|
|
1054
1064
|
}
|
|
1055
1065
|
getExpression() {
|
|
1056
|
-
return new FunctionExpression(
|
|
1066
|
+
return new FunctionExpression("max", this.args.map((arg) => arg.getExpression()), this._editorConfig);
|
|
1057
1067
|
}
|
|
1058
1068
|
};
|
|
1059
|
-
|
|
1060
1069
|
//#endregion
|
|
1061
1070
|
//#region src/expressions/editors/expression-editor-generators.ts
|
|
1062
1071
|
const const_string_array = (...values) => {
|
|
@@ -1161,20 +1170,6 @@ const min = (...args) => {
|
|
|
1161
1170
|
const max = (...args) => {
|
|
1162
1171
|
return new MaxExpressionEditor(args);
|
|
1163
1172
|
};
|
|
1164
|
-
|
|
1165
|
-
//#endregion
|
|
1166
|
-
//#region src/survey/utils/content.ts
|
|
1167
|
-
let ContentType = /* @__PURE__ */ function(ContentType) {
|
|
1168
|
-
ContentType["CQM"] = "CQM";
|
|
1169
|
-
ContentType["md"] = "md";
|
|
1170
|
-
return ContentType;
|
|
1171
|
-
}({});
|
|
1172
|
-
let AttributionType = /* @__PURE__ */ function(AttributionType) {
|
|
1173
|
-
AttributionType["style"] = "style";
|
|
1174
|
-
AttributionType["template"] = "template";
|
|
1175
|
-
return AttributionType;
|
|
1176
|
-
}({});
|
|
1177
|
-
|
|
1178
1173
|
//#endregion
|
|
1179
1174
|
//#region src/engine/engine.ts
|
|
1180
1175
|
var SurveyEngineCore = class {
|
|
@@ -1182,14 +1177,17 @@ var SurveyEngineCore = class {
|
|
|
1182
1177
|
renderedSurveyTree;
|
|
1183
1178
|
context;
|
|
1184
1179
|
locale;
|
|
1180
|
+
sessionSeedValue;
|
|
1185
1181
|
responses;
|
|
1186
1182
|
prefills;
|
|
1187
1183
|
_events;
|
|
1188
1184
|
_openedAt;
|
|
1189
1185
|
dateLocales;
|
|
1186
|
+
prefillEnvironment;
|
|
1190
1187
|
cache;
|
|
1191
|
-
constructor(survey, context, prefills, dateLocales) {
|
|
1188
|
+
constructor(survey, context, prefills, dateLocales, options) {
|
|
1192
1189
|
this._openedAt = this._getTimestamp();
|
|
1190
|
+
this.sessionSeedValue = generateId();
|
|
1193
1191
|
this.surveyDef = survey;
|
|
1194
1192
|
this.context = context ? context : { locale: "en" };
|
|
1195
1193
|
this.locale = this.context.locale;
|
|
@@ -1197,12 +1195,14 @@ var SurveyEngineCore = class {
|
|
|
1197
1195
|
acc[p.itemId] = SurveyItemResponse.deserialize(p);
|
|
1198
1196
|
return acc;
|
|
1199
1197
|
}, {}) : void 0;
|
|
1198
|
+
this.prefillEnvironment = options?.prefillEnvironment;
|
|
1200
1199
|
this.dateLocales = dateLocales || [{
|
|
1201
1200
|
code: "en",
|
|
1202
1201
|
locale: enUS
|
|
1203
1202
|
}];
|
|
1204
1203
|
this.responses = this.initResponseObject(this.surveyDef.surveyItems);
|
|
1205
1204
|
this.initCache();
|
|
1205
|
+
this.applyConfiguredPrefills();
|
|
1206
1206
|
this.evalExpressions();
|
|
1207
1207
|
if (!survey.rootItem) throw new Error("constructor: root item not found");
|
|
1208
1208
|
this.renderedSurveyTree = this.renderGroup(survey.rootItem);
|
|
@@ -1253,6 +1253,9 @@ var SurveyEngineCore = class {
|
|
|
1253
1253
|
get openedAt() {
|
|
1254
1254
|
return this._openedAt;
|
|
1255
1255
|
}
|
|
1256
|
+
get sessionSeed() {
|
|
1257
|
+
return this.sessionSeedValue;
|
|
1258
|
+
}
|
|
1256
1259
|
get survey() {
|
|
1257
1260
|
return this.surveyDef;
|
|
1258
1261
|
}
|
|
@@ -1262,7 +1265,7 @@ var SurveyEngineCore = class {
|
|
|
1262
1265
|
if (!size) size = "large";
|
|
1263
1266
|
let currentPage = [];
|
|
1264
1267
|
renderedSurvey.forEach((item) => {
|
|
1265
|
-
if (item.type ===
|
|
1268
|
+
if (item.type === "page-break") {
|
|
1266
1269
|
if (currentPage.length > 0) {
|
|
1267
1270
|
pages.push([...currentPage]);
|
|
1268
1271
|
currentPage = [];
|
|
@@ -1302,12 +1305,17 @@ var SurveyEngineCore = class {
|
|
|
1302
1305
|
return this._events.slice();
|
|
1303
1306
|
}
|
|
1304
1307
|
getResponses() {
|
|
1305
|
-
const
|
|
1308
|
+
const renderedPositions = /* @__PURE__ */ new Map();
|
|
1309
|
+
flattenTree(this.renderedSurveyTree).filter((item) => item.type !== "page-break").forEach((item, index) => {
|
|
1310
|
+
if (this.responses[item.id]) renderedPositions.set(item.id, index);
|
|
1311
|
+
});
|
|
1306
1312
|
const responses = [];
|
|
1307
|
-
|
|
1308
|
-
|
|
1313
|
+
this.surveyDef.surveyItems.forEach((item, itemId) => {
|
|
1314
|
+
if (!item.isInteractive()) return;
|
|
1315
|
+
const response = this.getResponseItem(itemId);
|
|
1309
1316
|
if (!response) return;
|
|
1310
|
-
|
|
1317
|
+
const position = renderedPositions.get(itemId);
|
|
1318
|
+
response.meta = position === void 0 ? void 0 : { position };
|
|
1311
1319
|
responses.push(response);
|
|
1312
1320
|
});
|
|
1313
1321
|
return responses;
|
|
@@ -1410,6 +1418,67 @@ var SurveyEngineCore = class {
|
|
|
1410
1418
|
});
|
|
1411
1419
|
return respGroup;
|
|
1412
1420
|
}
|
|
1421
|
+
applyConfiguredPrefills() {
|
|
1422
|
+
const evalEngine = new ExpressionEvaluator({
|
|
1423
|
+
responses: this.responses,
|
|
1424
|
+
surveyContext: this.context
|
|
1425
|
+
});
|
|
1426
|
+
const maxPasses = Math.max(this.surveyDef.surveyItems.size, 1);
|
|
1427
|
+
for (let pass = 0; pass < maxPasses; pass++) {
|
|
1428
|
+
this.evalTemplateValues(evalEngine);
|
|
1429
|
+
let changedInPass = false;
|
|
1430
|
+
this.surveyDef.surveyItems.forEach((item) => {
|
|
1431
|
+
if (!item.isInteractive()) return;
|
|
1432
|
+
changedInPass = this.applyConfiguredPrefillsForItem(item, evalEngine) || changedInPass;
|
|
1433
|
+
});
|
|
1434
|
+
if (!changedInPass) break;
|
|
1435
|
+
}
|
|
1436
|
+
this.evalTemplateValues(evalEngine);
|
|
1437
|
+
}
|
|
1438
|
+
applyConfiguredPrefillsForItem(item, evalEngine) {
|
|
1439
|
+
const responseItem = this.responses[item.id];
|
|
1440
|
+
if (!responseItem) return false;
|
|
1441
|
+
let changed = false;
|
|
1442
|
+
for (const prefill of item.prefills ?? []) {
|
|
1443
|
+
const targetSlot = item.resolvePrefillTarget(prefill.target);
|
|
1444
|
+
if (!targetSlot) continue;
|
|
1445
|
+
if ((prefill.apply ?? SurveyItemPrefillApplyMode.ifEmpty) === SurveyItemPrefillApplyMode.ifEmpty && responseItem.response?.get(targetSlot.slotId) !== void 0) continue;
|
|
1446
|
+
if (!this.shouldApplyConfiguredPrefill(prefill, evalEngine)) continue;
|
|
1447
|
+
const resolvedValue = this.resolveConfiguredPrefillValue(prefill, targetSlot, evalEngine);
|
|
1448
|
+
if (!resolvedValue) continue;
|
|
1449
|
+
const normalizedValue = item.normalizePrefillValue(prefill, targetSlot, resolvedValue);
|
|
1450
|
+
if (!normalizedValue) continue;
|
|
1451
|
+
const nextResponse = responseItem.response?.clone() ?? new ResponseItem();
|
|
1452
|
+
nextResponse.setSlotValue(targetSlot.slotId, normalizedValue);
|
|
1453
|
+
responseItem.response = nextResponse.isEmpty() ? void 0 : nextResponse;
|
|
1454
|
+
changed = true;
|
|
1455
|
+
}
|
|
1456
|
+
return changed;
|
|
1457
|
+
}
|
|
1458
|
+
shouldApplyConfiguredPrefill(prefill, evalEngine) {
|
|
1459
|
+
if (!prefill.when) return true;
|
|
1460
|
+
const resolved = evalEngine.eval(prefill.when);
|
|
1461
|
+
return resolved?.type === ValueType.boolean && resolved.value === true;
|
|
1462
|
+
}
|
|
1463
|
+
resolveConfiguredPrefillValue(prefill, _target, evalEngine) {
|
|
1464
|
+
switch (prefill.source.type) {
|
|
1465
|
+
case "static": return prefill.source.value;
|
|
1466
|
+
case "expression": return evalEngine.eval(prefill.source.expression);
|
|
1467
|
+
case "templateValue": return this.getTemplateValue(prefill.source.key);
|
|
1468
|
+
case "previousResponse": {
|
|
1469
|
+
if (!this.prefillEnvironment?.getPreviousResponse) return;
|
|
1470
|
+
const refTarget = prefill.source.ref.target ?? prefill.target;
|
|
1471
|
+
const resolved = this.prefillEnvironment.getPreviousResponse({
|
|
1472
|
+
surveyKey: prefill.source.ref.surveyKey,
|
|
1473
|
+
itemId: prefill.source.ref.itemId,
|
|
1474
|
+
target: refTarget
|
|
1475
|
+
});
|
|
1476
|
+
if (!resolved) return;
|
|
1477
|
+
return resolved;
|
|
1478
|
+
}
|
|
1479
|
+
default: return;
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1413
1482
|
shouldRender(itemId, componentId) {
|
|
1414
1483
|
const displayConditionResult = this.getDisplayConditionValue(itemId, componentId);
|
|
1415
1484
|
if (displayConditionResult !== void 0) return displayConditionResult;
|
|
@@ -1424,7 +1493,7 @@ var SurveyEngineCore = class {
|
|
|
1424
1493
|
console.warn("sequentialRender: item not found: " + itemId);
|
|
1425
1494
|
continue;
|
|
1426
1495
|
}
|
|
1427
|
-
if (itemDef.type ===
|
|
1496
|
+
if (itemDef.type === "group") {
|
|
1428
1497
|
newItems.push(this.renderGroup(itemDef));
|
|
1429
1498
|
continue;
|
|
1430
1499
|
}
|
|
@@ -1435,7 +1504,7 @@ var SurveyEngineCore = class {
|
|
|
1435
1504
|
}
|
|
1436
1505
|
return {
|
|
1437
1506
|
id: groupDef.id,
|
|
1438
|
-
type:
|
|
1507
|
+
type: "group",
|
|
1439
1508
|
items: newItems
|
|
1440
1509
|
};
|
|
1441
1510
|
}
|
|
@@ -1452,7 +1521,7 @@ var SurveyEngineCore = class {
|
|
|
1452
1521
|
console.warn("randomizedItemRender: item not found: " + itemId);
|
|
1453
1522
|
continue;
|
|
1454
1523
|
}
|
|
1455
|
-
if (itemDef.type ===
|
|
1524
|
+
if (itemDef.type === "group") {
|
|
1456
1525
|
newItems.push(this.renderGroup(itemDef, parent));
|
|
1457
1526
|
continue;
|
|
1458
1527
|
}
|
|
@@ -1463,14 +1532,14 @@ var SurveyEngineCore = class {
|
|
|
1463
1532
|
}
|
|
1464
1533
|
return {
|
|
1465
1534
|
id: groupDef.id,
|
|
1466
|
-
type:
|
|
1535
|
+
type: "group",
|
|
1467
1536
|
items: newItems
|
|
1468
1537
|
};
|
|
1469
1538
|
}
|
|
1470
1539
|
renderGroup(groupDef, parent) {
|
|
1471
1540
|
if (!parent) parent = {
|
|
1472
1541
|
id: groupDef.id,
|
|
1473
|
-
type:
|
|
1542
|
+
type: "group",
|
|
1474
1543
|
items: []
|
|
1475
1544
|
};
|
|
1476
1545
|
if (groupDef.config.shuffleItems) return this.randomizedItemRender(groupDef, parent);
|
|
@@ -1502,6 +1571,7 @@ var SurveyEngineCore = class {
|
|
|
1502
1571
|
evalTemplateValues(evalEngine) {
|
|
1503
1572
|
Object.keys(this.cache.templateValues).forEach((templateValueKey) => {
|
|
1504
1573
|
const templateValue = this.cache.templateValues[templateValueKey];
|
|
1574
|
+
this.cache.templateValues[templateValueKey].value = void 0;
|
|
1505
1575
|
if (!templateValue.templateDef?.expression) {
|
|
1506
1576
|
console.warn("evalTemplateValues: template value expression not found: " + templateValueKey);
|
|
1507
1577
|
return;
|
|
@@ -1512,7 +1582,7 @@ var SurveyEngineCore = class {
|
|
|
1512
1582
|
return;
|
|
1513
1583
|
}
|
|
1514
1584
|
switch (templateValue.templateDef.type) {
|
|
1515
|
-
case
|
|
1585
|
+
case "date2string":
|
|
1516
1586
|
if (evaluatedValue.type !== ValueType.date) {
|
|
1517
1587
|
console.warn("evalTemplateValues: template value expression returned non-date value: " + templateValueKey);
|
|
1518
1588
|
return;
|
|
@@ -1578,12 +1648,11 @@ var SurveyEngineCore = class {
|
|
|
1578
1648
|
const flattenTree = (itemTree) => {
|
|
1579
1649
|
const flatTree = new Array();
|
|
1580
1650
|
itemTree.items?.forEach((item) => {
|
|
1581
|
-
if (item.type ===
|
|
1651
|
+
if (item.type === "group") flatTree.push(...flattenTree(item));
|
|
1582
1652
|
else flatTree.push({ ...item });
|
|
1583
1653
|
});
|
|
1584
1654
|
return flatTree;
|
|
1585
1655
|
};
|
|
1586
|
-
|
|
1587
1656
|
//#endregion
|
|
1588
1657
|
//#region src/response-exporter/types.ts
|
|
1589
1658
|
/** Meta column keys in fixed order (common attributes first). */
|
|
@@ -1599,13 +1668,14 @@ const SlotTransformMode = {
|
|
|
1599
1668
|
mask: "mask",
|
|
1600
1669
|
dateFormat: "dateFormat"
|
|
1601
1670
|
};
|
|
1671
|
+
/** Separator between item key path and slot coding path in default export headers. */
|
|
1672
|
+
const EXPORT_COLUMN_SLOT_SEPARATOR = "__";
|
|
1602
1673
|
/** Source of an export column. */
|
|
1603
1674
|
const ExportColumnSource = {
|
|
1604
1675
|
meta: "meta",
|
|
1605
1676
|
context: "context",
|
|
1606
1677
|
response: "response"
|
|
1607
1678
|
};
|
|
1608
|
-
|
|
1609
1679
|
//#endregion
|
|
1610
1680
|
//#region src/response-exporter/slot-formatter.ts
|
|
1611
1681
|
/** Default transform config when no profile override. */
|
|
@@ -1672,7 +1742,6 @@ function valueToString(value) {
|
|
|
1672
1742
|
default: return String(value.value ?? "");
|
|
1673
1743
|
}
|
|
1674
1744
|
}
|
|
1675
|
-
|
|
1676
1745
|
//#endregion
|
|
1677
1746
|
//#region src/response-exporter/csv-serializer.ts
|
|
1678
1747
|
const DEFAULT_OPTIONS = {
|
|
@@ -1699,32 +1768,28 @@ function serializeToCsv(columns, rows, options) {
|
|
|
1699
1768
|
};
|
|
1700
1769
|
const sep = opts.separator;
|
|
1701
1770
|
const lines = [];
|
|
1702
|
-
const
|
|
1703
|
-
if (opts.includeHeader) lines.push(
|
|
1771
|
+
const headers = columns.map((c) => c.header);
|
|
1772
|
+
if (opts.includeHeader) lines.push(headers.map((header) => escapeCsvCell(header, sep)).join(sep));
|
|
1704
1773
|
for (const row of rows) {
|
|
1705
|
-
const cells =
|
|
1774
|
+
const cells = headers.map((header) => escapeCsvCell(row[header] ?? "", sep));
|
|
1706
1775
|
lines.push(cells.join(sep));
|
|
1707
1776
|
}
|
|
1708
1777
|
return lines.join(opts.lineEnding);
|
|
1709
1778
|
}
|
|
1710
|
-
|
|
1711
1779
|
//#endregion
|
|
1712
1780
|
//#region src/response-exporter/exporter.ts
|
|
1713
|
-
const VALUE_REF_SEP$1 = "...";
|
|
1714
|
-
function parseValueRef(ref) {
|
|
1715
|
-
const parts = ref.split(VALUE_REF_SEP$1);
|
|
1716
|
-
if (parts.length !== 3 || parts[1] !== ValueReferenceMethod.get) return {
|
|
1717
|
-
itemId: "",
|
|
1718
|
-
slotId: ""
|
|
1719
|
-
};
|
|
1720
|
-
return {
|
|
1721
|
-
itemId: parts[0],
|
|
1722
|
-
slotId: parts[2]
|
|
1723
|
-
};
|
|
1724
|
-
}
|
|
1725
1781
|
function slotOverrideKey(itemId, slotId) {
|
|
1726
1782
|
return `${itemId}::${slotId}`;
|
|
1727
1783
|
}
|
|
1784
|
+
function responseColumnId(itemId, slotId) {
|
|
1785
|
+
return `${itemId}::${slotId}`;
|
|
1786
|
+
}
|
|
1787
|
+
function metaColumnId(metaField) {
|
|
1788
|
+
return `meta:${metaField}`;
|
|
1789
|
+
}
|
|
1790
|
+
function contextColumnId(contextKey) {
|
|
1791
|
+
return `context:${contextKey}`;
|
|
1792
|
+
}
|
|
1728
1793
|
function formatMetaValue(response, metaField) {
|
|
1729
1794
|
switch (metaField) {
|
|
1730
1795
|
case "submittedAt":
|
|
@@ -1752,25 +1817,27 @@ var SurveyResponseExporter = class {
|
|
|
1752
1817
|
const binding = this.versions.get(versionId);
|
|
1753
1818
|
if (!binding) return [];
|
|
1754
1819
|
const survey = binding.survey;
|
|
1755
|
-
const slots = survey.getAvailableResponseValueSlots();
|
|
1756
1820
|
const keyIndex = survey.keyIndex;
|
|
1757
1821
|
const keyByItemId = new Map(keyIndex.map((r) => [r.itemId, r]));
|
|
1758
1822
|
const profile = this.resolveProfileForVersion(versionId);
|
|
1759
1823
|
const columns = [];
|
|
1760
|
-
for (const
|
|
1761
|
-
const { itemId, slotId } = parseValueRef(valueRef);
|
|
1762
|
-
if (!itemId || !slotId) continue;
|
|
1763
|
-
if (valueRef.includes(`${VALUE_REF_SEP$1}${ValueReferenceMethod.isDefined}`)) continue;
|
|
1824
|
+
for (const { itemId, slots } of survey.getResponseSlotDefinitions()) {
|
|
1764
1825
|
const keyInfo = keyByItemId.get(itemId);
|
|
1765
|
-
const
|
|
1766
|
-
const
|
|
1767
|
-
|
|
1768
|
-
key
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1826
|
+
const itemBaseKey = keyInfo ? [...keyInfo.keyPath, keyInfo.key].join(".") : itemId;
|
|
1827
|
+
for (const slot of slots) {
|
|
1828
|
+
const columnId = responseColumnId(itemId, slot.slotId);
|
|
1829
|
+
const codingPath = [...slot.keyPath, slot.key].filter((part) => part.trim().length > 0);
|
|
1830
|
+
const defaultHeader = codingPath.length > 0 ? `${itemBaseKey}__${codingPath.join(".")}` : `${itemBaseKey}__${slot.slotId}`;
|
|
1831
|
+
const header = this.resolveColumnHeader(profile, columnId, defaultHeader);
|
|
1832
|
+
columns.push({
|
|
1833
|
+
id: columnId,
|
|
1834
|
+
header,
|
|
1835
|
+
source: ExportColumnSource.response,
|
|
1836
|
+
itemId,
|
|
1837
|
+
slotId: slot.slotId,
|
|
1838
|
+
valueType: slot.valueType
|
|
1839
|
+
});
|
|
1840
|
+
}
|
|
1774
1841
|
}
|
|
1775
1842
|
return columns;
|
|
1776
1843
|
}
|
|
@@ -1782,13 +1849,14 @@ var SurveyResponseExporter = class {
|
|
|
1782
1849
|
const vids = versionIds ?? [versionId];
|
|
1783
1850
|
const responseCols = [];
|
|
1784
1851
|
const seen = /* @__PURE__ */ new Set();
|
|
1785
|
-
for (const vid of vids) for (const c of this.computeResponseColumns(vid)) if (!seen.has(c.
|
|
1786
|
-
seen.add(c.
|
|
1852
|
+
for (const vid of vids) for (const c of this.computeResponseColumns(vid)) if (!seen.has(c.id)) {
|
|
1853
|
+
seen.add(c.id);
|
|
1787
1854
|
responseCols.push(c);
|
|
1788
1855
|
}
|
|
1789
1856
|
const profile = this.resolveProfileForVersion(versionId);
|
|
1790
1857
|
const metaColumns = META_COLUMN_ORDER.map((metaField) => ({
|
|
1791
|
-
|
|
1858
|
+
id: metaColumnId(metaField),
|
|
1859
|
+
header: this.resolveColumnHeader(profile, metaColumnId(metaField), metaField),
|
|
1792
1860
|
source: ExportColumnSource.meta,
|
|
1793
1861
|
metaField
|
|
1794
1862
|
}));
|
|
@@ -1803,23 +1871,38 @@ var SurveyResponseExporter = class {
|
|
|
1803
1871
|
if (ib >= 0) return 1;
|
|
1804
1872
|
return a.localeCompare(b);
|
|
1805
1873
|
} : void 0).map((contextKey) => ({
|
|
1806
|
-
|
|
1874
|
+
id: contextColumnId(contextKey),
|
|
1875
|
+
header: this.resolveColumnHeader(profile, contextColumnId(contextKey), `context.${contextKey}`),
|
|
1807
1876
|
source: ExportColumnSource.context,
|
|
1808
1877
|
contextKey
|
|
1809
1878
|
}));
|
|
1810
1879
|
const respOrder = profile?.responseColumnOrder ?? [];
|
|
1811
|
-
const byOrder = respOrder.filter((
|
|
1812
|
-
const remaining = responseCols.filter((c) => !respOrder.includes(c.
|
|
1880
|
+
const byOrder = respOrder.filter((id) => responseCols.some((c) => c.id === id)).map((id) => responseCols.find((c) => c.id === id));
|
|
1881
|
+
const remaining = responseCols.filter((c) => !respOrder.includes(c.id)).sort((a, b) => a.header.localeCompare(b.header));
|
|
1813
1882
|
const respCols = [...byOrder, ...remaining];
|
|
1814
|
-
|
|
1883
|
+
const columns = [
|
|
1815
1884
|
...metaColumns,
|
|
1816
1885
|
...contextCols,
|
|
1817
1886
|
...respCols
|
|
1818
1887
|
];
|
|
1888
|
+
this.assertUniqueHeaders(columns);
|
|
1889
|
+
return columns;
|
|
1819
1890
|
}
|
|
1820
1891
|
resolveProfileForVersion(versionId) {
|
|
1821
1892
|
return this.profiles.find((p) => !p.versionId || p.versionId === versionId);
|
|
1822
1893
|
}
|
|
1894
|
+
resolveColumnHeader(profile, columnId, defaultHeader) {
|
|
1895
|
+
const override = profile?.columnHeaders?.[columnId]?.trim();
|
|
1896
|
+
return override && override.length > 0 ? override : defaultHeader;
|
|
1897
|
+
}
|
|
1898
|
+
assertUniqueHeaders(columns) {
|
|
1899
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1900
|
+
for (const column of columns) {
|
|
1901
|
+
const existingId = seen.get(column.header);
|
|
1902
|
+
if (existingId && existingId !== column.id) throw new Error(`Duplicate export column header '${column.header}' for columns '${existingId}' and '${column.id}'`);
|
|
1903
|
+
seen.set(column.header, column.id);
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1823
1906
|
getTransformConfig(versionId, itemId, slotId) {
|
|
1824
1907
|
return this.resolveProfileForVersion(versionId)?.slotOverrides?.[slotOverrideKey(itemId, slotId)] ?? DEFAULT_TRANSFORM;
|
|
1825
1908
|
}
|
|
@@ -1832,14 +1915,14 @@ var SurveyResponseExporter = class {
|
|
|
1832
1915
|
const row = {};
|
|
1833
1916
|
for (const col of columns) {
|
|
1834
1917
|
if (col.source === ExportColumnSource.meta && col.metaField) {
|
|
1835
|
-
row[col.
|
|
1918
|
+
row[col.header] = formatMetaValue(response, col.metaField);
|
|
1836
1919
|
continue;
|
|
1837
1920
|
}
|
|
1838
1921
|
if (col.source === ExportColumnSource.context && col.contextKey) {
|
|
1839
1922
|
const value = response.context?.[col.contextKey];
|
|
1840
1923
|
const transformConfig = this.getContextTransformConfig(response.versionId, col.contextKey);
|
|
1841
1924
|
const valueType = value?.type ?? ValueType.string;
|
|
1842
|
-
row[col.
|
|
1925
|
+
row[col.header] = exportSingleResponseSlot({
|
|
1843
1926
|
value,
|
|
1844
1927
|
valueType,
|
|
1845
1928
|
transformConfig
|
|
@@ -1849,7 +1932,7 @@ var SurveyResponseExporter = class {
|
|
|
1849
1932
|
if (col.source === ExportColumnSource.response && col.itemId != null && col.slotId != null && col.valueType != null) {
|
|
1850
1933
|
const value = response.responses.get(col.itemId)?.response?.get(col.slotId);
|
|
1851
1934
|
const transformConfig = this.getTransformConfig(response.versionId, col.itemId, col.slotId);
|
|
1852
|
-
row[col.
|
|
1935
|
+
row[col.header] = exportSingleResponseSlot({
|
|
1853
1936
|
value,
|
|
1854
1937
|
valueType: col.valueType,
|
|
1855
1938
|
transformConfig
|
|
@@ -1872,17 +1955,8 @@ var SurveyResponseExporter = class {
|
|
|
1872
1955
|
return serializeToCsv(this.computeColumnsForBatch(responses), responses.map((r) => this.exportResponse(r)).filter((r) => r !== null), options);
|
|
1873
1956
|
}
|
|
1874
1957
|
};
|
|
1875
|
-
|
|
1876
1958
|
//#endregion
|
|
1877
1959
|
//#region src/response-exporter/codebook.ts
|
|
1878
|
-
const VALUE_REF_SEP = "...";
|
|
1879
|
-
/**
|
|
1880
|
-
* Extract plain text from Content for codebook display.
|
|
1881
|
-
*/
|
|
1882
|
-
function contentToPlainText(c) {
|
|
1883
|
-
if (!c) return "";
|
|
1884
|
-
return c.content ?? "";
|
|
1885
|
-
}
|
|
1886
1960
|
/**
|
|
1887
1961
|
* Generate a structured codebook from a survey definition.
|
|
1888
1962
|
*/
|
|
@@ -1890,26 +1964,18 @@ function generateCodebook(survey, options) {
|
|
|
1890
1964
|
const locales = options?.locales ?? survey.locales;
|
|
1891
1965
|
const keyIndex = survey.keyIndex;
|
|
1892
1966
|
const keyByItemId = new Map(keyIndex.map((r) => [r.itemId, r]));
|
|
1893
|
-
const
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
const slotId = parts[2];
|
|
1900
|
-
const list = valueRefToSlots.get(itemId) ?? [];
|
|
1901
|
-
if (!list.some((s) => s.slotId === slotId)) list.push({
|
|
1902
|
-
slotId,
|
|
1903
|
-
valueType
|
|
1904
|
-
});
|
|
1905
|
-
valueRefToSlots.set(itemId, list);
|
|
1906
|
-
}
|
|
1967
|
+
const slotDefsByItemId = new Map(survey.getResponseSlotDefinitions().map(({ itemId, slots }) => [itemId, slots.map((slot) => ({
|
|
1968
|
+
slotId: slot.slotId,
|
|
1969
|
+
key: slot.key,
|
|
1970
|
+
keyPath: [...slot.keyPath],
|
|
1971
|
+
valueType: slot.valueType
|
|
1972
|
+
}))]));
|
|
1907
1973
|
const items = [];
|
|
1908
1974
|
for (const item of survey.surveyItems.values()) {
|
|
1909
1975
|
const keyInfo = keyByItemId.get(item.id);
|
|
1910
1976
|
const key = keyInfo?.key ?? item.id;
|
|
1911
1977
|
const keyPath = keyInfo?.keyPath ?? [];
|
|
1912
|
-
const slotList =
|
|
1978
|
+
const slotList = slotDefsByItemId.get(item.id) ?? [];
|
|
1913
1979
|
slotList.sort((a, b) => a.slotId.localeCompare(b.slotId));
|
|
1914
1980
|
let contentByLocale;
|
|
1915
1981
|
if (locales.length > 0) {
|
|
@@ -1919,7 +1985,7 @@ function generateCodebook(survey, options) {
|
|
|
1919
1985
|
const all = itemTranslations.getAllForLocale(locale);
|
|
1920
1986
|
if (all) {
|
|
1921
1987
|
const flat = {};
|
|
1922
|
-
for (const [contentKey, content] of Object.entries(all)) flat[contentKey] =
|
|
1988
|
+
for (const [contentKey, content] of Object.entries(all)) flat[contentKey] = getContentPlainText(content);
|
|
1923
1989
|
contentByLocale[locale] = flat;
|
|
1924
1990
|
}
|
|
1925
1991
|
}
|
|
@@ -1939,7 +2005,7 @@ function generateCodebook(survey, options) {
|
|
|
1939
2005
|
items: items.sort((a, b) => a.key.localeCompare(b.key))
|
|
1940
2006
|
};
|
|
1941
2007
|
}
|
|
1942
|
-
|
|
1943
2008
|
//#endregion
|
|
1944
|
-
export { AndExpressionEditor,
|
|
2009
|
+
export { AndExpressionEditor, CURRENT_SURVEY_SCHEMA, ConstBooleanEditor, ConstDateArrayEditor, ConstDateEditor, ConstExpression, ConstNumberArrayEditor, ConstNumberEditor, ConstStringArrayEditor, ConstStringEditor, ContentType, ContextVariableExpression, ContextVariableType, CtxCustomExpressionEditor, CtxCustomValueEditor, CtxLocaleEditor, CtxPFlagDateEditor, CtxPFlagIsDefinedEditor, CtxPFlagNumEditor, CtxPFlagStringEditor, DEFAULT_TRANSFORM, DurationUnits, EXPORT_COLUMN_SLOT_SEPARATOR, EqExpressionEditor, Expression, ExpressionEditor, ExpressionEvaluator, ExpressionType, FunctionExpression, FunctionExpressionNames, GroupItemCore, GtExpressionEditor, GteExpressionEditor, InRangeExpressionEditor, LtExpressionEditor, LteExpressionEditor, META_COLUMN_ORDER, MaxExpressionEditor, MinExpressionEditor, NumberPrecision, OrExpressionEditor, PageBreakItemCore, ReferenceUsageType, ReservedSurveyItemTypes, ResponseItem, ResponseVariableEditor, ResponseVariableExpression, SURVEY_RESPONSE_SCHEMA_VERSION, SlotTransformMode, StrEqExpressionEditor, StrListContainsExpressionEditor, SumExpressionEditor, Survey, SurveyEngineCore, SurveyEventTypes, SurveyItemCore, SurveyItemKey, SurveyItemPrefillApplyMode, SurveyItemPrefillTargetType, SurveyItemResponse, SurveyItemTranslations, SurveyResponse, SurveyResponseExporter, SurveyTranslations, TemplateDefTypes, ValueReference, ValueReferenceMethod, ValueType, and, assertResponseValue, buildItemExpression, builtInItemCoreRegistry, const_boolean, const_date, const_date_array, const_number, const_number_array, const_string, const_string_array, createFullRegistry, createItemCore, createItemTypeDefinitionRegistry, createRichTextContent, createSeededRandom, ctx_custom_expression, ctx_custom_value, ctx_locale, ctx_pflag_date, ctx_pflag_is_defined, ctx_pflag_num, ctx_pflag_string, deserializeSurveyItemPrefill, deserializeTemplateValue, deserializeTemplateValues, eq, escapeCsvCell, exportSingleResponseSlot, flattenTree, generateCodebook, generateCodingKey, generateId, getAssetUsagesFromContent, getContentPlainText, getItemExpressionDefinition, getPlainTextFromRichTextContent, gt, gte, hasRenderableRichTextBlock, hasRenderableRichTextContent, in_range, initValueForType, isBuiltInItemType, isContentEmpty, isLegacyItemGroupComponent, isLegacySurveyGroupItem, isResponseValue, lt, lte, max, min, or, prefillTargetsEqual, response_boolean, response_date, response_date_array, response_number, response_number_array, response_string, response_string_array, serializeSurveyItemPrefill, serializeTemplateValue, serializeTemplateValues, serializeToCsv, shuffleArray, shuffleIndices, str_eq, str_list_contains, structuredCloneMethod, sum, toItemTypeDefinitionRegistry, validateLocale };
|
|
2010
|
+
|
|
1945
2011
|
//# sourceMappingURL=index.mjs.map
|