@funnelsgrove/runtime 0.1.56 → 0.1.59

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 (54) hide show
  1. package/dist/components/FunnelContext.d.ts +5 -1
  2. package/dist/components/FunnelContext.js +2 -1
  3. package/dist/components/ManageSubscriptionScreen.js +4 -1
  4. package/dist/components/SubscriptionHandoffScreen.d.ts +2 -1
  5. package/dist/components/SubscriptionHandoffScreen.js +11 -6
  6. package/dist/config/funnel.manifest.types.d.ts +4 -2
  7. package/dist/generated/step-contract-hash.d.ts +1 -0
  8. package/dist/generated/step-contract-hash.js +2 -0
  9. package/dist/index.d.ts +12 -0
  10. package/dist/index.js +10 -0
  11. package/dist/migrations/step-contract-v2.d.ts +50 -0
  12. package/dist/migrations/step-contract-v2.js +310 -0
  13. package/dist/migrations/step-contract-v3.d.ts +41 -0
  14. package/dist/migrations/step-contract-v3.js +26 -0
  15. package/dist/runtime/funnel-manifest.validation.d.ts +7 -2
  16. package/dist/runtime/funnel-manifest.validation.js +24 -68
  17. package/dist/runtime/funnel-step-lifecycle.d.ts +35 -0
  18. package/dist/runtime/funnel-step-lifecycle.js +49 -0
  19. package/dist/runtime/funnel-step-metadata.validation.d.ts +7 -0
  20. package/dist/runtime/funnel-step-metadata.validation.js +88 -0
  21. package/dist/runtime/submit-email-capture.d.ts +23 -0
  22. package/dist/runtime/submit-email-capture.js +54 -0
  23. package/dist/runtime/use-funnel-flow-controller.d.ts +58 -5
  24. package/dist/runtime/use-funnel-flow-controller.js +804 -122
  25. package/dist/runtime/use-step-choices.d.ts +58 -0
  26. package/dist/runtime/use-step-choices.js +187 -0
  27. package/dist/sdk/userAnswers.d.ts +1 -0
  28. package/dist/services/api.service.d.ts +10 -0
  29. package/dist/services/api.service.js +32 -0
  30. package/dist/services/funnel-sdk.service.d.ts +17 -0
  31. package/dist/services/funnel-sdk.service.js +13 -0
  32. package/dist/steps/choice-contract.d.ts +33 -0
  33. package/dist/steps/choice-contract.js +302 -0
  34. package/dist/steps/step-contract.d.ts +498 -0
  35. package/dist/steps/step-contract.js +506 -0
  36. package/dist/steps/types.d.ts +7 -5
  37. package/dist/steps/types.js +1 -18
  38. package/dist/testing/funnel-contract-journey-driver.d.ts +35 -0
  39. package/dist/testing/funnel-contract-journey-driver.js +266 -0
  40. package/dist/testing/index.d.ts +1 -0
  41. package/dist/testing/index.js +1 -0
  42. package/dist/validation/fixtures/invalid-reserved-identities.d.ts +249 -0
  43. package/dist/validation/fixtures/invalid-reserved-identities.js +20 -0
  44. package/dist/validation/fixtures/valid-v2-project.d.ts +419 -0
  45. package/dist/validation/fixtures/valid-v2-project.js +228 -0
  46. package/dist/validation/fixtures/valid-v3-project.d.ts +419 -0
  47. package/dist/validation/fixtures/valid-v3-project.js +30 -0
  48. package/dist/validation/funnel-contract-diagnostics.d.ts +49 -0
  49. package/dist/validation/funnel-contract-diagnostics.js +67 -0
  50. package/dist/validation/funnel-contract-validator.d.ts +30 -0
  51. package/dist/validation/funnel-contract-validator.js +1458 -0
  52. package/dist/validation/funnel-manifest-input.normalization.d.ts +67 -0
  53. package/dist/validation/funnel-manifest-input.normalization.js +386 -0
  54. package/package.json +9 -1
