@nodii/onboarding 0.1.0-dev.0 → 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.
Files changed (66) hide show
  1. package/README.md +78 -0
  2. package/dist/chunk-AZE3NPSY.js +186 -0
  3. package/dist/chunk-AZE3NPSY.js.map +1 -0
  4. package/dist/{chunk-BQCTDU5V.js → chunk-BMQINH6O.js} +89 -15
  5. package/dist/chunk-BMQINH6O.js.map +1 -0
  6. package/dist/{chunk-34BQX2KR.js → chunk-F75ZJERM.js} +41 -6
  7. package/dist/chunk-F75ZJERM.js.map +1 -0
  8. package/dist/chunk-FIRSA7EH.js +3 -0
  9. package/dist/{chunk-ZDY2I6KY.js.map → chunk-FIRSA7EH.js.map} +1 -1
  10. package/dist/{chunk-SWMIIUXR.js → chunk-IPAKPLIF.js} +590 -92
  11. package/dist/chunk-IPAKPLIF.js.map +1 -0
  12. package/dist/chunk-JFDQZ3AC.js +3 -0
  13. package/dist/chunk-JFDQZ3AC.js.map +1 -0
  14. package/dist/{chunk-4SWOVHZ2.js → chunk-KQTS47FC.js} +129 -17
  15. package/dist/chunk-KQTS47FC.js.map +1 -0
  16. package/dist/chunk-LVJM4CTG.js +306 -0
  17. package/dist/chunk-LVJM4CTG.js.map +1 -0
  18. package/dist/chunk-SEKNVHD3.js +59 -0
  19. package/dist/chunk-SEKNVHD3.js.map +1 -0
  20. package/dist/chunk-SIMLMQPT.js +37 -0
  21. package/dist/chunk-SIMLMQPT.js.map +1 -0
  22. package/dist/chunk-U56GQITG.js +79 -0
  23. package/dist/chunk-U56GQITG.js.map +1 -0
  24. package/dist/{chunk-AFCJLUPK.js → chunk-U6AXKGYQ.js} +14 -5
  25. package/dist/chunk-U6AXKGYQ.js.map +1 -0
  26. package/dist/{chunk-AW7W3HAC.js → chunk-XJTJPBJB.js} +40 -3
  27. package/dist/chunk-XJTJPBJB.js.map +1 -0
  28. package/dist/client-CqE2dF9A.d.ts +86 -0
  29. package/dist/consent/index.d.ts +59 -0
  30. package/dist/consent/index.js +7 -0
  31. package/dist/consent/index.js.map +1 -0
  32. package/dist/controller-BQb62D0N.d.ts +177 -0
  33. package/dist/dynamic/index.d.ts +57 -6
  34. package/dist/dynamic/index.js +4 -2
  35. package/dist/errors-vJkye4a0.d.ts +110 -0
  36. package/dist/form/index.d.ts +2 -2
  37. package/dist/form/index.js +2 -2
  38. package/dist/index-Dqfa890U.d.ts +83 -0
  39. package/dist/index.d.ts +12 -6
  40. package/dist/index.js +12 -8
  41. package/dist/{model-IEyDI54w.d.ts → model-ESLSEbi0.d.ts} +199 -46
  42. package/dist/model-mnjAEtKe.d.ts +253 -0
  43. package/dist/render-DC7P2BGQ.js +5 -0
  44. package/dist/render-DC7P2BGQ.js.map +1 -0
  45. package/dist/schema-BrXb9gnh.d.ts +267 -0
  46. package/dist/{signup-client-Bl6eUrxR.d.ts → signup-client-BL5DfarJ.d.ts} +152 -19
  47. package/dist/spec/index.d.ts +10 -81
  48. package/dist/spec/index.js +3 -2
  49. package/dist/submit/index.d.ts +7 -71
  50. package/dist/submit/index.js +3 -3
  51. package/dist/viewer/index.d.ts +4 -0
  52. package/dist/viewer/index.js +5 -0
  53. package/dist/viewer/index.js.map +1 -0
  54. package/dist/widget/index.d.ts +50 -7
  55. package/dist/widget/index.js +9 -7
  56. package/package.json +21 -2
  57. package/dist/chunk-34BQX2KR.js.map +0 -1
  58. package/dist/chunk-4SWOVHZ2.js.map +0 -1
  59. package/dist/chunk-AFCJLUPK.js.map +0 -1
  60. package/dist/chunk-AW7W3HAC.js.map +0 -1
  61. package/dist/chunk-BIFANV7M.js +0 -22
  62. package/dist/chunk-BIFANV7M.js.map +0 -1
  63. package/dist/chunk-BQCTDU5V.js.map +0 -1
  64. package/dist/chunk-SWMIIUXR.js.map +0 -1
  65. package/dist/chunk-ZDY2I6KY.js +0 -3
  66. package/dist/schema-TfyBU6JW.d.ts +0 -107
@@ -1,6 +1,7 @@
1
1
  import { z } from 'zod/v3';
2
- import { T as TerminalStage } from './model-IEyDI54w.js';
3
- import { C as ContactFormValues } from './schema-TfyBU6JW.js';
2
+ import { T as TerminalStage } from './model-ESLSEbi0.js';
3
+ import { e as ConsentSubmitDocument } from './controller-BQb62D0N.js';
4
+ import { C as ContactFormValues } from './schema-BrXb9gnh.js';
4
5
 
5
6
  /**
6
7
  * Submit client for POST /api/v1/public/onboarding/leads.
@@ -42,7 +43,7 @@ interface LeadsSubmitOptions {
42
43
  * fresh token (recommended — tokens are single-use; a fixed string on a
43
44
  * retried request risks 403 after the first attempt consumed it).
44
45
  */
45
- botToken: BotTokenSource;
46
+ botToken?: BotTokenSource;
46
47
  /**
47
48
  * Stable idempotency key for this submission. Generate ONCE with
48
49
  * `generateIdempotencyKey()` and pass the same key for retries.
@@ -116,7 +117,7 @@ declare function submitLead(values: ContactFormValues, options: LeadsSubmitOptio
116
117
  * Contract per the LOCKED hub REST interface (PublicOnboardingSubmitRequest):
117
118
  * - Body: { specVersion, answers, selectedServices?, botToken,
118
119
  * consent:{tosAccepted:true, privacyAccepted:true},
119
- * credentials:{email, password(12-256)} }
120
+ * credentials:{email, displayName?}, organisationName?, subdomain }
120
121
  * additionalProperties: false — validated STRICTLY client-side before
121
122
  * any fetch (unknown keys are rejected, not stripped).
122
123
  * - Idempotency-Key header REQUIRED (same D538 discipline as leads:
@@ -134,61 +135,177 @@ declare function submitLead(values: ContactFormValues, options: LeadsSubmitOptio
134
135
  * (/leads tolerates body-less 2xx because its only signal IS the status.)
135
136
  */
136
137
 
