@cxpinsight/survey-spec 0.5.0 → 0.6.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/dist/expressionEval.js +29 -1
- package/dist/validate.d.ts +15 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +72 -3
- package/package.json +2 -2
package/dist/expressionEval.js
CHANGED
|
@@ -198,8 +198,10 @@ function tokenize(src) {
|
|
|
198
198
|
tokens.push({ kind: 'op', value: '&&' });
|
|
199
199
|
else if (lower === 'or')
|
|
200
200
|
tokens.push({ kind: 'op', value: '||' });
|
|
201
|
+
// Kept DISTINCT from `!` on purpose — the two do not bind the same way.
|
|
202
|
+
// See parseUnary: the word binds below comparison, the symbol above it.
|
|
201
203
|
else if (lower === 'not')
|
|
202
|
-
tokens.push({ kind: 'op', value: '
|
|
204
|
+
tokens.push({ kind: 'op', value: 'not' });
|
|
203
205
|
else if (lower === 'contains')
|
|
204
206
|
tokens.push({ kind: 'op', value: 'contains' });
|
|
205
207
|
else
|
|
@@ -243,10 +245,36 @@ function parseExpression(tokens, pos, ctx, minPrec = 1) {
|
|
|
243
245
|
}
|
|
244
246
|
return [lhs, next];
|
|
245
247
|
}
|
|
248
|
+
/**
|
|
249
|
+
* Precedence of the WORD `not`, which is deliberately not the precedence of `!`.
|
|
250
|
+
*
|
|
251
|
+
* `not {a} = 2` used to parse as `(not {a}) = 2` — false for every value of `a`,
|
|
252
|
+
* so an author writing "a is not 2" got a condition that could never be true and
|
|
253
|
+
* a question that never appeared. Conventional precedence, and SurveyJS whose
|
|
254
|
+
* dialect this emulates, put `not` BELOW comparison.
|
|
255
|
+
*
|
|
256
|
+
* It became urgent rather than latent when the server started shipping compiled
|
|
257
|
+
* trees: the compiler's `notExpr` already wrapped the whole comparison, so with
|
|
258
|
+
* a = 1 the same condition returned false here and true from the tree. One
|
|
259
|
+
* survey, two answers, decided by which path happened to run.
|
|
260
|
+
*
|
|
261
|
+
* 3 is the comparison tier in PREC, so `not` swallows a comparison and its
|
|
262
|
+
* arithmetic and stops at `and`/`or` — matching the compiler exactly:
|
|
263
|
+
* not {a} = 2 and {b} = 1 → (not ({a} = 2)) and ({b} = 1)
|
|
264
|
+
*
|
|
265
|
+
* `!` is left alone. The compiler rejects it outright, so no tree exists to
|
|
266
|
+
* disagree with, and it binds tightly in every C-family language including the
|
|
267
|
+
* JavaScript authors are borrowing from.
|
|
268
|
+
*/
|
|
269
|
+
const NOT_WORD_PREC = 3;
|
|
246
270
|
function parseUnary(tokens, pos, ctx) {
|
|
247
271
|
const t = tokens[pos];
|
|
248
272
|
if (!t)
|
|
249
273
|
throw new Error('unexpected end of expression');
|
|
274
|
+
if (t.kind === 'op' && t.value === 'not') {
|
|
275
|
+
const [inner, after] = parseExpression(tokens, pos + 1, ctx, NOT_WORD_PREC);
|
|
276
|
+
return [!truthy(inner), after];
|
|
277
|
+
}
|
|
250
278
|
if (t.kind === 'op' && t.value === '!') {
|
|
251
279
|
const [inner, after] = parseUnary(tokens, pos + 1, ctx);
|
|
252
280
|
return [!truthy(inner), after];
|
package/dist/validate.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export interface ValidatableQuestion {
|
|
|
8
8
|
maxLength?: number;
|
|
9
9
|
minValue?: number;
|
|
10
10
|
maxValue?: number;
|
|
11
|
+
/** spec §8's other spelling of a pattern rule — see validateRules. */
|
|
12
|
+
regex?: string;
|
|
11
13
|
minCount?: number;
|
|
12
14
|
maxCount?: number;
|
|
13
15
|
rules?: unknown;
|
|
@@ -33,7 +35,19 @@ export declare function impliedChoices(question: ValidatableQuestion): string[];
|
|
|
33
35
|
* it records. One place, so "Activate discount" reads the same on a website,
|
|
34
36
|
* a link and a phone.
|
|
35
37
|
*/
|
|
36
|
-
export declare function impliedActions(question: ValidatableQuestion
|
|
38
|
+
export declare function impliedActions(question: ValidatableQuestion,
|
|
39
|
+
/**
|
|
40
|
+
* Resolves {{references}} in the destination. Optional only so existing
|
|
41
|
+
* callers keep working; every renderer should pass one.
|
|
42
|
+
*
|
|
43
|
+
* A destination is authored as a TEMPLATE — "https://shop.example/cart/
|
|
44
|
+
* {{eventData.orderId}}" is the entire point of an abandoned-cart nudge —
|
|
45
|
+
* and until this existed the href was handed to the renderers verbatim. So
|
|
46
|
+
* the button navigated to a literal `{{eventData.orderId}}`, on the link
|
|
47
|
+
* surface and on React Native, sending someone to a 404 in the one moment
|
|
48
|
+
* the interaction exists to convert.
|
|
49
|
+
*/
|
|
50
|
+
interpolate?: (s: string) => string): Array<{
|
|
37
51
|
value: string;
|
|
38
52
|
label: string;
|
|
39
53
|
href?: string;
|
package/dist/validate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAkDjE,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,mBAAmB,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAE3F;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,mBAAmB,EAAE,KAAK,EAAE,OAAO,GAAG,iBAAiB,GAAG,IAAI,CAgB1G;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
|
package/dist/validate.js
CHANGED
|
@@ -194,6 +194,34 @@ function validateTextish(question, value) {
|
|
|
194
194
|
if (typeof question.minLength === 'number' && trimmed.length < question.minLength) {
|
|
195
195
|
return { code: 'min_length', params: { min: question.minLength } };
|
|
196
196
|
}
|
|
197
|
+
// minValue / maxValue on a NUMERIC text input.
|
|
198
|
+
//
|
|
199
|
+
// These used to do nothing here. validateNumericRange is reached only from
|
|
200
|
+
// rating/csat/ces/nps, which carry real numbers; a question with
|
|
201
|
+
// inputType 'number' submits the STRING '5' and arrived at this function
|
|
202
|
+
// instead, which checked lengths and formats and never a range. An author
|
|
203
|
+
// setting "between 1 and 10" on a number question got a control that read as
|
|
204
|
+
// configured and enforced nothing, on every channel at once.
|
|
205
|
+
//
|
|
206
|
+
// The coercion is not new behaviour invented here: applyRule already does
|
|
207
|
+
// exactly this for a rules[] entry of type min/max. So the same author intent
|
|
208
|
+
// was enforced when written one way and ignored when written the other. This
|
|
209
|
+
// makes the two agree.
|
|
210
|
+
//
|
|
211
|
+
// Guarded on inputType rather than applied to all text, because a range on a
|
|
212
|
+
// free-text comment is meaningless and coercing it would reject prose for
|
|
213
|
+
// being NaN.
|
|
214
|
+
if (inputType === 'number' && trimmed !== '') {
|
|
215
|
+
const n = Number(trimmed);
|
|
216
|
+
if (!Number.isNaN(n)) {
|
|
217
|
+
if (typeof question.minValue === 'number' && n < question.minValue) {
|
|
218
|
+
return { code: 'min_value', params: { min: question.minValue } };
|
|
219
|
+
}
|
|
220
|
+
if (typeof question.maxValue === 'number' && n > question.maxValue) {
|
|
221
|
+
return { code: 'max_value', params: { max: question.maxValue } };
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
197
225
|
return null;
|
|
198
226
|
}
|
|
199
227
|
function validateCheckbox(question, value) {
|
|
@@ -224,7 +252,20 @@ function validateNumericRange(question, value) {
|
|
|
224
252
|
return null;
|
|
225
253
|
}
|
|
226
254
|
function validateRules(question, value) {
|
|
227
|
-
const
|
|
255
|
+
const declared = Array.isArray(question.rules) ? question.rules : [];
|
|
256
|
+
// A top-level `regex` is the other spelling of a pattern rule, and it was read
|
|
257
|
+
// by nothing: `rules: [{ type: 'pattern' }]` rejected a bad value while
|
|
258
|
+
// `regex: '…'` accepted it, from the same author meaning the same thing. The
|
|
259
|
+
// setting did not fail — it disappeared, on every channel, with no warning.
|
|
260
|
+
//
|
|
261
|
+
// Treated as a pattern rule so one intent has one behaviour. This is the same
|
|
262
|
+
// client-side exposure the existing spelling already carries: a catastrophic
|
|
263
|
+
// pattern costs the respondent their own tab, which is why the SERVER still
|
|
264
|
+
// refuses to evaluate either spelling — there the cost is shared, and
|
|
265
|
+
// `^(a+)+$` against 24 characters takes 116ms and doubles every two.
|
|
266
|
+
const rules = typeof question.regex === 'string' && question.regex !== ''
|
|
267
|
+
? declared.concat([{ type: 'pattern', value: question.regex }])
|
|
268
|
+
: declared;
|
|
228
269
|
if (rules.length === 0)
|
|
229
270
|
return null;
|
|
230
271
|
const str = typeof value === 'string' ? value : String(value ?? '');
|
|
@@ -336,7 +377,19 @@ function impliedChoices(question) {
|
|
|
336
377
|
* it records. One place, so "Activate discount" reads the same on a website,
|
|
337
378
|
* a link and a phone.
|
|
338
379
|
*/
|
|
339
|
-
function impliedActions(question
|
|
380
|
+
function impliedActions(question,
|
|
381
|
+
/**
|
|
382
|
+
* Resolves {{references}} in the destination. Optional only so existing
|
|
383
|
+
* callers keep working; every renderer should pass one.
|
|
384
|
+
*
|
|
385
|
+
* A destination is authored as a TEMPLATE — "https://shop.example/cart/
|
|
386
|
+
* {{eventData.orderId}}" is the entire point of an abandoned-cart nudge —
|
|
387
|
+
* and until this existed the href was handed to the renderers verbatim. So
|
|
388
|
+
* the button navigated to a literal `{{eventData.orderId}}`, on the link
|
|
389
|
+
* surface and on React Native, sending someone to a 404 in the one moment
|
|
390
|
+
* the interaction exists to convert.
|
|
391
|
+
*/
|
|
392
|
+
interpolate = (s) => s) {
|
|
340
393
|
const raw = question.choices
|
|
341
394
|
|| question.options;
|
|
342
395
|
if (!Array.isArray(raw))
|
|
@@ -356,7 +409,23 @@ function impliedActions(question) {
|
|
|
356
409
|
// function returned only {value, label}, and so a "Resume" button on an
|
|
357
410
|
// abandoned-cart nudge recorded the answer and left the customer exactly
|
|
358
411
|
// where they were — which is the one thing that nudge exists to change.
|
|
359
|
-
|
|
412
|
+
// Interpolated BEFORE the scheme check, never after: a template that
|
|
413
|
+
// resolves to `javascript:` has to be caught on what it BECAME, not on
|
|
414
|
+
// the harmless-looking string it started as.
|
|
415
|
+
const rawHref = (o.action && typeof o.action === 'object')
|
|
416
|
+
? o.action.value
|
|
417
|
+
: undefined;
|
|
418
|
+
const resolved = typeof rawHref === 'string' && rawHref
|
|
419
|
+
? interpolate(rawHref)
|
|
420
|
+
: rawHref;
|
|
421
|
+
// A reference that resolved to nothing leaves the braces behind. Sending
|
|
422
|
+
// someone to a URL with `{{...}}` still in it is worse than not moving
|
|
423
|
+
// them: the answer is recorded either way, and a 404 reads as the
|
|
424
|
+
// product being broken rather than a destination being unset.
|
|
425
|
+
const usable = typeof resolved === 'string' && /\{\{.*\}\}/.test(resolved)
|
|
426
|
+
? undefined
|
|
427
|
+
: resolved;
|
|
428
|
+
const href = safeActionHref(usable === undefined ? undefined : { ...o.action, value: usable });
|
|
360
429
|
if (value !== '' || label !== '') {
|
|
361
430
|
const entry = href ? { value, label: label || value, href } : { value, label: label || value };
|
|
362
431
|
// "Remind me later" — see isDeferChoice. Carried through because a
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cxpinsight/survey-spec",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "The survey specification the renderers share
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "The survey specification the renderers share — expression evaluation first. Source of truth for behaviour that must be identical on web, links and mobile.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|