@cxpinsight/survey-spec 0.1.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.
@@ -0,0 +1,337 @@
1
+ "use strict";
2
+ // Expression evaluator — supports the subset of operators the spec
3
+ // commits to (spec §7, §22):
4
+ //
5
+ // Comparators: = != < > <= >=
6
+ // Boolean: and or not && || !
7
+ // Arithmetic: + - * /
8
+ // Refs: {q_id} the respondent's answer to q_id
9
+ // {{variable}} resolved variable value
10
+ // 'string' string literal
11
+ // 42 numeric literal
12
+ // true / false boolean literal
13
+ //
14
+ // This is deliberately a simple tokens-based evaluator, not a full
15
+ // JS-compatible expression engine. It's used for:
16
+ // - showWhen / enabledWhen / requiredWhen (question + section)
17
+ // - `expression` type questions (computed value)
18
+ // - `calculated` variable expressions
19
+ //
20
+ // Being cautious: an untyped eval() would let survey authors run
21
+ // arbitrary JS against respondent answers. This restricted grammar
22
+ // keeps the surface area bounded.
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.evaluateExpression = evaluateExpression;
25
+ exports.evaluateCondition = evaluateCondition;
26
+ exports.isParseable = isParseable;
27
+ // ─── Public entry point ───────────────────────────────────────────────
28
+ function evaluateExpression(source, ctx) {
29
+ if (typeof source !== 'string')
30
+ return undefined;
31
+ const src = source.trim();
32
+ if (!src)
33
+ return undefined;
34
+ try {
35
+ const tokens = tokenize(src);
36
+ const [value, consumed] = parseExpression(tokens, 0, ctx);
37
+ if (consumed !== tokens.length)
38
+ return undefined; // trailing garbage
39
+ return value;
40
+ }
41
+ catch {
42
+ return undefined;
43
+ }
44
+ }
45
+ // showWhen/enabledWhen coerce the result to boolean. Empty / undefined
46
+ // evaluates to false (hides the question) — friendlier than throwing.
47
+ function evaluateCondition(source, ctx) {
48
+ if (!source)
49
+ return true; // no condition = always shown
50
+ // An expression that cannot be PARSED is not a false condition — it is not a
51
+ // condition. Treating a typo as "false" hid the question, and a hidden question
52
+ // is invisible in the response data: no answers, no error, no signal, and the
53
+ // author concludes nobody wanted to answer it. Silent data loss is the worse
54
+ // failure, so an invalid condition is ignored and the question shows. The
55
+ // builder is where a malformed expression should be surfaced, before it ships.
56
+ //
57
+ // A well-formed expression that evaluates falsy still hides the question, which
58
+ // is the whole point of showWhen. Only unparseable input is ignored.
59
+ if (!isParseable(source))
60
+ return true;
61
+ const result = evaluateExpression(source, ctx);
62
+ return truthy(result);
63
+ }
64
+ /** Whether `source` parses at all, independent of what it evaluates to. */
65
+ function isParseable(source) {
66
+ if (!source || !source.trim())
67
+ return true;
68
+ try {
69
+ const tokens = tokenize(source.trim());
70
+ const [, consumed] = parseExpression(tokens, 0, { variables: {}, answers: {} });
71
+ return consumed === tokens.length;
72
+ }
73
+ catch {
74
+ return false;
75
+ }
76
+ }
77
+ function tokenize(src) {
78
+ const tokens = [];
79
+ let i = 0;
80
+ const len = src.length;
81
+ while (i < len) {
82
+ const c = src[i];
83
+ // whitespace
84
+ if (c === ' ' || c === '\t' || c === '\n' || c === '\r') {
85
+ i++;
86
+ continue;
87
+ }
88
+ // string literal — single or double quoted
89
+ if (c === "'" || c === '"') {
90
+ const quote = c;
91
+ let out = '';
92
+ i++;
93
+ while (i < len && src[i] !== quote) {
94
+ if (src[i] === '\\' && i + 1 < len) {
95
+ out += src[i + 1];
96
+ i += 2;
97
+ }
98
+ else {
99
+ out += src[i];
100
+ i++;
101
+ }
102
+ }
103
+ i++; // closing quote
104
+ tokens.push({ kind: 'str', value: out });
105
+ continue;
106
+ }
107
+ // numeric literal
108
+ if ((c >= '0' && c <= '9') || (c === '-' && src[i + 1] >= '0' && src[i + 1] <= '9' && !prevExpectsBinary(tokens))) {
109
+ let j = i;
110
+ if (src[j] === '-')
111
+ j++;
112
+ while (j < len && ((src[j] >= '0' && src[j] <= '9') || src[j] === '.'))
113
+ j++;
114
+ tokens.push({ kind: 'num', value: parseFloat(src.slice(i, j)) });
115
+ i = j;
116
+ continue;
117
+ }
118
+ // {{variable_ref}} — spec §22 interpolation shape
119
+ if (c === '{' && src[i + 1] === '{') {
120
+ const end = src.indexOf('}}', i + 2);
121
+ if (end < 0)
122
+ throw new Error('unterminated {{');
123
+ const inner = src.slice(i + 2, end).trim();
124
+ const dot = inner.indexOf('.');
125
+ if (dot > 0) {
126
+ tokens.push({ kind: 'variable_ref', name: inner.slice(0, dot).trim(), suffix: inner.slice(dot + 1).trim() });
127
+ }
128
+ else {
129
+ tokens.push({ kind: 'variable_ref', name: inner });
130
+ }
131
+ i = end + 2;
132
+ continue;
133
+ }
134
+ // {q_id} — answer reference (single-brace, spec §7)
135
+ if (c === '{') {
136
+ const end = src.indexOf('}', i + 1);
137
+ if (end < 0)
138
+ throw new Error('unterminated {');
139
+ tokens.push({ kind: 'answer_ref', name: src.slice(i + 1, end).trim() });
140
+ i = end + 1;
141
+ continue;
142
+ }
143
+ // parentheses
144
+ if (c === '(') {
145
+ tokens.push({ kind: 'lparen' });
146
+ i++;
147
+ continue;
148
+ }
149
+ if (c === ')') {
150
+ tokens.push({ kind: 'rparen' });
151
+ i++;
152
+ continue;
153
+ }
154
+ // Multi-character operators. Order matters — longest first.
155
+ //
156
+ // The "did we consume one?" check used to be `src[i - 1] === src[i]`, which
157
+ // is not that question. After `<=` is consumed, `c` still holds `<` from the
158
+ // top of the loop, so the single-character branch below pushed a SECOND `<`
159
+ // token and advanced i again. The extra token made `consumed !== tokens.length`
160
+ // in evaluateExpression, which returns undefined, which is falsy — so every
161
+ // showWhen using <=, >=, ==, <> , && or || silently evaluated to FALSE and hid
162
+ // its question. Only `!=` survived, by accident of token ordering.
163
+ //
164
+ // This is the live respondent path for link surveys and SdkSurveyHost, while
165
+ // the mobile and web SDKs both tokenize correctly — so the same survey branched
166
+ // differently depending on how a respondent arrived. Mobile already carries
167
+ // this fix (survey/expressionEval.ts); this is that fix, ported back.
168
+ let matchedMulti = false;
169
+ for (const op of ['<=', '>=', '!=', '<>', '&&', '||', '==']) {
170
+ if (src.slice(i, i + op.length) === op) {
171
+ tokens.push({ kind: 'op', value: op === '==' ? '=' : op });
172
+ i += op.length;
173
+ matchedMulti = true;
174
+ break;
175
+ }
176
+ }
177
+ if (matchedMulti)
178
+ continue;
179
+ // Single-char operators
180
+ if ('=<>+-*/!'.includes(c)) {
181
+ tokens.push({ kind: 'op', value: c });
182
+ i++;
183
+ continue;
184
+ }
185
+ // Keywords: true / false / null / and / or / not / contains
186
+ const kw = src.slice(i).match(/^[a-zA-Z_][a-zA-Z_0-9]*/);
187
+ if (kw) {
188
+ const word = kw[0];
189
+ i += word.length;
190
+ const lower = word.toLowerCase();
191
+ if (lower === 'true')
192
+ tokens.push({ kind: 'bool', value: true });
193
+ else if (lower === 'false')
194
+ tokens.push({ kind: 'bool', value: false });
195
+ else if (lower === 'null')
196
+ tokens.push({ kind: 'null' });
197
+ else if (lower === 'and')
198
+ tokens.push({ kind: 'op', value: '&&' });
199
+ else if (lower === 'or')
200
+ tokens.push({ kind: 'op', value: '||' });
201
+ else if (lower === 'not')
202
+ tokens.push({ kind: 'op', value: '!' });
203
+ else if (lower === 'contains')
204
+ tokens.push({ kind: 'op', value: 'contains' });
205
+ else
206
+ throw new Error(`unknown identifier "${word}" — refs must be wrapped in {}`);
207
+ continue;
208
+ }
209
+ throw new Error(`unexpected character "${c}" at position ${i}`);
210
+ }
211
+ return tokens;
212
+ }
213
+ function prevExpectsBinary(tokens) {
214
+ const prev = tokens[tokens.length - 1];
215
+ if (!prev)
216
+ return false;
217
+ return prev.kind === 'num' || prev.kind === 'str' || prev.kind === 'bool'
218
+ || prev.kind === 'answer_ref' || prev.kind === 'variable_ref'
219
+ || prev.kind === 'rparen';
220
+ }
221
+ // ─── Parser — precedence climbing ────────────────────────────────────
222
+ // Operator precedence table — higher number = tighter binding.
223
+ const PREC = {
224
+ '||': 1, '&&': 2,
225
+ '=': 3, '!=': 3, '<>': 3, 'contains': 3,
226
+ '<': 4, '>': 4, '<=': 4, '>=': 4,
227
+ '+': 5, '-': 5,
228
+ '*': 6, '/': 6,
229
+ };
230
+ function parseExpression(tokens, pos, ctx, minPrec = 1) {
231
+ let [lhs, next] = parseUnary(tokens, pos, ctx);
232
+ while (next < tokens.length) {
233
+ const t = tokens[next];
234
+ if (t.kind !== 'op')
235
+ break;
236
+ const prec = PREC[t.value];
237
+ if (prec === undefined || prec < minPrec)
238
+ break;
239
+ const op = t.value;
240
+ const [rhs, after] = parseExpression(tokens, next + 1, ctx, prec + 1);
241
+ lhs = applyBinary(op, lhs, rhs);
242
+ next = after;
243
+ }
244
+ return [lhs, next];
245
+ }
246
+ function parseUnary(tokens, pos, ctx) {
247
+ const t = tokens[pos];
248
+ if (!t)
249
+ throw new Error('unexpected end of expression');
250
+ if (t.kind === 'op' && t.value === '!') {
251
+ const [inner, after] = parseUnary(tokens, pos + 1, ctx);
252
+ return [!truthy(inner), after];
253
+ }
254
+ if (t.kind === 'op' && t.value === '-') {
255
+ const [inner, after] = parseUnary(tokens, pos + 1, ctx);
256
+ return [-Number(inner), after];
257
+ }
258
+ return parsePrimary(tokens, pos, ctx);
259
+ }
260
+ function parsePrimary(tokens, pos, ctx) {
261
+ const t = tokens[pos];
262
+ if (!t)
263
+ throw new Error('unexpected end of expression');
264
+ switch (t.kind) {
265
+ case 'num': return [t.value, pos + 1];
266
+ case 'str': return [t.value, pos + 1];
267
+ case 'bool': return [t.value, pos + 1];
268
+ case 'null': return [null, pos + 1];
269
+ case 'answer_ref': return [ctx.answers[t.name], pos + 1];
270
+ case 'variable_ref': {
271
+ // Resolution rules for {{name.suffix}}:
272
+ // • {{q1.answer}} → ctx.answers.q1 (special-case for legacy)
273
+ // • {{customer_name}} → ctx.variables.customer_name
274
+ // • {{device.theme}} → walk dotted path into ctx.variables.device
275
+ // • {{a.b.c.d}} → walk into ctx.variables.a.b.c.d
276
+ // A dotted suffix that hits a non-object mid-walk returns undefined —
277
+ // which then compares falsy in showWhen. This lets authors reference
278
+ // any structured runtime signal (device, session, session.location, …)
279
+ // without adding new token kinds — they just live under variables.*
280
+ // as nested objects, injected by the SDK at render time.
281
+ if (t.suffix === 'answer')
282
+ return [ctx.answers[t.name], pos + 1];
283
+ const root = ctx.variables[t.name];
284
+ if (!t.suffix)
285
+ return [root, pos + 1];
286
+ let cursor = root;
287
+ for (const seg of t.suffix.split('.')) {
288
+ if (cursor == null || typeof cursor !== 'object') {
289
+ cursor = undefined;
290
+ break;
291
+ }
292
+ cursor = cursor[seg];
293
+ }
294
+ return [cursor, pos + 1];
295
+ }
296
+ case 'lparen': {
297
+ const [inner, after] = parseExpression(tokens, pos + 1, ctx, 1);
298
+ if (tokens[after]?.kind !== 'rparen')
299
+ throw new Error('missing closing paren');
300
+ return [inner, after + 1];
301
+ }
302
+ default: throw new Error(`unexpected token: ${JSON.stringify(t)}`);
303
+ }
304
+ }
305
+ // ─── Operators ───────────────────────────────────────────────────────
306
+ function applyBinary(op, lhs, rhs) {
307
+ switch (op) {
308
+ case '=': return String(lhs) === String(rhs);
309
+ case '!=':
310
+ case '<>': return String(lhs) !== String(rhs);
311
+ case '<': return Number(lhs) < Number(rhs);
312
+ case '>': return Number(lhs) > Number(rhs);
313
+ case '<=': return Number(lhs) <= Number(rhs);
314
+ case '>=': return Number(lhs) >= Number(rhs);
315
+ case '&&': return truthy(lhs) && truthy(rhs);
316
+ case '||': return truthy(lhs) || truthy(rhs);
317
+ case '+': return typeof lhs === 'string' || typeof rhs === 'string'
318
+ ? String(lhs) + String(rhs)
319
+ : Number(lhs) + Number(rhs);
320
+ case '-': return Number(lhs) - Number(rhs);
321
+ case '*': return Number(lhs) * Number(rhs);
322
+ case '/': return Number(lhs) / Number(rhs);
323
+ case 'contains':
324
+ if (Array.isArray(lhs))
325
+ return lhs.includes(rhs);
326
+ return String(lhs ?? '').includes(String(rhs));
327
+ default: return undefined;
328
+ }
329
+ }
330
+ function truthy(v) {
331
+ if (v === false || v === null || v === undefined || v === 0 || v === '')
332
+ return false;
333
+ if (Array.isArray(v))
334
+ return v.length > 0;
335
+ return true;
336
+ }
337
+ //# sourceMappingURL=expressionEval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expressionEval.js","sourceRoot":"","sources":["expressionEval.ts"],"names":[],"mappings":"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"}