138
+ /**
139
+ * STRICT wire schema for ONE element of the D543 §4 consent.documents array.
140
+ * `accepted` is const-true (an unaccepted doc is never sent — the consent
141
+ * controller omits it), and `evidence` carries only the gate-relevant flags.
142
+ */
143
+ declare const consentSubmitDocumentSchema: z.ZodObject<{
144
+ legalDocumentId: z.ZodString;
145
+ versionNo: z.ZodNumber;
146
+ accepted: z.ZodLiteral<true>;
147
+ evidence: z.ZodObject<{
148
+ scrolled_to_end: z.ZodOptional<z.ZodBoolean>;
149
+ opened: z.ZodOptional<z.ZodBoolean>;
150
+ }, "strict", z.ZodTypeAny, {
151
+ opened?: boolean | undefined;
152
+ scrolled_to_end?: boolean | undefined;
153
+ }, {
154
+ opened?: boolean | undefined;
155
+ scrolled_to_end?: boolean | undefined;
156
+ }>;
157
+ }, "strict", z.ZodTypeAny, {
158
+ legalDocumentId: string;
159
+ versionNo: number;
160
+ accepted: true;
161
+ evidence: {
162
+ opened?: boolean | undefined;
163
+ scrolled_to_end?: boolean | undefined;
164
+ };
165
+ }, {
166
+ legalDocumentId: string;
167
+ versionNo: number;
168
+ accepted: true;
169
+ evidence: {
170
+ opened?: boolean | undefined;
171
+ scrolled_to_end?: boolean | undefined;
172
+ };
173
+ }>;
137
174
  /**
138
175
  * STRICT wire schema — mirrors PublicOnboardingSubmitRequest exactly
139
- * (additionalProperties: false; consent booleans are const-true; password
140
- * length 12-256 per the locked schema).
176
+ * (additionalProperties: false; consent booleans are const-true; passwordless
177
+ * per D1010, with the workspace subdomain required by D836).
178
+ *
179
+ * D543 §4: `consent` extends from booleans to a per-document array. The
180
+ * `documents` array is AUTHORITATIVE (the server re-validates it); the
181
+ * `tosAccepted`/`privacyAccepted` booleans are kept as a DERIVED convenience
182
+ * (D543 "kept as a derived convenience only"). `documents` is OPTIONAL on the
183
+ * wire for backward-compat — a pre-ConsentPack onboarder serves no consentPack
184
+ * and submits the booleans alone (D543 "pre-ConsentPack submits still parse").
141
185
  */
142
186
  declare const signupWireSchema: z.ZodObject<{
143
187
  specVersion: z.ZodString;
144
188
  answers: z.ZodRecord<z.ZodString, z.ZodUnknown>;
145
189
  selectedServices: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
146
- botToken: z.ZodString;
190
+ botToken: z.ZodOptional<z.ZodString>;
147
191
  consent: z.ZodObject<{
148
192
  tosAccepted: z.ZodLiteral<true>;
149
193
  privacyAccepted: z.ZodLiteral<true>;
194
+ documents: z.ZodOptional<z.ZodArray<z.ZodObject<{
195
+ legalDocumentId: z.ZodString;
196
+ versionNo: z.ZodNumber;
197
+ accepted: z.ZodLiteral<true>;
198
+ evidence: z.ZodObject<{
199
+ scrolled_to_end: z.ZodOptional<z.ZodBoolean>;
200
+ opened: z.ZodOptional<z.ZodBoolean>;
201
+ }, "strict", z.ZodTypeAny, {
202
+ opened?: boolean | undefined;
203
+ scrolled_to_end?: boolean | undefined;
204
+ }, {
205
+ opened?: boolean | undefined;
206
+ scrolled_to_end?: boolean | undefined;
207
+ }>;
208
+ }, "strict", z.ZodTypeAny, {
209
+ legalDocumentId: string;
210
+ versionNo: number;
211
+ accepted: true;
212
+ evidence: {
213
+ opened?: boolean | undefined;
214
+ scrolled_to_end?: boolean | undefined;
215
+ };
216
+ }, {
217
+ legalDocumentId: string;
218
+ versionNo: number;
219
+ accepted: true;
220
+ evidence: {
221
+ opened?: boolean | undefined;
222
+ scrolled_to_end?: boolean | undefined;
223
+ };
224
+ }>, "many">>;
150
225
  }, "strict", z.ZodTypeAny, {
151
226
  tosAccepted: true;
152
227
  privacyAccepted: true;
228
+ documents?: {
229
+ legalDocumentId: string;
230
+ versionNo: number;
231
+ accepted: true;
232
+ evidence: {
233
+ opened?: boolean | undefined;
234
+ scrolled_to_end?: boolean | undefined;
235
+ };
236
+ }[] | undefined;
153
237
  }, {
154
238
  tosAccepted: true;
155
239
  privacyAccepted: true;
240
+ documents?: {
241
+ legalDocumentId: string;
242
+ versionNo: number;
243
+ accepted: true;
244
+ evidence: {
245
+ opened?: boolean | undefined;
246
+ scrolled_to_end?: boolean | undefined;
247
+ };
248
+ }[] | undefined;
156
249
  }>;
157
250
  credentials: z.ZodObject<{
158
251
  email: z.ZodString;
159
- password: z.ZodString;
252
+ displayName: z.ZodOptional<z.ZodString>;
160
253
  }, "strict", z.ZodTypeAny, {
161
254
  email: string;
162
- password: string;
255
+ displayName?: string | undefined;
163
256
  }, {
164
257
  email: string;
165
- password: string;
258
+ displayName?: string | undefined;
166
259
  }>;
260
+ organisationName: z.ZodOptional<z.ZodString>;
261
+ subdomain: z.ZodString;
167
262
  }, "strict", z.ZodTypeAny, {
168
- botToken: string;
169
263
  specVersion: string;
170
264
  credentials: {
171
265
  email: string;
172
- password: string;
266
+ displayName?: string | undefined;
173
267
  };
268
+ subdomain: string;
174
269
  answers: Record<string, unknown>;
175
270
  consent: {
176
271
  tosAccepted: true;
177
272
  privacyAccepted: true;
273
+ documents?: {
274
+ legalDocumentId: string;
275
+ versionNo: number;
276
+ accepted: true;
277
+ evidence: {
278
+ opened?: boolean | undefined;
279
+ scrolled_to_end?: boolean | undefined;
280
+ };
281
+ }[] | undefined;
178
282
  };
283
+ botToken?: string | undefined;
284
+ organisationName?: string | undefined;
179
285
  selectedServices?: string[] | undefined;
180
286
  }, {
181
- botToken: string;
182
287
  specVersion: string;
183
288
  credentials: {
184
289
  email: string;
185
- password: string;
290
+ displayName?: string | undefined;
186
291
  };
292
+ subdomain: string;
187
293
  answers: Record<string, unknown>;
188
294
  consent: {
189
295
  tosAccepted: true;
190
296
  privacyAccepted: true;
297
+ documents?: {
298
+ legalDocumentId: string;
299
+ versionNo: number;
300
+ accepted: true;
301
+ evidence: {
302
+ opened?: boolean | undefined;
303
+ scrolled_to_end?: boolean | undefined;
304
+ };
305
+ }[] | undefined;
191
306
  };
307
+ botToken?: string | undefined;
308
+ organisationName?: string | undefined;
192
309
  selectedServices?: string[] | undefined;
193
310
  }>;
194
311
  type SignupWirePayload = z.infer<typeof signupWireSchema>;
