@cxpinsight/survey-spec 0.4.0 → 0.5.1

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.
@@ -1,41 +1,4 @@
1
- /**
2
- * Answer validation — whether a respondent may submit.
3
- *
4
- * A divergence here means the same answer is accepted on one channel and
5
- * rejected on another. The respondent hits a wall that does not exist for
6
- * someone who arrived by a different route, and an analyst comparing the two
7
- * sets of responses is comparing two instruments.
8
- *
9
- * There were three implementations and all three disagreed:
10
- *
11
- * • The WEB SDK had none. `survey.js` checked emptiness inline at the Next
12
- * button and nothing else, so it accepted 8 of 32 answers the others
13
- * rejected — including whitespace against a required question, `nope` as an
14
- * email address, and any string against `minLength`.
15
- *
16
- * • REACT and MOBILE agreed on 26 fixtures and still differed, because every
17
- * one of those fixtures used `type: 'text'` with an `inputType`. React's
18
- * dispatcher has no case for `email`, `number`, `csat` or `ces` as question
19
- * TYPES, so a question of `type: 'email'` was format-checked on the phone
20
- * and waved through on a link.
21
- *
22
- * This module is the union, and each half was chosen for a reason:
23
- *
24
- * • `isEmpty` is React's, because it is type-aware. The web renderer's values
25
- * are compound — `{ choice }`, `{ choices }`, `{ text, attachments }` — and
26
- * mobile's primitives pass through the same code unharmed. Mobile's
27
- * primitive-only version would have called `{ choice: undefined }` non-empty
28
- * and let a blank required radio through.
29
- *
30
- * • The type dispatcher is mobile's, because it is the superset, and the
31
- * effective format is derived from `inputType || type` so `type: 'email'`
32
- * validates as an email whether or not the author also set an inputType.
33
- *
34
- * Order is spec §8 and it matters: required, then type-specific format, then
35
- * the author's `rules[]`. An empty answer should read "this is required", not
36
- * "that is not a valid email" — which sounds like the shape is wrong rather
37
- * than the field being blank.
38
- */
1
+ import { type ValidationMessage } from './messages';
39
2
  export interface ValidatableQuestion {
40
3
  type?: string;
41
4
  inputType?: string;
@@ -52,8 +15,17 @@ export interface ValidatableQuestion {
52
15
  choices?: unknown;
53
16
  options?: unknown;
54
17
  }
55
- /** Null when the answer is valid; otherwise the message to show. */
18
+ /**
19
+ * Null when the answer is valid; otherwise the ENGLISH message to show.
20
+ *
21
+ * The signature is unchanged on purpose — three renderers call this and expect
22
+ * a string. The wording now comes from one table (messages.ts) rather than
23
+ * being built inside the rules, so a renderer that wants another language calls
24
+ * `validateAnswerCode` and words the code itself.
25
+ */
56
26
  export declare function validateAnswer(question: ValidatableQuestion, value: unknown): string | null;
27
+ /** The same rules, as a code and its parameters. This is what a port implements. */
28
+ export declare function validateAnswerCode(question: ValidatableQuestion, value: unknown): ValidationMessage | null;
57
29
  /** The values an implied question offers, in order. Its buttons, effectively. */
58
30
  export declare function impliedChoices(question: ValidatableQuestion): string[];
59
31
  /**
@@ -61,8 +33,309 @@ export declare function impliedChoices(question: ValidatableQuestion): string[];
61
33
  * it records. One place, so "Activate discount" reads the same on a website,
62
34
  * a link and a phone.
63
35
  */
64
- export declare function impliedActions(question: ValidatableQuestion): Array<{
36
+ export declare function impliedActions(question: ValidatableQuestion,
37
+ /**
38
+ * Resolves {{references}} in the destination. Optional only so existing
39
+ * callers keep working; every renderer should pass one.
40
+ *
41
+ * A destination is authored as a TEMPLATE — "https://shop.example/cart/
42
+ * {{eventData.orderId}}" is the entire point of an abandoned-cart nudge —
43
+ * and until this existed the href was handed to the renderers verbatim. So
44
+ * the button navigated to a literal `{{eventData.orderId}}`, on the link
45
+ * surface and on React Native, sending someone to a 404 in the one moment
46
+ * the interaction exists to convert.
47
+ */
48
+ interpolate?: (s: string) => string): Array<{
65
49
  value: string;
66
50
  label: string;
51
+ href?: string;
52
+ defer?: boolean;
67
53
  }>;
54
+ /**
55
+ * Is this choice a "Remind me later" — a deferral rather than an answer?
56
+ *
57
+ * A deferring choice CLOSES the surface AND RECORDS A SKIP, and deliberately
58
+ * does not submit. That distinction is the whole feature: a skip feeds
59
+ * cooldownOnSkip and maxSkips, so the interaction comes back after the wait and
60
+ * gives up after the last try. A submission feeds maxSubmissions, which means
61
+ * "they decided" — and a person who asked to be reminded has decided nothing.
62
+ *
63
+ * Without this, "Remind me later" could only be built as an ordinary choice,
64
+ * which recorded an answer and retired the interaction for good: the one button
65
+ * whose entire purpose is to bring it back was the one that guaranteed it never
66
+ * would.
67
+ *
68
+ * NEVER ON A COMPLIANCE SURFACE, and not as a matter of taste. must-show
69
+ * bypasses the frequency gate entirely while unsatisfied, so a deferral there
70
+ * would be inert — the takeover would reappear immediately and the button would
71
+ * be a visible lie. If someone may genuinely postpone, the interaction is not
72
+ * must-show, and that is the setting to change.
73
+ */
74
+ export declare function isDeferChoice(choice: unknown, interactionType?: string | null): boolean;
75
+ /**
76
+ * The navigable target of a choice's `action`, or undefined.
77
+ *
78
+ * Only `type: 'url'` navigates today, and only to a scheme that cannot execute
79
+ * script in the host page. `javascript:` and `data:` are the two that can, so
80
+ * an author-supplied (or API-supplied) action is not a place to be permissive:
81
+ * a survey definition travels from the server into a customer's own site, and a
82
+ * URL that runs code there is an XSS vector wearing a button.
83
+ *
84
+ * Relative paths and app deep-link schemes are allowed — a mobile nudge that
85
+ * opens `myapp://cart` is the point of the feature.
86
+ */
87
+ export declare function safeActionHref(action: unknown): string | undefined;
88
+ /**
89
+ * The `src` for an image the author placed in a survey, or '' to draw nothing.
90
+ *
91
+ * SEPARATE FROM safeActionHref ON PURPOSE. That one guards a NAVIGATION target,
92
+ * where `data:` is an XSS vector wearing a button — a URL the host page is told
93
+ * to follow. This guards an IMAGE SOURCE, which the host page only ever
94
+ * decodes as pixels, and `data:image/...;base64,` is exactly how the builder
95
+ * stores an uploaded picture: there is no file host in the product, so an
96
+ * upload becomes a data URI or it becomes nothing.
97
+ *
98
+ * Collapsing the two was a real bug, not a hypothetical one. The web SDK ran
99
+ * every image through its link guard, which allows only http/https/mailto/tel,
100
+ * so every uploaded offer image was rewritten to `src=""` and vanished —
101
+ * on the web and mobile preview frames, which both run the SDK, while the link
102
+ * surface (React, no guard) showed it. An author saw their picture appear on
103
+ * one surface out of three and had no way to tell why.
104
+ *
105
+ * `<img>` is a non-scripting context: an SVG loaded through it cannot run its
106
+ * own script, so `data:image/*` is safe here in a way it is not on an href.
107
+ * Everything else with a scheme is still refused — `data:text/html` most of
108
+ * all, which is the one that would actually execute.
109
+ */
110
+ export declare function safeImageSrc(url: unknown): string;
111
+ /**
112
+ * The action buttons for a STEP, or [] for an ordinary step.
113
+ *
114
+ * A Notify, Offer or Comply interaction's buttons are its ANSWER — "Activate
115
+ * discount" and "No thanks" are the two things the respondent can say, not
116
+ * decoration beside a Next button. So a step that ends in an implied question
117
+ * has NO Next and NO Submit: pressing an action IS the submission.
118
+ *
119
+ * The rule lives here because all three renderers have to agree on it. When
120
+ * they didn't, the web SDK replaced Next with the actions while the React and
121
+ * React Native renderers drew the actions AND kept Submit — the respondent saw
122
+ * "Resume" and "Submit" stacked, and pressing Resume did nothing but tick a
123
+ * radio nobody could see.
124
+ *
125
+ * The LAST question decides. A step is allowed to carry content above the
126
+ * actions (a paragraph of terms, an image); what closes it is what turns it
127
+ * into a decision.
128
+ *
129
+ * Never returns an empty list for an implied step: an implied question with no
130
+ * choices would be a dead end — no buttons and no way out — so one neutral
131
+ * action beats a surface the respondent cannot leave.
132
+ */
133
+ export declare function impliedStepActions(questions: ValidatableQuestion[] | null | undefined): Array<{
134
+ value: string;
135
+ label: string;
136
+ }>;
137
+ /**
138
+ * Should this step's actions render with EQUAL PROMINENCE?
139
+ *
140
+ * A consent choice is not a call to action with an escape hatch. When accept is
141
+ * a filled accent button and decline is a quiet outline, the design is doing
142
+ * persuasion work on a decision that must be freely given — the pattern
143
+ * regulators name when they talk about consent dark patterns, and the reason
144
+ * `equalProminence` exists on the question.
145
+ *
146
+ * It was being SET by the compliance templates and read by nothing, so both
147
+ * shipped with a filled "I agree" beside a ghosted "Decline".
148
+ *
149
+ * Same "last question decides" rule as impliedStepActions, so the two can never
150
+ * disagree about which question they are talking about.
151
+ */
152
+ export declare function impliedEqualProminence(questions: ValidatableQuestion[] | null | undefined): boolean;
153
+ /**
154
+ * May this surface be dismissed by SWIPING it away?
155
+ *
156
+ * A push notification on a phone has no ✕. It slides down, and it leaves when
157
+ * you flick it. Removing the close button without providing the gesture would
158
+ * just make it untouchable, so the two decisions are one decision and it lives
159
+ * here rather than three times over.
160
+ *
161
+ * THE FULLSCREEN EXCLUSION IS THE WHOLE POINT. A compliance takeover ALSO sets
162
+ * showClose:false — for the opposite reason: it must not be escapable. Deriving
163
+ * "swipeable" from "has no close button" alone would hand every terms prompt and
164
+ * age check a flick-to-skip gesture, which is precisely the thing that makes it
165
+ * a blocking surface. So a swipe needs a POPUP, and a `mustShow` interaction is
166
+ * never swipeable whatever its mode.
167
+ *
168
+ * @param display The resolved display slice for THIS surface (already picked
169
+ * per platform — a web slice is not a mobile one).
170
+ * @param delivery The survey's delivery policy, for the mustShow veto.
171
+ */
172
+ export declare function canSwipeToDismiss(display: {
173
+ mode?: unknown;
174
+ showClose?: unknown;
175
+ } | null | undefined, delivery?: {
176
+ mustShow?: unknown;
177
+ } | null): boolean;
178
+ /**
179
+ * How long before this surface dismisses ITSELF, in ms. 0 = never.
180
+ *
181
+ * A push notification leaves on its own; that is most of what separates it from
182
+ * a dialog. `autoDismiss` was named in the interaction profile as a control the
183
+ * notify purpose leads with, and then existed nowhere else — no field, no UI, no
184
+ * timer — so every notification sat there until someone dealt with it.
185
+ *
186
+ * TWO SURFACES MUST NEVER SELF-DISMISS, and both would be silent disasters:
187
+ *
188
+ * - A LINK IS THE PAGE. Auto-dismissing there does not tidy a banner away, it
189
+ * blanks the page the respondent deliberately opened. The caller passes the
190
+ * resolved slice, so a link slice simply never carries the value — but the
191
+ * mode check below makes it structural rather than a matter of nobody
192
+ * having set it.
193
+ * - A BLOCKING SURFACE. Fullscreen compliance and anything `mustShow` exist to
194
+ * be answered; a timer that clears them is an escape hatch with a stopwatch.
195
+ *
196
+ * Clamped to 2s minimum: a notification that vanishes faster than it can be
197
+ * read is worse than one that never appeared, and it is the accessibility
198
+ * complaint that gets filed about auto-dismissing content.
199
+ */
200
+ export declare function autoDismissMs(display: {
201
+ mode?: unknown;
202
+ autoDismiss?: unknown;
203
+ } | null | undefined, delivery?: {
204
+ mustShow?: unknown;
205
+ } | null): number;
206
+ /**
207
+ * The countdown to show on an interaction, or null.
208
+ *
209
+ * THE TIMER IS THE DEADLINE — it is not a separate number an author types.
210
+ * That identity is the whole design: the survey's `endDate` is what the
211
+ * eligibility gate already enforces, so a countdown derived from it cannot
212
+ * outlive the thing it counts down to. An independently-authored timer can, and
213
+ * an offer whose clock hits zero while the discount still works (or keeps
214
+ * ticking after it stops) is the expired-deadline dark pattern the validity
215
+ * gate exists to prevent.
216
+ *
217
+ * Returns null when there is no deadline, when it has already passed (the gate
218
+ * stops serving then anyway), or when the surface has not asked to show one.
219
+ * Never invents a deadline.
220
+ */
221
+ export declare function deadlineCountdown(survey: {
222
+ endDate?: unknown;
223
+ } | null | undefined, display?: {
224
+ showDeadline?: unknown;
225
+ } | null, now?: number): {
226
+ ms: number;
227
+ text: string;
228
+ } | null;
229
+ /** "3d 4h" · "4h 12m" · "12m 30s" · "30s" — two units at most, never a wall of zeros. */
230
+ export declare function formatCountdown(ms: number): string;
231
+ export type OutcomeKind = 'thanks' | 'navigate' | 'dismiss' | 'fulfil' | 'unblock' | 'hold';
232
+ export interface OutcomeInput {
233
+ interactionType?: string | null;
234
+ /** The implied choice taken, e.g. 'accepted' | 'declined' | 'resumed'. */
235
+ action?: string | null;
236
+ /** True when the chosen action is the affirmative one (first choice). */
237
+ affirmative?: boolean;
238
+ reward?: {
239
+ type?: unknown;
240
+ value?: unknown;
241
+ whereValid?: unknown;
242
+ } | null;
243
+ compliance?: {
244
+ reviewRequired?: unknown;
245
+ onDecline?: unknown;
246
+ blockedMessage?: unknown;
247
+ } | null;
248
+ }
249
+ /**
250
+ * Decide the ending.
251
+ *
252
+ * The compliance branch is the one with teeth. Accepting is NOT the same as
253
+ * being cleared: when a human has to review an identity document, letting the
254
+ * customer through on submit tells them they are finished when they are not,
255
+ * and defeats the check. So `reviewRequired` holds the surface up, and a
256
+ * decline holds it too unless the author chose otherwise — a compliance
257
+ * surface you get past by saying no is not a compliance surface.
258
+ */
259
+ export declare function outcomeFor(input: OutcomeInput): OutcomeKind;
260
+ /**
261
+ * Can voice mode do anything on this step?
262
+ *
263
+ * A notification, an offer and a compliance takeover ask one question whose
264
+ * answer is which button you pressed. A microphone on that surface offers to
265
+ * transcribe nothing — it was showing up on offers because `voiceMode` was
266
+ * merely DEFAULTED off on newer templates, so any interaction created before
267
+ * that, or through the API, still rendered one.
268
+ *
269
+ * Structural, not a default: if the step has no answerable input, voice is off
270
+ * regardless of what the survey or the application says.
271
+ */
272
+ export declare function voiceUsable(questions: ValidatableQuestion[] | null | undefined): boolean;
273
+ /** The reward, ready to show — or null when there is nothing to hand over. */
274
+ export declare function rewardToShow(survey: {
275
+ reward?: {
276
+ type?: unknown;
277
+ value?: unknown;
278
+ whereValid?: unknown;
279
+ } | null;
280
+ endDate?: unknown;
281
+ } | null | undefined): {
282
+ type: string;
283
+ value: string;
284
+ whereValid: string;
285
+ expiresAt: string | null;
286
+ } | null;
287
+ /**
288
+ * Where clicking the CARD ITSELF should take someone, or null.
289
+ *
290
+ * People tap the message, not the button — so a notification's whole card is
291
+ * the click target. This was derived behaviour ("one action that has a link");
292
+ * it is now something an author sets, with the derived rule as the default so
293
+ * nothing that already worked stops working.
294
+ *
295
+ * THE TWO-ACTION VETO IS ABSOLUTE and not an author's to override. On a card
296
+ * offering accept and decline, a stray click anywhere would have to mean one of
297
+ * them — and on a consent surface that would manufacture agreement from a
298
+ * mis-tap. So a card is only ever clickable when it asks for exactly one thing.
299
+ */
300
+ export declare function cardClickTarget(display: {
301
+ cardClickable?: unknown;
302
+ cardHref?: unknown;
303
+ } | null | undefined, actions: Array<{
304
+ href?: string;
305
+ }> | null | undefined): string | null;
306
+ /** Hover treatment for a clickable card. Pointer devices only. */
307
+ export declare function cardHoverEffect(display: {
308
+ hoverEffect?: unknown;
309
+ } | null | undefined): 'none' | 'lift' | 'glow' | 'tint';
310
+ export type ActionKind = 'url' | 'event' | 'webhook';
311
+ export interface RawAction {
312
+ type?: unknown;
313
+ value?: unknown;
314
+ /** For 'event': the name the host application listens for. */
315
+ eventName?: unknown;
316
+ /** Template payload — values may contain {{variable}} references. */
317
+ payload?: unknown;
318
+ }
319
+ export interface ResolvedAction {
320
+ kind: ActionKind;
321
+ /** Navigable target for 'url', endpoint for 'webhook'. Null when unusable. */
322
+ href: string | null;
323
+ eventName: string | null;
324
+ /** Payload with every {{reference}} substituted. */
325
+ payload: Record<string, string>;
326
+ }
327
+ /**
328
+ * Resolve an action against a variable context.
329
+ *
330
+ * `interpolate` is supplied by the caller because each renderer already owns
331
+ * one, with its own context — the web SDK's reads the trigger event and device
332
+ * signals, the link renderer's reads URL params and answers. Passing the
333
+ * function keeps one rule here and one context there.
334
+ *
335
+ * INTERPOLATE FIRST, THEN CHECK THE SCHEME. A variable is data from outside —
336
+ * a URL parameter, a trait, an event field — so validating the template and
337
+ * then substituting would let `{{next}}` smuggle in `javascript:`. safeActionHref
338
+ * runs on the FINISHED string.
339
+ */
340
+ export declare function resolveAction(action: RawAction | null | undefined, interpolate?: (s: string) => string): ResolvedAction | null;
68
341
  //# sourceMappingURL=validate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAYH,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,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,mBAAmB,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAgB3F;AAuND,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAetE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,mBAAmB,GAAG,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAerG"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}