@@ -0,0 +1,419 @@
1
+ export declare const validV2ProjectManifest: {
2
+ readonly templateArchitectureVersion: 1;
3
+ readonly stepContractVersion: 2;
4
+ readonly meta: {
5
+ readonly title: "Contract fixture";
6
+ readonly description: "A valid version 2 funnel contract fixture.";
7
+ };
8
+ readonly viewport: {
9
+ readonly width: 390;
10
+ readonly height: 844;
11
+ };
12
+ readonly assets: {};
13
+ readonly steps: readonly [{
14
+ readonly id: "step-1";
15
+ readonly name: "step-one";
16
+ readonly path: "/step-1";
17
+ readonly filePath: "src/steps/step-01.tsx";
18
+ readonly componentKey: "stepOne";
19
+ readonly type: "intro_hero";
20
+ readonly title: "Introduction";
21
+ }, {
22
+ readonly id: "step-2";
23
+ readonly name: "device-choice";
24
+ readonly path: "/step-2";
25
+ readonly filePath: "src/steps/step-02.tsx";
26
+ readonly componentKey: "stepTwo";
27
+ readonly type: "multi_select_choice";
28
+ readonly choice: {
29
+ readonly answerKey: "selectedDevices";
30
+ readonly allowEmpty: true;
31
+ };
32
+ readonly title: "Choose devices";
33
+ }, {
34
+ readonly id: "email-capture";
35
+ readonly name: "email-capture";
36
+ readonly path: "/email-capture";
37
+ readonly filePath: "src/steps/step-31-email-capture.tsx";
38
+ readonly componentKey: "stepEmailCapture";
39
+ readonly type: "form_input";
40
+ readonly title: "Email capture";
41
+ }, {
42
+ readonly id: "paywall";
43
+ readonly name: "paywall";
44
+ readonly path: "/paywall";
45
+ readonly filePath: "src/steps/step-32-paywall.tsx";
46
+ readonly componentKey: "stepPaywall";
47
+ readonly type: "paywall_offer";
48
+ readonly kind: "paywall";
49
+ readonly title: "Paywall";
50
+ }, {
51
+ readonly id: "paywall-b";
52
+ readonly name: "paywall-b";
53
+ readonly path: "/paywall-b";
54
+ readonly filePath: "src/steps/step-32b-paywall-b.tsx";
55
+ readonly componentKey: "stepPaywallB";
56
+ readonly type: "paywall_offer";
57
+ readonly kind: "paywall";
58
+ readonly title: "Paywall B";
59
+ }, {
60
+ readonly id: "subscription-started";
61
+ readonly name: "subscription-started";
62
+ readonly path: "/subscription-started";
63
+ readonly filePath: "src/steps/step-33-subscription-started.tsx";
64
+ readonly componentKey: "stepSubscriptionStarted";
65
+ readonly type: "complete_registration";
66
+ readonly kind: "subscription-handoff";
67
+ readonly title: "Subscription started";
68
+ }, {
69
+ readonly id: "manage-subscription";
70
+ readonly name: "manage-subscription";
71
+ readonly path: "/manage-subscription";
72
+ readonly filePath: "src/steps/step-35-manage-subscription.tsx";
73
+ readonly componentKey: "stepManageSubscription";
74
+ readonly type: "subscription_management";
75
+ readonly kind: "manage-subscription";
76
+ readonly title: "Manage subscription";
77
+ }];
78
+ readonly entryPoints: readonly [{
79
+ readonly id: "default";
80
+ readonly stepId: "step-1";
81
+ readonly isDefault: true;
82
+ }, {
83
+ readonly id: "manage-subscription";
84
+ readonly stepId: "manage-subscription";
85
+ }];
86
+ readonly edgesByStepId: {
87
+ readonly 'step-1': readonly [{
88
+ readonly toStepId: "step-2";
89
+ }];
90
+ readonly 'step-2': readonly [{
91
+ readonly toStepId: "email-capture";
92
+ }];
93
+ readonly 'email-capture': readonly [{
94
+ readonly toStepId: "paywall";
95
+ }];
96
+ readonly paywall: readonly [{
97
+ readonly toStepId: "subscription-started";
98
+ }];
99
+ readonly 'paywall-b': readonly [{
100
+ readonly toStepId: "subscription-started";
101
+ }];
102
+ };
103
+ readonly branches: readonly [{
104
+ readonly id: "device-owners";
105
+ readonly name: "Device owners";
106
+ readonly sourceStepId: "step-2";
107
+ readonly stepIds: readonly ["email-capture", "paywall"];
108
+ }];
109
+ readonly experiments: readonly [{
110
+ readonly experimentId: "paywall-offer";
111
+ readonly stepId: "paywall";
112
+ readonly variants: readonly [{
113
+ readonly variantKey: "control";
114
+ readonly routeToStepId: "paywall";
115
+ }, {
116
+ readonly variantKey: "variant-b";
117
+ readonly routeToStepId: "paywall-b";
118
+ }];
119
+ }];
120
+ };
121
+ export declare const validV2ProjectComponentMetaByKey: {
122
+ readonly stepOne: {
123
+ readonly id: "step-1";
124
+ readonly name: "step-one";
125
+ readonly type: "intro_hero";
126
+ readonly figmaNodeId: "fixture:step-1";
127
+ readonly title: "Introduction";
128
+ readonly description: "Introduce the funnel.";
129
+ };
130
+ readonly stepTwo: {
131
+ readonly id: "step-2";
132
+ readonly name: "device-choice";
133
+ readonly type: "multi_select_choice";
134
+ readonly choice: {
135
+ readonly answerKey: "selectedDevices";
136
+ readonly allowEmpty: true;
137
+ };
138
+ readonly figmaNodeId: "fixture:step-2";
139
+ readonly title: "Choose devices";
140
+ readonly description: "Choose every device that applies.";
141
+ };
142
+ readonly stepEmailCapture: {
143
+ readonly id: "email-capture";
144
+ readonly name: "email-capture";
145
+ readonly type: "form_input";
146
+ readonly figmaNodeId: "fixture:email-capture";
147
+ readonly title: "Email capture";
148
+ readonly description: "Capture an email address.";
149
+ };
150
+ readonly stepPaywall: {
151
+ readonly id: "paywall";
152
+ readonly name: "paywall";
153
+ readonly type: "paywall_offer";
154
+ readonly kind: "paywall";
155
+ readonly figmaNodeId: "fixture:paywall";
156
+ readonly title: "Paywall";
157
+ readonly description: "Present the primary offer.";
158
+ };
159
+ readonly stepPaywallB: {
160
+ readonly id: "paywall-b";
161
+ readonly name: "paywall-b";
162
+ readonly type: "paywall_offer";
163
+ readonly kind: "paywall";
164
+ readonly figmaNodeId: "fixture:paywall-b";
165
+ readonly title: "Paywall B";
166
+ readonly description: "Present the alternate offer.";
167
+ };
168
+ readonly stepSubscriptionStarted: {
169
+ readonly id: "subscription-started";
170
+ readonly name: "subscription-started";
171
+ readonly type: "complete_registration";
172
+ readonly kind: "subscription-handoff";
173
+ readonly figmaNodeId: "fixture:subscription-started";
174
+ readonly title: "Subscription started";
175
+ readonly description: "Complete the funnel after subscription handoff.";
176
+ };
177
+ readonly stepManageSubscription: {
178
+ readonly id: "manage-subscription";
179
+ readonly name: "manage-subscription";
180
+ readonly type: "subscription_management";
181
+ readonly kind: "manage-subscription";
182
+ readonly figmaNodeId: "fixture:manage-subscription";
183
+ readonly title: "Manage subscription";
184
+ readonly description: "Manage the active subscription.";
185
+ };
186
+ };
187
+ export declare const validV2ProjectSnapshot: {
188
+ readonly manifest: {
189
+ readonly templateArchitectureVersion: 1;
190
+ readonly stepContractVersion: 2;
191
+ readonly meta: {
192
+ readonly title: "Contract fixture";
193
+ readonly description: "A valid version 2 funnel contract fixture.";
194
+ };
195
+ readonly viewport: {
196
+ readonly width: 390;
197
+ readonly height: 844;
198
+ };
199
+ readonly assets: {};
200
+ readonly steps: readonly [{
201
+ readonly id: "step-1";
202
+ readonly name: "step-one";
203
+ readonly path: "/step-1";
204
+ readonly filePath: "src/steps/step-01.tsx";
205
+ readonly componentKey: "stepOne";
206
+ readonly type: "intro_hero";
207
+ readonly title: "Introduction";
208
+ }, {
209
+ readonly id: "step-2";
210
+ readonly name: "device-choice";
211
+ readonly path: "/step-2";
212
+ readonly filePath: "src/steps/step-02.tsx";
213
+ readonly componentKey: "stepTwo";
214
+ readonly type: "multi_select_choice";
215
+ readonly choice: {
216
+ readonly answerKey: "selectedDevices";
217
+ readonly allowEmpty: true;
218
+ };
219
+ readonly title: "Choose devices";
220
+ }, {
221
+ readonly id: "email-capture";
222
+ readonly name: "email-capture";
223
+ readonly path: "/email-capture";
224
+ readonly filePath: "src/steps/step-31-email-capture.tsx";
225
+ readonly componentKey: "stepEmailCapture";
226
+ readonly type: "form_input";
227
+ readonly title: "Email capture";
228
+ }, {
229
+ readonly id: "paywall";
230
+ readonly name: "paywall";
231
+ readonly path: "/paywall";
232
+ readonly filePath: "src/steps/step-32-paywall.tsx";
233
+ readonly componentKey: "stepPaywall";
234
+ readonly type: "paywall_offer";
235
+ readonly kind: "paywall";
236
+ readonly title: "Paywall";
237
+ }, {
238
+ readonly id: "paywall-b";
239
+ readonly name: "paywall-b";
240
+ readonly path: "/paywall-b";
241
+ readonly filePath: "src/steps/step-32b-paywall-b.tsx";
242
+ readonly componentKey: "stepPaywallB";
243
+ readonly type: "paywall_offer";
244
+ readonly kind: "paywall";
245
+ readonly title: "Paywall B";
246
+ }, {
247
+ readonly id: "subscription-started";
248
+ readonly name: "subscription-started";
249
+ readonly path: "/subscription-started";
250
+ readonly filePath: "src/steps/step-33-subscription-started.tsx";
251
+ readonly componentKey: "stepSubscriptionStarted";
252
+ readonly type: "complete_registration";
253
+ readonly kind: "subscription-handoff";
254
+ readonly title: "Subscription started";
255
+ }, {
256
+ readonly id: "manage-subscription";
257
+ readonly name: "manage-subscription";
258
+ readonly path: "/manage-subscription";
259
+ readonly filePath: "src/steps/step-35-manage-subscription.tsx";
260
+ readonly componentKey: "stepManageSubscription";
261
+ readonly type: "subscription_management";
262
+ readonly kind: "manage-subscription";
263
+ readonly title: "Manage subscription";
264
+ }];
265
+ readonly entryPoints: readonly [{
266
+ readonly id: "default";
267
+ readonly stepId: "step-1";
268
+ readonly isDefault: true;
269
+ }, {
270
+ readonly id: "manage-subscription";
271
+ readonly stepId: "manage-subscription";
272
+ }];
273
+ readonly edgesByStepId: {
274
+ readonly 'step-1': readonly [{
275
+ readonly toStepId: "step-2";
276
+ }];
277
+ readonly 'step-2': readonly [{
278
+ readonly toStepId: "email-capture";
279
+ }];
280
+ readonly 'email-capture': readonly [{
281
+ readonly toStepId: "paywall";
282
+ }];
283
+ readonly paywall: readonly [{
284
+ readonly toStepId: "subscription-started";
285
+ }];
286
+ readonly 'paywall-b': readonly [{
287
+ readonly toStepId: "subscription-started";
288
+ }];
289
+ };
290
+ readonly branches: readonly [{
291
+ readonly id: "device-owners";
292
+ readonly name: "Device owners";
293
+ readonly sourceStepId: "step-2";
294
+ readonly stepIds: readonly ["email-capture", "paywall"];
295
+ }];
296
+ readonly experiments: readonly [{
297
+ readonly experimentId: "paywall-offer";
298
+ readonly stepId: "paywall";
299
+ readonly variants: readonly [{
300
+ readonly variantKey: "control";
301
+ readonly routeToStepId: "paywall";
302
+ }, {
303
+ readonly variantKey: "variant-b";
304
+ readonly routeToStepId: "paywall-b";
305
+ }];
306
+ }];
307
+ };
308
+ readonly componentMetaByKey: {
309
+ readonly stepOne: {
310
+ readonly id: "step-1";
311
+ readonly name: "step-one";
312
+ readonly type: "intro_hero";
313
+ readonly figmaNodeId: "fixture:step-1";
314
+ readonly title: "Introduction";
315
+ readonly description: "Introduce the funnel.";
316
+ };
317
+ readonly stepTwo: {
318
+ readonly id: "step-2";
319
+ readonly name: "device-choice";
320
+ readonly type: "multi_select_choice";
321
+ readonly choice: {
322
+ readonly answerKey: "selectedDevices";
323
+ readonly allowEmpty: true;
324
+ };
325
+ readonly figmaNodeId: "fixture:step-2";
326
+ readonly title: "Choose devices";
327
+ readonly description: "Choose every device that applies.";
328
+ };
329
+ readonly stepEmailCapture: {
330
+ readonly id: "email-capture";
331
+ readonly name: "email-capture";
332
+ readonly type: "form_input";
333
+ readonly figmaNodeId: "fixture:email-capture";
334
+ readonly title: "Email capture";
335
+ readonly description: "Capture an email address.";
336
+ };
337
+ readonly stepPaywall: {
338
+ readonly id: "paywall";
339
+ readonly name: "paywall";
340
+ readonly type: "paywall_offer";
341
+ readonly kind: "paywall";
342
+ readonly figmaNodeId: "fixture:paywall";
343
+ readonly title: "Paywall";
344
+ readonly description: "Present the primary offer.";
345
+ };
346
+ readonly stepPaywallB: {
347
+ readonly id: "paywall-b";
348
+ readonly name: "paywall-b";
349
+ readonly type: "paywall_offer";
350
+ readonly kind: "paywall";
351
+ readonly figmaNodeId: "fixture:paywall-b";
352
+ readonly title: "Paywall B";
353
+ readonly description: "Present the alternate offer.";
354
+ };
355
+ readonly stepSubscriptionStarted: {
356
+ readonly id: "subscription-started";
357
+ readonly name: "subscription-started";
358
+ readonly type: "complete_registration";
359
+ readonly kind: "subscription-handoff";
360
+ readonly figmaNodeId: "fixture:subscription-started";
361
+ readonly title: "Subscription started";
362
+ readonly description: "Complete the funnel after subscription handoff.";
363
+ };
364
+ readonly stepManageSubscription: {
365
+ readonly id: "manage-subscription";
366
+ readonly name: "manage-subscription";
367
+ readonly type: "subscription_management";
368
+ readonly kind: "manage-subscription";
369
+ readonly figmaNodeId: "fixture:manage-subscription";
370
+ readonly title: "Manage subscription";
371
+ readonly description: "Manage the active subscription.";
372
+ };
373
+ };
374
+ readonly registeredComponentKeys: readonly ["stepOne", "stepTwo", "stepEmailCapture", "stepPaywall", "stepPaywallB", "stepSubscriptionStarted", "stepManageSubscription"];
375
+ readonly contentOptionsByStepId: {
376
+ readonly 'step-2': readonly [{
377
+ readonly id: "phone";
378
+ readonly label: "Phone";
379
+ readonly imageSrc: "/images/phone.png";
380
+ }];
381
+ };
382
+ readonly edgesByStepId: {
383
+ readonly 'step-1': readonly [{
384
+ readonly toStepId: "step-2";
385
+ }];
386
+ readonly 'step-2': readonly [{
387
+ readonly toStepId: "email-capture";
388
+ }];
389
+ readonly 'email-capture': readonly [{
390
+ readonly toStepId: "paywall";
391
+ }];
392
+ readonly paywall: readonly [{
393
+ readonly toStepId: "subscription-started";
394
+ }];
395
+ readonly 'paywall-b': readonly [{
396
+ readonly toStepId: "subscription-started";
397
+ }];
398
+ };
399
+ readonly experiments: readonly [{
400
+ readonly experimentId: "paywall-offer";
401
+ readonly stepId: "paywall";
402
+ readonly variants: readonly [{
403
+ readonly variantKey: "control";
404
+ readonly routeToStepId: "paywall";
405
+ }, {
406
+ readonly variantKey: "variant-b";
407
+ readonly routeToStepId: "paywall-b";
408
+ }];
409
+ }];
410
+ readonly docs: {
411
+ readonly schemaVersion: 1;
412
+ readonly bundleVersion: "2.0.0";
413
+ readonly stepContractVersion: 2;
414
+ readonly contractHash: "d761e91d5ac6ff9e72c6d49c5bcd014270912473a66f99c49d726c65998085cf";
415
+ readonly missing: readonly [];
416
+ readonly changed: readonly [];
417
+ readonly conflicts: readonly [];
418
+ };
419
+ };
@@ -0,0 +1,228 @@
1
+ import { CURRENT_STEP_CONTRACT_HASH } from '../../generated/step-contract-hash.js';
2
+ export const validV2ProjectManifest = {
3
+ templateArchitectureVersion: 1,
4
+ stepContractVersion: 2,
5
+ meta: {
6
+ title: 'Contract fixture',
7
+ description: 'A valid version 2 funnel contract fixture.',
8
+ },
9
+ viewport: {
10
+ width: 390,
11
+ height: 844,
12
+ },
13
+ assets: {},
14
+ steps: [
15
+ {
16
+ id: 'step-1',
17
+ name: 'step-one',
18
+ path: '/step-1',
19
+ filePath: 'src/steps/step-01.tsx',
20
+ componentKey: 'stepOne',
21
+ type: 'intro_hero',
22
+ title: 'Introduction',
23
+ },
24
+ {
25
+ id: 'step-2',
26
+ name: 'device-choice',
27
+ path: '/step-2',
28
+ filePath: 'src/steps/step-02.tsx',
29
+ componentKey: 'stepTwo',
30
+ type: 'multi_select_choice',
31
+ choice: {
32
+ answerKey: 'selectedDevices',
33
+ allowEmpty: true,
34
+ },
35
+ title: 'Choose devices',
36
+ },
37
+ {
38
+ id: 'email-capture',
39
+ name: 'email-capture',
40
+ path: '/email-capture',
41
+ filePath: 'src/steps/step-31-email-capture.tsx',
42
+ componentKey: 'stepEmailCapture',
43
+ type: 'form_input',
44
+ title: 'Email capture',
45
+ },
46
+ {
47
+ id: 'paywall',
48
+ name: 'paywall',
49
+ path: '/paywall',
50
+ filePath: 'src/steps/step-32-paywall.tsx',
51
+ componentKey: 'stepPaywall',
52
+ type: 'paywall_offer',
53
+ kind: 'paywall',
54
+ title: 'Paywall',
55
+ },
56
+ {
57
+ id: 'paywall-b',
58
+ name: 'paywall-b',
59
+ path: '/paywall-b',
60
+ filePath: 'src/steps/step-32b-paywall-b.tsx',
61
+ componentKey: 'stepPaywallB',
62
+ type: 'paywall_offer',
63
+ kind: 'paywall',
64
+ title: 'Paywall B',
65
+ },
66
+ {
67
+ id: 'subscription-started',
68
+ name: 'subscription-started',
69
+ path: '/subscription-started',
70
+ filePath: 'src/steps/step-33-subscription-started.tsx',
71
+ componentKey: 'stepSubscriptionStarted',
72
+ type: 'complete_registration',
73
+ kind: 'subscription-handoff',
74
+ title: 'Subscription started',
75
+ },
76
+ {
77
+ id: 'manage-subscription',
78
+ name: 'manage-subscription',
79
+ path: '/manage-subscription',
80
+ filePath: 'src/steps/step-35-manage-subscription.tsx',
81
+ componentKey: 'stepManageSubscription',
82
+ type: 'subscription_management',
83
+ kind: 'manage-subscription',
84
+ title: 'Manage subscription',
85
+ },
86
+ ],
87
+ entryPoints: [
88
+ {
89
+ id: 'default',
90
+ stepId: 'step-1',
91
+ isDefault: true,
92
+ },
93
+ {
94
+ id: 'manage-subscription',
95
+ stepId: 'manage-subscription',
96
+ },
97
+ ],
98
+ edgesByStepId: {
99
+ 'step-1': [{ toStepId: 'step-2' }],
100
+ 'step-2': [{ toStepId: 'email-capture' }],
101
+ 'email-capture': [{ toStepId: 'paywall' }],
102
+ paywall: [{ toStepId: 'subscription-started' }],
103
+ 'paywall-b': [{ toStepId: 'subscription-started' }],
104
+ },
105
+ branches: [
106
+ {
107
+ id: 'device-owners',
108
+ name: 'Device owners',
109
+ sourceStepId: 'step-2',
110
+ stepIds: ['email-capture', 'paywall'],
111
+ },
112
+ ],
113
+ experiments: [
114
+ {
115
+ experimentId: 'paywall-offer',
116
+ stepId: 'paywall',
117
+ variants: [
118
+ {
119
+ variantKey: 'control',
120
+ routeToStepId: 'paywall',
121
+ },
122
+ {
123
+ variantKey: 'variant-b',
124
+ routeToStepId: 'paywall-b',
125
+ },
126
+ ],
127
+ },
128
+ ],
129
+ };
130
+ export const validV2ProjectComponentMetaByKey = {
131
+ stepOne: {
132
+ id: 'step-1',
133
+ name: 'step-one',
134
+ type: 'intro_hero',
135
+ figmaNodeId: 'fixture:step-1',
136
+ title: 'Introduction',
137
+ description: 'Introduce the funnel.',
138
+ },
139
+ stepTwo: {
140
+ id: 'step-2',
141
+ name: 'device-choice',
142
+ type: 'multi_select_choice',
143
+ choice: {
144
+ answerKey: 'selectedDevices',
145
+ allowEmpty: true,
146
+ },
147
+ figmaNodeId: 'fixture:step-2',
148
+ title: 'Choose devices',
149
+ description: 'Choose every device that applies.',
150
+ },
151
+ stepEmailCapture: {
152
+ id: 'email-capture',
153
+ name: 'email-capture',
154
+ type: 'form_input',
155
+ figmaNodeId: 'fixture:email-capture',
156
+ title: 'Email capture',
157
+ description: 'Capture an email address.',
158
+ },
159
+ stepPaywall: {
160
+ id: 'paywall',
161
+ name: 'paywall',
162
+ type: 'paywall_offer',
163
+ kind: 'paywall',
164
+ figmaNodeId: 'fixture:paywall',
165
+ title: 'Paywall',
166
+ description: 'Present the primary offer.',
167
+ },
168
+ stepPaywallB: {
169
+ id: 'paywall-b',
170
+ name: 'paywall-b',
171
+ type: 'paywall_offer',
172
+ kind: 'paywall',
173
+ figmaNodeId: 'fixture:paywall-b',
174
+ title: 'Paywall B',
175
+ description: 'Present the alternate offer.',
176
+ },
177
+ stepSubscriptionStarted: {
178
+ id: 'subscription-started',
179
+ name: 'subscription-started',
180
+ type: 'complete_registration',
181
+ kind: 'subscription-handoff',
182
+ figmaNodeId: 'fixture:subscription-started',
183
+ title: 'Subscription started',
184
+ description: 'Complete the funnel after subscription handoff.',
185
+ },
186
+ stepManageSubscription: {
187
+ id: 'manage-subscription',
188
+ name: 'manage-subscription',
189
+ type: 'subscription_management',
190
+ kind: 'manage-subscription',
191
+ figmaNodeId: 'fixture:manage-subscription',
192
+ title: 'Manage subscription',
193
+ description: 'Manage the active subscription.',
194
+ },
195
+ };
196
+ export const validV2ProjectSnapshot = {
197
+ manifest: validV2ProjectManifest,
198
+ componentMetaByKey: validV2ProjectComponentMetaByKey,
199
+ registeredComponentKeys: [
200
+ 'stepOne',
201
+ 'stepTwo',
202
+ 'stepEmailCapture',
203
+ 'stepPaywall',
204
+ 'stepPaywallB',
205
+ 'stepSubscriptionStarted',
206
+ 'stepManageSubscription',
207
+ ],
208
+ contentOptionsByStepId: {
209
+ 'step-2': [
210
+ {
211
+ id: 'phone',
212
+ label: 'Phone',
213
+ imageSrc: '/images/phone.png',
214
+ },
215
+ ],
216
+ },
217
+ edgesByStepId: validV2ProjectManifest.edgesByStepId,
218
+ experiments: validV2ProjectManifest.experiments,
219
+ docs: {
220
+ schemaVersion: 1,
221
+ bundleVersion: '2.0.0',
222
+ stepContractVersion: 2,
223
+ contractHash: CURRENT_STEP_CONTRACT_HASH,
224
+ missing: [],
225
+ changed: [],
226
+ conflicts: [],
227
+ },
228
+ };