@@ -197,14 +314,22 @@ interface SignupSubmitBody {
197
314
  specVersion: string;
198
315
  answers: Record<string, unknown>;
199
316
  selectedServices?: string[];
317
+ /**
318
+ * D543 §4 consent. `documents` (the per-doc array) is authoritative when
319
+ * present; the booleans are the derived convenience. `documents` is omitted
320
+ * for a pre-ConsentPack onboarder (backward-compat).
321
+ */
200
322
  consent: {
201
323
  tosAccepted: true;
202
324
  privacyAccepted: true;
325
+ documents?: ConsentSubmitDocument[];
203
326
  };
204
327
  credentials: {
205
328
  email: string;
206
- password: string;
329
+ displayName?: string;
207
330
  };
331
+ organisationName?: string;
332
+ subdomain: string;
208
333
  }
209
334
  interface SignupSubmitOptions {
210
335
  baseUrl: string;
@@ -214,7 +339,7 @@ interface SignupSubmitOptions {
214
339
  * string on a retried request risks 403 after the first attempt consumed
215
340
  * it — pass a provider for retry-safe recovery.
216
341
  */
217
- botToken: BotTokenSource;
342
+ botToken?: BotTokenSource;
218
343
  /** Stable idempotency key — same discipline as submitLead. */
219
344
  idempotencyKey: string;
220
345
  fetch?: typeof globalThis.fetch;
@@ -247,13 +372,21 @@ declare function computeSignupFingerprint(body: SignupSubmitBody): string;
247
372
  * throws (reCAPTCHA unreachable) on any attempt
248
373
  * @throws {OnboardingSpecStaleError} on 409 with code:"spec_stale" (caller
249
374
  * refetches spec); carries the server's currentSpecVersion
250
- * @throws {OnboardingConflictError} on a 409 that is NOT spec_stale
375
+ * @throws {OnboardingConsentStaleError} on 409 with code:"consent_stale"
376
+ * (D543 §4 — a required legal doc changed; caller refetches spec + requires
377
+ * re-acceptance of the changed docs, NEVER auto-accepts); carries
378
+ * staleDocuments
379
+ * @throws {OnboardingConsentIncompleteError} on 400 with
380
+ * code:"consent_incomplete" (D543 §4 — server found a required doc missing/
381
+ * unaccepted/evidence-insufficient)
382
+ * @throws {OnboardingConflictError} on a 409 that is NOT spec_stale/consent_stale
251
383
  * @throws {OnboardingRateLimitError} on 429
252
- * @throws {OnboardingValidationError} on 422 (server re-validation)
384
+ * @throws {OnboardingValidationError} on 422 (server re-validation) or a
385
+ * generic 400 that is NOT consent_incomplete
253
386
  * @throws {OnboardingServerError} on 5xx after retries, or a 2xx without
254
387
  * the required {accepted:true, terminalStage} body
255
388
  * @throws {OnboardingNetworkError} on network failure OR timeout after retries
256
389
  */
257
390
  declare function submitSignup(body: SignupSubmitBody, options: SignupSubmitOptions): Promise<SignupSubmitResult>;
258
391
 
259
- export { type BotTokenSource as B, type LeadsSubmitOptions as L, type SignupSubmitBody as S, type LeadsSubmitResult as a, type SignupSubmitOptions as b, type SignupSubmitResult as c, type SignupWirePayload as d, computePayloadFingerprint as e, computeSignupFingerprint as f, generateIdempotencyKey as g, submitLead as h, submitSignup as i, resolveBotToken as r, signupWireSchema as s };
392
+ export { type BotTokenSource as B, type LeadsSubmitOptions as L, type SignupSubmitBody as S, type LeadsSubmitResult as a, type SignupSubmitOptions as b, type SignupSubmitResult as c, type SignupWirePayload as d, computePayloadFingerprint as e, computeSignupFingerprint as f, consentSubmitDocumentSchema as g, generateIdempotencyKey as h, submitLead as i, submitSignup as j, resolveBotToken as r, signupWireSchema as s };
@@ -1,88 +1,17 @@
1
- import { a as OnboardingSpec } from '../model-IEyDI54w.js';
2
- export { F as FIELD_KEY_PATTERN, O as OnboarderTier, P as PiiClass, S as SpecField, b as SpecStage, c as SpecStep, T as TerminalStage, o as onboardingSpecSchema, s as specFieldSchema, d as specStepSchema, v as validateOnboardingSpec } from '../model-IEyDI54w.js';
1
+ export { F as FIELD_KEY_PATTERN, O as OnboarderTier, a as OnboardingSpec, P as PiiClass, S as SpecField, b as SpecStage, c as SpecStep, T as TerminalStage, o as onboardingSpecSchema, s as specFieldSchema, d as specStepSchema, v as validateOnboardingSpec } from '../model-ESLSEbi0.js';
2
+ export { A as ACCEPTANCE_LEVELS, a as AcceptanceLevel, C as ConsentDocType, b as ConsentDocument, c as ConsentPack, D as DOC_TYPES, d as acceptanceLevelSchema, e as consentDocKey, f as consentDocumentSchema, g as consentPackSchema } from '../model-mnjAEtKe.js';
3
+ export { O as OnboardingSpecCache, S as SpecFetchOptions, a as SpecFieldDiff, d as defaultSpecCache, b as diffSpecFields, f as fetchOnboardingSpec } from '../client-CqE2dF9A.js';
3
4
  import 'zod/v3';
4
5
 
5
- /**
6
- * Config-fetch client for GET /api/v1/public/onboarding/spec (D540 §1/§3).
7
- *
8
- * - The onboarder is derived SERVER-side from the request Host (D536) —
9
- * it is NOT sent by the client. The `onboarder` value here is purely the
10
- * CLIENT-side cache key (D540 §3: "cache key (onboarder, specVersion)").
11
- * - The spec response is validated against the LOCKED D540 shape before
12
- * it is returned; a malformed spec throws OnboardingSpecInvalidError.
13
- * - Cache semantics: every successful fetch is stored under
14
- * (onboarder, specVersion) and as the onboarder's "latest". The versioned
15
- * entries let the 409 spec_stale flow diff the previously-served version
16
- * against the refetched one (see `diffSpecFields` + the signup widget's
17
- * handleSpecStale, which reads the cached prior version before refetching).
18
- */
19
-
20
- /**
21
- * In-memory spec cache keyed by (onboarder, specVersion), with a "latest"
22
- * pointer per onboarder. Purely client-side; no TTL — the reject-stale
23
- * policy (409 spec_stale on submit) is the authoritative staleness signal,
24
- * and a refetch overwrites "latest".
25
- */
26
- declare class OnboardingSpecCache {
27
- private readonly byVersion;
28
- private readonly latest;
29
- /**
30
- * Collision-proof composite key. Uses JSON.stringify of the tuple so an
31
- * onboarder or version containing the delimiter can never alias another
32
- * entry — and, critically, contains NO control characters (an earlier
33
- * NUL-separator made git treat this whole file as binary/undiffable).
34
- */
35
- private static versionKey;
36
- get(onboarder: string, specVersion: string): OnboardingSpec | undefined;
37
- getLatest(onboarder: string): OnboardingSpec | undefined;
38
- set(onboarder: string, spec: OnboardingSpec): void;
39
- clear(): void;
40
- }
41
- /** Module-level default cache (one per page). Injectable for tests/apps. */
42
- declare const defaultSpecCache: OnboardingSpecCache;
43
- /**
44
- * Diff two spec versions' signup field sets — used by the 409 spec_stale
45
- * flow to tell the user WHAT changed. Compares by field key across all
46
- * signup steps.
47
- */
48
- interface SpecFieldDiff {
49
- added: string[];
50
- removed: string[];
51
- changed: string[];
6
+ interface PinStateResult {
7
+ pin: string;
8
+ stateIso: string | null;
52
9
  }
53
- declare function diffSpecFields(prev: OnboardingSpec, next: OnboardingSpec): SpecFieldDiff;
54
- interface SpecFetchOptions {
10
+ declare function fetchPinState(options: {
55
11
  baseUrl: string;
56
- /**
57
- * Client-side cache key ONLY (never transmitted; trust is host-derived
58
- * per D536). Use the onboarder slug/id your embed is configured with.
59
- */
60
- onboarder: string;
61
- /** Custom fetch implementation (defaults to globalThis.fetch). */
12
+ pin: string;
62
13
  fetch?: typeof globalThis.fetch;
63
- /** Cache to read/write (defaults to the module-level cache). */
64
- cache?: OnboardingSpecCache;
65
- /**
66
- * Request timeout in ms (default 15s). A stalled intake aborts with
67
- * OnboardingNetworkError so the boot doesn't hang on "Loading signup form…".
68
- */
69
14
  timeoutMs?: number;
70
- /**
71
- * When true, return the cached "latest" for this onboarder if present
72
- * WITHOUT a network round-trip. Default false (spec fetches are cheap
73
- * and the server bumps specVersion on any change). The signup widget's
74
- * boot passes preferCached:true so a remount reuses the loaded spec.
75
- */
76
- preferCached?: boolean;
77
- }
78
- /**
79
- * Fetch (and validate, and cache) the onboarding spec.
80
- *
81
- * @throws {OnboardingSpecInvalidError} response does not match D540 §1
82
- * @throws {OnboardingRateLimitError} on 429
83
- * @throws {OnboardingServerError} on any other non-2xx status
84
- * @throws {OnboardingNetworkError} on network failure OR timeout
85
- */
86
- declare function fetchOnboardingSpec(options: SpecFetchOptions): Promise<OnboardingSpec>;
15
+ }): Promise<PinStateResult>;
87
16
 
88
- export { OnboardingSpec, OnboardingSpecCache, type SpecFetchOptions, type SpecFieldDiff, defaultSpecCache, diffSpecFields, fetchOnboardingSpec };
17
+ export { type PinStateResult, fetchPinState };
@@ -1,4 +1,5 @@
1
- export { FIELD_KEY_PATTERN, OnboardingSpecCache, defaultSpecCache, diffSpecFields, fetchOnboardingSpec, onboardingSpecSchema, specFieldSchema, specStepSchema, validateOnboardingSpec } from '../chunk-34BQX2KR.js';
2
- import '../chunk-AW7W3HAC.js';
1
+ export { FIELD_KEY_PATTERN, OnboardingSpecCache, defaultSpecCache, diffSpecFields, fetchOnboardingSpec, fetchPinState, onboardingSpecSchema, specFieldSchema, specStepSchema, validateOnboardingSpec } from '../chunk-F75ZJERM.js';
2
+ export { ACCEPTANCE_LEVELS, DOC_TYPES, acceptanceLevelSchema, consentDocKey, consentDocumentSchema, consentPackSchema } from '../chunk-U56GQITG.js';
3
+ import '../chunk-XJTJPBJB.js';
3
4
  //# sourceMappingURL=index.js.map
4
5
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,10 @@
1
- export { B as BotTokenSource, L as LeadsSubmitOptions, a as LeadsSubmitResult, S as SignupSubmitBody, b as SignupSubmitOptions, c as SignupSubmitResult, d as SignupWirePayload, e as computePayloadFingerprint, f as computeSignupFingerprint, g as generateIdempotencyKey, r as resolveBotToken, s as signupWireSchema, h as submitLead, i as submitSignup } from '../signup-client-Bl6eUrxR.js';
1
+ export { B as BotTokenSource, L as LeadsSubmitOptions, a as LeadsSubmitResult, S as SignupSubmitBody, b as SignupSubmitOptions, c as SignupSubmitResult, d as SignupWirePayload, e as computePayloadFingerprint, f as computeSignupFingerprint, g as consentSubmitDocumentSchema, h as generateIdempotencyKey, r as resolveBotToken, s as signupWireSchema, i as submitLead, j as submitSignup } from '../signup-client-BL5DfarJ.js';
2
+ export { O as OnboardingBotChallengeError, a as OnboardingConflictError, b as OnboardingConsentIncompleteError, c as OnboardingConsentStaleError, d as OnboardingError, e as OnboardingErrorKind, f as OnboardingNetworkError, g as OnboardingRateLimitError, h as OnboardingServerError, i as OnboardingSpecInvalidError, j as OnboardingSpecStaleError, k as OnboardingSubdomainTakenError, l as OnboardingValidationError, S as StaleConsentDocument } from '../errors-vJkye4a0.js';
2
3
  import 'zod/v3';
3
- import '../model-IEyDI54w.js';
4
- import '../schema-TfyBU6JW.js';
4
+ import '../model-ESLSEbi0.js';
5
+ import '../controller-BQb62D0N.js';
6
+ import '../model-mnjAEtKe.js';
7
+ import '../schema-BrXb9gnh.js';
5
8
 
6
9
  /**
7
10
  * Shared HTTP helper: fetch bounded by a timeout via AbortController.
@@ -36,71 +39,4 @@ declare function fetchWithTimeout(url: string, options?: TimeoutFetchOptions): P
36
39
  */
37
40
  declare function withTimeout<T>(op: Promise<T>, timeoutMs: number, onTimeout: () => Error): Promise<T>;
38
41
 
39
- /**
40
- * Error taxonomy for the onboarding submit client.
41
- *
42
- * Maps HTTP status codes and server error bodies to typed errors:
43
- * 403 bot_challenge_failed → OnboardingBotChallengeError
44
- * 409 spec_stale (SUBMIT) → OnboardingSpecStaleError (submit endpoint only,
45
- * body { error:true, code:"spec_stale",
46
- * currentSpecVersion })
47
- * 409 (other / LEADS) → OnboardingConflictError (generic conflict)
48
- * 429 → OnboardingRateLimitError
49
- * 5xx → OnboardingServerError (retryable)
50
- * network / timeout → OnboardingNetworkError
51
- */
52
- type OnboardingErrorKind = "bot_challenge_failed" | "spec_stale" | "spec_invalid" | "conflict" | "rate_limited" | "server_error" | "network_error" | "validation_error";
53
- declare class OnboardingError extends Error {
54
- readonly kind: OnboardingErrorKind;
55
- readonly statusCode: number | null;
56
- constructor(kind: OnboardingErrorKind, message: string, statusCode?: number | null);
57
- }
58
- declare class OnboardingBotChallengeError extends OnboardingError {
59
- constructor(message?: string);
60
- }
61
- /**
62
- * A 409 that is NOT spec_stale. On the /leads path there is no spec_stale
63
- * concept (the payload carries no specVersion); on /submit, a 409 that
64
- * lacks `code:"spec_stale"` also lands here. Distinct from
65
- * OnboardingSpecStaleError so headless consumers switching on `kind` get the
66
- * correct diagnosis (a generic conflict, e.g. a D538 same-key concurrent
67
- * race) rather than a "form has been updated, refresh" recovery message.
68
- */
69
- declare class OnboardingConflictError extends OnboardingError {
70
- constructor(statusCode?: number, message?: string);
71
- }
72
- declare class OnboardingRateLimitError extends OnboardingError {
73
- readonly retryAfterSeconds: number | null;
74
- constructor(retryAfterSeconds?: number | null);
75
- }
76
- /**
77
- * A /submit 409 whose body carries `code:"spec_stale"` (D540 reject-stale).
78
- * The PINNED body shape (confirmed against the crm intake) is exactly:
79
- * { error: true, code: "spec_stale", currentSpecVersion: string }
80
- * The version is read ONLY from `currentSpecVersion` — no field hedging.
81
- * Submit-endpoint only; /leads 409s are OnboardingConflictError.
82
- */
83
- declare class OnboardingSpecStaleError extends OnboardingError {
84
- readonly currentSpecVersion: string;
85
- constructor(currentSpecVersion: string);
86
- }
87
- declare class OnboardingServerError extends OnboardingError {
88
- constructor(statusCode: number, message?: string);
89
- }
90
- declare class OnboardingNetworkError extends OnboardingError {
91
- constructor(cause?: unknown);
92
- }
93
- declare class OnboardingValidationError extends OnboardingError {
94
- constructor(message: string);
95
- }
96
- /**
97
- * The spec endpoint returned a body that does not conform to the LOCKED
98
- * D540 §1 response shape. This is a server-side contract violation — the
99
- * SDK refuses to render a form from a malformed spec (a half-parsed spec
100
- * could silently drop required fields).
101
- */
102
- declare class OnboardingSpecInvalidError extends OnboardingError {
103
- constructor(detail: string);
104
- }
105
-
106
- export { DEFAULT_REQUEST_TIMEOUT_MS, OnboardingBotChallengeError, OnboardingConflictError, OnboardingError, type OnboardingErrorKind, OnboardingNetworkError, OnboardingRateLimitError, OnboardingServerError, OnboardingSpecInvalidError, OnboardingSpecStaleError, OnboardingValidationError, fetchWithTimeout, withTimeout };
42
+ export { DEFAULT_REQUEST_TIMEOUT_MS, fetchWithTimeout, withTimeout };
@@ -1,6 +1,6 @@
1
1
  import '../chunk-Z4PA6C2Z.js';
2
- export { computePayloadFingerprint, computeSignupFingerprint, generateIdempotencyKey, resolveBotToken, signupWireSchema, submitLead, submitSignup } from '../chunk-BQCTDU5V.js';
3
- import '../chunk-BIFANV7M.js';
4
- export { DEFAULT_REQUEST_TIMEOUT_MS, OnboardingBotChallengeError, OnboardingConflictError, OnboardingError, OnboardingNetworkError, OnboardingRateLimitError, OnboardingServerError, OnboardingSpecInvalidError, OnboardingSpecStaleError, OnboardingValidationError, fetchWithTimeout, withTimeout } from '../chunk-AW7W3HAC.js';
2
+ export { computePayloadFingerprint, computeSignupFingerprint, consentSubmitDocumentSchema, generateIdempotencyKey, resolveBotToken, signupWireSchema, submitLead, submitSignup } from '../chunk-BMQINH6O.js';
3
+ import '../chunk-SIMLMQPT.js';
4
+ export { DEFAULT_REQUEST_TIMEOUT_MS, OnboardingBotChallengeError, OnboardingConflictError, OnboardingConsentIncompleteError, OnboardingConsentStaleError, OnboardingError, OnboardingNetworkError, OnboardingRateLimitError, OnboardingServerError, OnboardingSpecInvalidError, OnboardingSpecStaleError, OnboardingSubdomainTakenError, OnboardingValidationError, fetchWithTimeout, withTimeout } from '../chunk-XJTJPBJB.js';
5
5
  //# sourceMappingURL=index.js.map
6
6
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,4 @@
1
+ export { C as ConsentDocumentViewerOptions, a as ConsentDocumentViewerResult, b as _resetPdfWorkerState, r as renderConsentDocument } from '../index-Dqfa890U.js';
2
+ import '../controller-BQb62D0N.js';
3
+ import '../model-mnjAEtKe.js';
4
+ import 'zod/v3';
@@ -0,0 +1,5 @@
1
+ export { _resetPdfWorkerState, renderConsentDocument } from '../chunk-LVJM4CTG.js';
2
+ import '../chunk-SEKNVHD3.js';
3
+ import '../chunk-XJTJPBJB.js';
4
+ //# sourceMappingURL=index.js.map
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -1,8 +1,11 @@
1
- import { a as OnboardingSpec } from '../model-IEyDI54w.js';
2
- import { OnboardingSpecCache } from '../spec/index.js';
3
- import { c as SignupSubmitResult } from '../signup-client-Bl6eUrxR.js';
1
+ import { a as OnboardingSpec } from '../model-ESLSEbi0.js';
2
+ import { O as OnboardingSpecCache } from '../client-CqE2dF9A.js';
3
+ import { c as SignupSubmitResult } from '../signup-client-BL5DfarJ.js';
4
+ import { _ as ___viewer_render_js } from '../index-Dqfa890U.js';
5
+ import { C as ConsentController, c as ConsentState } from '../controller-BQb62D0N.js';
4
6
  import 'zod/v3';
5
- import '../schema-TfyBU6JW.js';
7
+ import '../schema-BrXb9gnh.js';
8
+ import '../model-mnjAEtKe.js';
6
9
 
7
10
  /**
8
11
  * Default vanilla-TS contact form widget.
@@ -40,7 +43,7 @@ interface ContactFormMountOptions {
40
43
  * reCAPTCHA v3 site key. Obtained from the spec endpoint (D540 §1)
41
44
  * or passed directly in Phase 1 before spec-fetch is wired.
42
45
  */
43
- siteKey: string;
46
+ siteKey?: string;
44
47
  /**
45
48
  * Which form to render. Phase 1 supports "contact" only.
46
49
  * Phase 2 will add "signup" (dynamic stepper from spec).
@@ -162,7 +165,7 @@ declare function mountSignupForm(host: HTMLElement, options: SignupFormMountOpti
162
165
  * The widget scopes all styles under `.nodii-onboarding-widget` to avoid
163
166
  * leaking into the host page.
164
167
  */
165
- declare const DEFAULT_WIDGET_CSS = "\n.nodii-onboarding-widget {\n --_font: var(--nodii-onboarding-font-family, system-ui, -apple-system, sans-serif);\n --_primary: var(--nodii-onboarding-primary-color, #2563eb);\n --_primary-hover: var(--nodii-onboarding-primary-hover, #1d4ed8);\n --_error: var(--nodii-onboarding-error-color, #dc2626);\n --_border: var(--nodii-onboarding-border-color, #d1d5db);\n --_input-bg: var(--nodii-onboarding-input-bg, #fff);\n --_label: var(--nodii-onboarding-label-color, #374151);\n --_radius: var(--nodii-onboarding-radius, 6px);\n --_spacing: var(--nodii-onboarding-spacing, 16px);\n\n font-family: var(--_font);\n box-sizing: border-box;\n}\n\n.nodii-onboarding-widget *,\n.nodii-onboarding-widget *::before,\n.nodii-onboarding-widget *::after {\n box-sizing: inherit;\n}\n\n.nodii-onboarding-field {\n display: flex;\n flex-direction: column;\n gap: calc(var(--_spacing) * 0.25);\n margin-bottom: var(--_spacing);\n}\n\n.nodii-onboarding-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--_label);\n}\n\n.nodii-onboarding-label.required::after {\n content: \" *\";\n color: var(--_error);\n}\n\n.nodii-onboarding-input,\n.nodii-onboarding-textarea {\n width: 100%;\n padding: calc(var(--_spacing) * 0.5) calc(var(--_spacing) * 0.75);\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n background: var(--_input-bg);\n font-family: var(--_font);\n font-size: 1rem;\n line-height: 1.5;\n outline: none;\n transition: border-color 0.15s ease;\n}\n\n.nodii-onboarding-input:focus,\n.nodii-onboarding-textarea:focus {\n border-color: var(--_primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--_primary) 20%, transparent);\n}\n\n.nodii-onboarding-input.has-error,\n.nodii-onboarding-textarea.has-error {\n border-color: var(--_error);\n}\n\n.nodii-onboarding-textarea {\n min-height: 100px;\n resize: vertical;\n}\n\n.nodii-onboarding-field-error {\n font-size: 0.75rem;\n color: var(--_error);\n margin-top: 2px;\n}\n\n.nodii-onboarding-server-error {\n padding: calc(var(--_spacing) * 0.75);\n border-radius: var(--_radius);\n background: color-mix(in srgb, var(--_error) 8%, transparent);\n border: 1px solid color-mix(in srgb, var(--_error) 30%, transparent);\n color: var(--_error);\n font-size: 0.875rem;\n margin-bottom: var(--_spacing);\n}\n\n.nodii-onboarding-success {\n padding: var(--_spacing);\n border-radius: var(--_radius);\n background: #f0fdf4;\n border: 1px solid #bbf7d0;\n color: #15803d;\n font-size: 0.9375rem;\n text-align: center;\n}\n\n.nodii-onboarding-submit-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n padding: calc(var(--_spacing) * 0.625) var(--_spacing);\n background: var(--_primary);\n color: #fff;\n border: none;\n border-radius: var(--_radius);\n font-family: var(--_font);\n font-size: 1rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.nodii-onboarding-submit-btn:hover:not(:disabled) {\n background: var(--_primary-hover);\n}\n\n.nodii-onboarding-submit-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.nodii-onboarding-spinner {\n display: inline-block;\n width: 1em;\n height: 1em;\n border: 2px solid rgba(255,255,255,0.4);\n border-top-color: #fff;\n border-radius: 50%;\n animation: nodii-spin 0.6s linear infinite;\n margin-right: 0.5em;\n}\n\n@keyframes nodii-spin {\n to { transform: rotate(360deg); }\n}\n\n.nodii-onboarding-recaptcha-notice {\n font-size: 0.7rem;\n color: #6b7280;\n margin-top: calc(var(--_spacing) * 0.5);\n text-align: center;\n}\n\n.nodii-onboarding-recaptcha-notice a {\n color: inherit;\n}\n\n/* \u2500\u2500 dynamic stepper (signup form) \u2500\u2500 */\n\n.nodii-onboarding-steps {\n display: flex;\n gap: calc(var(--_spacing) * 0.5);\n margin-bottom: var(--_spacing);\n}\n\n.nodii-onboarding-step-dot {\n flex: 1;\n height: 4px;\n border-radius: 2px;\n background: var(--_border);\n}\n\n.nodii-onboarding-step-dot.active {\n background: var(--_primary);\n}\n\n.nodii-onboarding-stage-title {\n font-size: 1.0625rem;\n font-weight: 600;\n color: var(--_label);\n margin: 0 0 var(--_spacing) 0;\n}\n\n.nodii-onboarding-nav {\n display: flex;\n gap: calc(var(--_spacing) * 0.5);\n margin-top: var(--_spacing);\n}\n\n.nodii-onboarding-back-btn {\n padding: calc(var(--_spacing) * 0.625) var(--_spacing);\n background: transparent;\n color: var(--_label);\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n font-family: var(--_font);\n font-size: 1rem;\n cursor: pointer;\n}\n\n.nodii-onboarding-stale-banner {\n padding: calc(var(--_spacing) * 0.75);\n border-radius: var(--_radius);\n background: #fffbeb;\n border: 1px solid #fcd34d;\n color: #92400e;\n font-size: 0.875rem;\n margin-bottom: var(--_spacing);\n}\n\n.nodii-onboarding-consent-row {\n display: flex;\n align-items: flex-start;\n gap: calc(var(--_spacing) * 0.5);\n margin-bottom: calc(var(--_spacing) * 0.5);\n font-size: 0.875rem;\n color: var(--_label);\n}\n\n.nodii-onboarding-consent-row input[type=\"checkbox\"] {\n margin-top: 3px;\n}\n\n.nodii-onboarding-account-section {\n border-top: 1px solid var(--_border);\n margin-top: var(--_spacing);\n padding-top: var(--_spacing);\n}\n\n.nodii-onboarding-loading {\n padding: var(--_spacing);\n text-align: center;\n color: var(--_label);\n}\n";
168
+ declare const DEFAULT_WIDGET_CSS = "\n.nodii-onboarding-widget {\n --_font: var(--nodii-onboarding-font-family, system-ui, -apple-system, sans-serif);\n --_primary: var(--nodii-onboarding-primary-color, #2563eb);\n --_primary-hover: var(--nodii-onboarding-primary-hover, #1d4ed8);\n --_error: var(--nodii-onboarding-error-color, #dc2626);\n --_border: var(--nodii-onboarding-border-color, #d1d5db);\n --_input-bg: var(--nodii-onboarding-input-bg, #fff);\n --_label: var(--nodii-onboarding-label-color, #374151);\n --_radius: var(--nodii-onboarding-radius, 6px);\n --_spacing: var(--nodii-onboarding-spacing, 16px);\n\n font-family: var(--_font);\n box-sizing: border-box;\n}\n\n.nodii-onboarding-widget *,\n.nodii-onboarding-widget *::before,\n.nodii-onboarding-widget *::after {\n box-sizing: inherit;\n}\n\n.nodii-onboarding-field {\n display: flex;\n flex-direction: column;\n gap: calc(var(--_spacing) * 0.25);\n margin-bottom: var(--_spacing);\n}\n\n.nodii-onboarding-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--_label);\n}\n\n.nodii-onboarding-label.required::after {\n content: \" *\";\n color: var(--_error);\n}\n\n.nodii-onboarding-input,\n.nodii-onboarding-textarea {\n width: 100%;\n padding: calc(var(--_spacing) * 0.5) calc(var(--_spacing) * 0.75);\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n background: var(--_input-bg);\n font-family: var(--_font);\n font-size: 1rem;\n line-height: 1.5;\n outline: none;\n transition: border-color 0.15s ease;\n}\n\n.nodii-onboarding-input:focus,\n.nodii-onboarding-textarea:focus {\n border-color: var(--_primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--_primary) 20%, transparent);\n}\n\n.nodii-onboarding-input.has-error,\n.nodii-onboarding-textarea.has-error {\n border-color: var(--_error);\n}\n\n.nodii-onboarding-textarea {\n min-height: 100px;\n resize: vertical;\n}\n\n.nodii-onboarding-field-error {\n font-size: 0.75rem;\n color: var(--_error);\n margin-top: 2px;\n}\n\n.nodii-onboarding-server-error {\n padding: calc(var(--_spacing) * 0.75);\n border-radius: var(--_radius);\n background: color-mix(in srgb, var(--_error) 8%, transparent);\n border: 1px solid color-mix(in srgb, var(--_error) 30%, transparent);\n color: var(--_error);\n font-size: 0.875rem;\n margin-bottom: var(--_spacing);\n}\n\n.nodii-onboarding-success {\n padding: var(--_spacing);\n border-radius: var(--_radius);\n background: #f0fdf4;\n border: 1px solid #bbf7d0;\n color: #15803d;\n font-size: 0.9375rem;\n text-align: center;\n}\n\n.nodii-onboarding-submit-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n padding: calc(var(--_spacing) * 0.625) var(--_spacing);\n background: var(--_primary);\n color: #fff;\n border: none;\n border-radius: var(--_radius);\n font-family: var(--_font);\n font-size: 1rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.nodii-onboarding-submit-btn:hover:not(:disabled) {\n background: var(--_primary-hover);\n}\n\n.nodii-onboarding-submit-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.nodii-onboarding-spinner {\n display: inline-block;\n width: 1em;\n height: 1em;\n border: 2px solid rgba(255,255,255,0.4);\n border-top-color: #fff;\n border-radius: 50%;\n animation: nodii-spin 0.6s linear infinite;\n margin-right: 0.5em;\n}\n\n@keyframes nodii-spin {\n to { transform: rotate(360deg); }\n}\n\n.nodii-onboarding-recaptcha-notice {\n font-size: 0.7rem;\n color: #6b7280;\n margin-top: calc(var(--_spacing) * 0.5);\n text-align: center;\n}\n\n.nodii-onboarding-recaptcha-notice a {\n color: inherit;\n}\n\n/* \u2500\u2500 dynamic stepper (signup form) \u2500\u2500 */\n\n.nodii-onboarding-steps {\n display: flex;\n gap: calc(var(--_spacing) * 0.5);\n margin-bottom: var(--_spacing);\n}\n\n.nodii-onboarding-step-dot {\n flex: 1;\n height: 4px;\n border-radius: 2px;\n background: var(--_border);\n}\n\n.nodii-onboarding-step-dot.active {\n background: var(--_primary);\n}\n\n.nodii-onboarding-stage-title {\n font-size: 1.0625rem;\n font-weight: 600;\n color: var(--_label);\n margin: 0 0 var(--_spacing) 0;\n}\n\n.nodii-onboarding-nav {\n display: flex;\n gap: calc(var(--_spacing) * 0.5);\n margin-top: var(--_spacing);\n}\n\n.nodii-onboarding-back-btn {\n padding: calc(var(--_spacing) * 0.625) var(--_spacing);\n background: transparent;\n color: var(--_label);\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n font-family: var(--_font);\n font-size: 1rem;\n cursor: pointer;\n}\n\n.nodii-onboarding-stale-banner {\n padding: calc(var(--_spacing) * 0.75);\n border-radius: var(--_radius);\n background: #fffbeb;\n border: 1px solid #fcd34d;\n color: #92400e;\n font-size: 0.875rem;\n margin-bottom: var(--_spacing);\n}\n\n.nodii-onboarding-consent-row {\n display: flex;\n align-items: flex-start;\n gap: calc(var(--_spacing) * 0.5);\n margin-bottom: calc(var(--_spacing) * 0.5);\n font-size: 0.875rem;\n color: var(--_label);\n}\n\n.nodii-onboarding-consent-row input[type=\"checkbox\"] {\n margin-top: 3px;\n}\n\n.nodii-onboarding-account-section {\n border-top: 1px solid var(--_border);\n margin-top: var(--_spacing);\n padding-top: var(--_spacing);\n}\n\n.nodii-onboarding-loading {\n padding: var(--_spacing);\n text-align: center;\n color: var(--_label);\n}\n\n/* \u2500\u2500 D543 ConsentPack step (full-width, generous spacing) \u2500\u2500 */\n\n.nodii-onboarding-consent-stage {\n /* Full-bleed within the widget host \u2014 consent cards may span the page. */\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: calc(var(--_spacing) * 2);\n margin: calc(var(--_spacing) * 1.5) 0;\n}\n\n.nodii-onboarding-consent-intro {\n font-size: 0.9375rem;\n color: var(--_label);\n margin: 0 0 calc(var(--_spacing) * 0.5) 0;\n line-height: 1.6;\n}\n\n.nodii-onboarding-consent-card {\n width: 100%;\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n background: var(--_input-bg);\n padding: calc(var(--_spacing) * 1.5);\n display: flex;\n flex-direction: column;\n gap: var(--_spacing);\n}\n\n.nodii-onboarding-consent-card.is-stale {\n border-color: #fcd34d;\n background: #fffbeb;\n}\n\n.nodii-onboarding-consent-card.has-error {\n border-color: var(--_error);\n}\n\n.nodii-onboarding-consent-title {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--_label);\n margin: 0;\n}\n\n.nodii-onboarding-consent-stale-tag {\n font-size: 0.8125rem;\n font-weight: 500;\n color: #92400e;\n}\n\n.nodii-onboarding-consent-gate {\n width: 100%;\n}\n\n.nodii-onboarding-consent-scrollbox {\n width: 100%;\n height: 360px;\n overflow-y: auto;\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n background: #fff;\n position: relative;\n}\n\n.nodii-onboarding-consent-scrollbox:focus {\n outline: none;\n border-color: var(--_primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--_primary) 20%, transparent);\n}\n\n/* Inline, same-origin document content (no iframe). Rendered by the default\n viewer: sanitized HTML/markdown, escaped plain text, or PDF.js canvases. */\n.nodii-onboarding-consent-doc-body {\n padding: var(--_spacing);\n font-size: 0.9375rem;\n line-height: 1.7;\n color: var(--_label);\n word-break: break-word;\n}\n\n.nodii-onboarding-consent-doc-body:not(.nodii-consent-pdf) {\n white-space: pre-wrap;\n}\n\n.nodii-onboarding-consent-doc-loading {\n padding: var(--_spacing);\n color: #6b7280;\n font-size: 0.875rem;\n}\n\n.nodii-consent-pdf {\n display: flex;\n flex-direction: column;\n gap: var(--_spacing);\n white-space: normal;\n}\n\n.nodii-consent-pdf-page {\n max-width: 100%;\n height: auto;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);\n}\n\n.nodii-onboarding-consent-note {\n font-size: 0.8125rem;\n color: #6b7280;\n margin: calc(var(--_spacing) * 0.5) 0 0 0;\n}\n\n/* A gated doc that could not be rendered inline: the gate stays unsatisfiable\n (accept disabled); we surface a clear error + Retry. NO click-to-satisfy. */\n.nodii-onboarding-consent-unrenderable {\n display: flex;\n flex-direction: column;\n gap: calc(var(--_spacing) * 0.5);\n padding: var(--_spacing);\n border: 1px solid color-mix(in srgb, var(--_error) 30%, transparent);\n border-radius: var(--_radius);\n background: color-mix(in srgb, var(--_error) 6%, transparent);\n}\n\n.nodii-onboarding-consent-retry {\n align-self: flex-start;\n padding: calc(var(--_spacing) * 0.5) var(--_spacing);\n background: transparent;\n color: var(--_primary);\n border: 1px solid var(--_primary);\n border-radius: var(--_radius);\n font-family: var(--_font);\n font-size: 0.875rem;\n cursor: pointer;\n}\n\n.nodii-onboarding-consent-open-row,\n.nodii-onboarding-consent-preview-row {\n display: flex;\n}\n\n.nodii-onboarding-consent-open {\n display: inline-flex;\n align-items: center;\n padding: calc(var(--_spacing) * 0.625) var(--_spacing);\n border: 1px solid var(--_primary);\n border-radius: var(--_radius);\n color: var(--_primary);\n text-decoration: none;\n font-size: 0.9375rem;\n font-weight: 500;\n}\n\n.nodii-onboarding-consent-open:hover {\n background: color-mix(in srgb, var(--_primary) 8%, transparent);\n}\n\n.nodii-onboarding-consent-preview {\n font-size: 0.875rem;\n color: var(--_primary);\n}\n\n.nodii-onboarding-consent-accept-row {\n display: flex;\n align-items: flex-start;\n gap: calc(var(--_spacing) * 0.5);\n}\n\n.nodii-onboarding-consent-accept {\n margin-top: 3px;\n width: 1.125rem;\n height: 1.125rem;\n}\n\n.nodii-onboarding-consent-accept:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.nodii-onboarding-consent-accept-label {\n font-size: 0.9375rem;\n color: var(--_label);\n line-height: 1.5;\n}\n\n.nodii-onboarding-consent-required {\n color: var(--_error);\n}\n";
166
169
  /**
167
170
  * Inject the default widget CSS once into the document head.
168
171
  * Idempotent — will not add a duplicate style tag.
@@ -189,6 +192,46 @@ declare function cssEscape(value: string): string;
189
192
  /** Build a safe `#id` selector with the id CSS-escaped. */
190
193
  declare function idSelector(id: string): string;
191
194
 
195
+ /** Render-time options for the default consent step. */
196
+ interface ConsentStepRenderOptions {
197
+ /** Injectable fetch for doc-content load (defaults to global). */
198
+ fetch?: typeof globalThis.fetch;
199
+ timeoutMs?: number;
200
+ /**
201
+ * Injectable viewer-module importer (defaults to the real dynamic
202
+ * `import("../viewer/render.js")`). Exposed so a consumer can control code-
203
+ * splitting AND so tests can drive the module-load-FAILURE branch WITHOUT
204
+ * `mock.module` (which leaks across bun tests). Must resolve to an object
205
+ * exposing `renderConsentDocument`; rejecting simulates a chunk-load failure.
206
+ */
207
+ importViewer?: () => Promise<typeof ___viewer_render_js>;
208
+ }
209
+ /**
210
+ * Turn a consent doc's stable key into a DOM-id-safe token. `doc_type` is a
211
+ * fixed enum (safe); a custom key arrives as `custom:<key>` — the `:` and any
212
+ * residual metachar are replaced so the raw token is valid inside an id AND
213
+ * inside a `#id` selector. (The key is already `[A-Za-z0-9_-]+` past the `:`
214
+ * per model.ts; this only neutralizes the `custom:` prefix separator.)
215
+ */
216
+ declare function consentDocElementId(key: string): string;
217
+ /**
218
+ * Render (or re-render) the consent stage into a host container from the given
219
+ * consent state. Full re-render (the doc set is small); disabled/checked/error
220
+ * state is refreshed in place via updateConsentStep so scroll position and
221
+ * inline doc content are not lost on unrelated state changes.
222
+ */
223
+ declare function renderConsentStep(host: HTMLElement, control: ConsentController, state: ConsentState, staleKeys?: string[], opts?: ConsentStepRenderOptions): void;
224
+ /**
225
+ * Refresh the consent cards' disabled/checked/error state in place (no full
226
+ * re-render) — called on every stepper state change so gate unlocks and
227
+ * live-clearing errors reflect immediately without losing scroll position or
228
+ * re-fetching inline doc content.
229
+ */
230
+ declare function updateConsentStep(host: HTMLElement, state: ConsentState, consentErrors: Array<{
231
+ path: string;
232
+ message: string;
233
+ }>): void;
234
+
192
235
  type WidgetMountOptions = ContactFormMountOptions | SignupFormMountOptions;
193
236
  declare const OnboardingWidget: {
194
237
  /**
@@ -216,4 +259,4 @@ declare const OnboardingWidget: {
216
259
  readonly mount: (el: HTMLElement, options: WidgetMountOptions) => MountedWidget;
217
260
  };
218
261
 
219
- export { type ContactFormMountOptions, DEFAULT_WIDGET_CSS, type MountedWidget, OnboardingWidget, type SignupFormMountOptions, type WidgetMountOptions, cssEscape, idSelector, injectWidgetStyles, mountContactForm, mountSignupForm };
262
+ export { type ConsentStepRenderOptions, type ContactFormMountOptions, DEFAULT_WIDGET_CSS, type MountedWidget, OnboardingWidget, type SignupFormMountOptions, type WidgetMountOptions, consentDocElementId, cssEscape, idSelector, injectWidgetStyles, mountContactForm, mountSignupForm, renderConsentStep, updateConsentStep };
@@ -1,10 +1,12 @@
1
- export { DEFAULT_WIDGET_CSS, OnboardingWidget, cssEscape, idSelector, injectWidgetStyles, mountContactForm, mountSignupForm } from '../chunk-SWMIIUXR.js';
2
- import '../chunk-AFCJLUPK.js';
3
- import '../chunk-34BQX2KR.js';
4
- import '../chunk-4SWOVHZ2.js';
5
- import '../chunk-BQCTDU5V.js';
6
- import '../chunk-BIFANV7M.js';
7
- import '../chunk-AW7W3HAC.js';
1
+ export { DEFAULT_WIDGET_CSS, OnboardingWidget, consentDocElementId, cssEscape, idSelector, injectWidgetStyles, mountContactForm, mountSignupForm, renderConsentStep, updateConsentStep } from '../chunk-IPAKPLIF.js';
2
+ import '../chunk-U6AXKGYQ.js';
3
+ import '../chunk-F75ZJERM.js';
4
+ import '../chunk-KQTS47FC.js';
5
+ import '../chunk-AZE3NPSY.js';
6
+ import '../chunk-U56GQITG.js';
7
+ import '../chunk-BMQINH6O.js';
8
+ import '../chunk-SIMLMQPT.js';
9
+ import '../chunk-XJTJPBJB.js';
8
10
  import '../chunk-7NS7ENJV.js';
9
11
  //# sourceMappingURL=index.js.map
10
12
  //# sourceMappingURL=index.js.map