@appfunnel-dev/sdk 2.0.0-canary.0 → 2.0.0-canary.2

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 (43) hide show
  1. package/dist/capabilities-7_hy5f5G.d.cts +114 -0
  2. package/dist/capabilities-7_hy5f5G.d.ts +114 -0
  3. package/dist/checkout-CZmEvWfC.d.cts +317 -0
  4. package/dist/checkout-DiQvRT5q.d.ts +317 -0
  5. package/dist/chunk-7UC5VXOR.js +446 -0
  6. package/dist/chunk-7UC5VXOR.js.map +1 -0
  7. package/dist/chunk-LJYLGLFS.cjs +153 -0
  8. package/dist/chunk-LJYLGLFS.cjs.map +1 -0
  9. package/dist/chunk-UIR6TGEW.js +97 -0
  10. package/dist/chunk-UIR6TGEW.js.map +1 -0
  11. package/dist/chunk-VQOD2Z6Q.cjs +104 -0
  12. package/dist/chunk-VQOD2Z6Q.cjs.map +1 -0
  13. package/dist/chunk-YY375F2B.js +140 -0
  14. package/dist/chunk-YY375F2B.js.map +1 -0
  15. package/dist/chunk-Z3TWO2PW.cjs +475 -0
  16. package/dist/chunk-Z3TWO2PW.cjs.map +1 -0
  17. package/dist/driver-paddle.cjs +814 -0
  18. package/dist/driver-paddle.cjs.map +1 -0
  19. package/dist/driver-paddle.d.cts +10 -0
  20. package/dist/driver-paddle.d.ts +10 -0
  21. package/dist/driver-paddle.js +811 -0
  22. package/dist/driver-paddle.js.map +1 -0
  23. package/dist/driver-stripe.cjs +2253 -0
  24. package/dist/driver-stripe.cjs.map +1 -0
  25. package/dist/driver-stripe.d.cts +8 -0
  26. package/dist/driver-stripe.d.ts +8 -0
  27. package/dist/driver-stripe.js +2247 -0
  28. package/dist/driver-stripe.js.map +1 -0
  29. package/dist/index.cjs +1953 -813
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +183 -933
  32. package/dist/index.d.ts +183 -933
  33. package/dist/index.js +1674 -655
  34. package/dist/index.js.map +1 -1
  35. package/dist/manifest-DQThneiG.d.cts +777 -0
  36. package/dist/manifest-DQThneiG.d.ts +777 -0
  37. package/dist/manifest-entry.cjs +203 -0
  38. package/dist/manifest-entry.cjs.map +1 -0
  39. package/dist/manifest-entry.d.cts +184 -0
  40. package/dist/manifest-entry.d.ts +184 -0
  41. package/dist/manifest-entry.js +98 -0
  42. package/dist/manifest-entry.js.map +1 -0
  43. package/package.json +37 -4
@@ -0,0 +1,203 @@
1
+ 'use strict';
2
+
3
+ var chunkZ3TWO2PW_cjs = require('./chunk-Z3TWO2PW.cjs');
4
+ var chunkLJYLGLFS_cjs = require('./chunk-LJYLGLFS.cjs');
5
+
6
+ // src/flow/scaffold.ts
7
+ var DRIVERS = {
8
+ stripe: { name: "stripeCheckoutDriver", sub: "driver-stripe" },
9
+ paddle: { name: "paddleCheckoutDriver", sub: "driver-paddle" }
10
+ };
11
+ var HEADER = "// GENERATED by AppFunnel \u2014 do not edit. Built from funnel.ts + the pages/ folder.\n";
12
+ function generateMount(opts) {
13
+ const p = opts.importPrefix ?? "./";
14
+ const driver = opts.checkout ? DRIVERS[opts.checkout] : null;
15
+ const imports = [
16
+ `import { createFunnelTree, type MountOpts, type RuntimePage } from '@appfunnel-dev/sdk'`,
17
+ driver && `import { ${driver.name} } from '@appfunnel-dev/sdk/${driver.sub}'`,
18
+ `import { config } from '${p}funnel'`,
19
+ opts.hasLayout && `import Layout from '${p}layout'`
20
+ ].filter(Boolean).join("\n");
21
+ const loaders = opts.pageKeys.map(
22
+ (k) => ` ${JSON.stringify(k)}: () => import(${JSON.stringify(`${p}pages/${k}`)}),`
23
+ ).join("\n");
24
+ const treeArgs = [
25
+ "config",
26
+ "pages",
27
+ opts.hasLayout && "layout: Layout",
28
+ driver && `checkoutDriver: ${driver.name}`
29
+ ].filter(Boolean).join(", ");
30
+ return `${HEADER}${imports}
31
+
32
+ const loaders: Record<string, () => Promise<unknown>> = {
33
+ ${loaders}
34
+ }
35
+
36
+ // Flow pages come from funnel.ts (order + meta + routing). Any remaining page file is an off-flow
37
+ // \`@variant\` page (wired by experiment records at render time), appended so it's loadable.
38
+ const decls = config.pages ?? []
39
+ const flowKeys = new Set(decls.map((d) => d.key))
40
+ export const pages: RuntimePage[] = [
41
+ ...decls.map((d) => ({ key: d.key, meta: d, load: loaders[d.key] })),
42
+ ...Object.keys(loaders)
43
+ .filter((k) => !flowKeys.has(k))
44
+ .map((k) => ({ key: k, meta: {}, load: loaders[k] })),
45
+ ] as RuntimePage[]
46
+
47
+ export const tree = createFunnelTree({ ${treeArgs} })
48
+
49
+ export type { MountOpts }
50
+ `;
51
+ }
52
+ function generateEntryClient(opts) {
53
+ const p = opts.importPrefix ?? "./";
54
+ const styles = opts.hasStyles ? `import '${p}styles.css'
55
+ ` : "";
56
+ return `${HEADER}${styles}import { hydrateRoot } from 'react-dom/client'
57
+ import { tree, type MountOpts } from './mount'
58
+
59
+ const dataEl = document.getElementById('__af_data')
60
+ const data = (dataEl?.textContent ? JSON.parse(dataEl.textContent) : {}) as MountOpts & {
61
+ initialKey?: string | null
62
+ }
63
+ const root = document.getElementById('root')
64
+ if (root) hydrateRoot(root, tree({ ...data, initialKey: data.initialKey ?? undefined }))
65
+ `;
66
+ }
67
+ function generateEntryServer(opts) {
68
+ const p = opts.importPrefix ?? "./";
69
+ return `${HEADER}import { renderToReadableStream } from 'react-dom/server.browser'
70
+ import { compileManifest } from '@appfunnel-dev/sdk'
71
+ import { config } from '${p}funnel'
72
+ import { tree, pages, type MountOpts } from './mount'
73
+
74
+ export const manifest = compileManifest({
75
+ funnel: config,
76
+ pages: pages.map((pg) => ({ key: pg.key, meta: pg.meta })),
77
+ })
78
+
79
+ export async function ssr(opts: MountOpts): Promise<string> {
80
+ const stream = await renderToReadableStream(tree(opts))
81
+ await stream.allReady
82
+ return await new Response(stream).text()
83
+ }
84
+ `;
85
+ }
86
+ function generateDevEntry(opts) {
87
+ const p = opts.importPrefix ?? "./";
88
+ const styles = opts.hasStyles ? `import '${p}styles.css'
89
+ ` : "";
90
+ return `${HEADER}${styles}import { createRoot } from 'react-dom/client'
91
+ import { tree } from './mount'
92
+
93
+ const el = document.getElementById('root')
94
+ if (el) createRoot(el).render(tree(${JSON.stringify(opts.data)}))
95
+ `;
96
+ }
97
+
98
+ Object.defineProperty(exports, "assignVariant", {
99
+ enumerable: true,
100
+ get: function () { return chunkZ3TWO2PW_cjs.assignVariant; }
101
+ });
102
+ Object.defineProperty(exports, "bucketingSeed", {
103
+ enumerable: true,
104
+ get: function () { return chunkZ3TWO2PW_cjs.bucketingSeed; }
105
+ });
106
+ Object.defineProperty(exports, "buildCatalog", {
107
+ enumerable: true,
108
+ get: function () { return chunkZ3TWO2PW_cjs.buildCatalog; }
109
+ });
110
+ Object.defineProperty(exports, "compileManifest", {
111
+ enumerable: true,
112
+ get: function () { return chunkZ3TWO2PW_cjs.compileManifest; }
113
+ });
114
+ Object.defineProperty(exports, "currencyExponent", {
115
+ enumerable: true,
116
+ get: function () { return chunkZ3TWO2PW_cjs.currencyExponent; }
117
+ });
118
+ Object.defineProperty(exports, "defineFunnel", {
119
+ enumerable: true,
120
+ get: function () { return chunkZ3TWO2PW_cjs.defineFunnel; }
121
+ });
122
+ Object.defineProperty(exports, "formatMoney", {
123
+ enumerable: true,
124
+ get: function () { return chunkZ3TWO2PW_cjs.formatMoney; }
125
+ });
126
+ Object.defineProperty(exports, "formatProduct", {
127
+ enumerable: true,
128
+ get: function () { return chunkZ3TWO2PW_cjs.formatProduct; }
129
+ });
130
+ Object.defineProperty(exports, "isRtl", {
131
+ enumerable: true,
132
+ get: function () { return chunkZ3TWO2PW_cjs.isRtl; }
133
+ });
134
+ Object.defineProperty(exports, "isVariantKey", {
135
+ enumerable: true,
136
+ get: function () { return chunkZ3TWO2PW_cjs.isVariantKey; }
137
+ });
138
+ Object.defineProperty(exports, "pageMeta", {
139
+ enumerable: true,
140
+ get: function () { return chunkZ3TWO2PW_cjs.pageMeta; }
141
+ });
142
+ Object.defineProperty(exports, "parseSlotKey", {
143
+ enumerable: true,
144
+ get: function () { return chunkZ3TWO2PW_cjs.parseSlotKey; }
145
+ });
146
+ Object.defineProperty(exports, "resolveLocale", {
147
+ enumerable: true,
148
+ get: function () { return chunkZ3TWO2PW_cjs.resolveLocale; }
149
+ });
150
+ Object.defineProperty(exports, "resolveProduct", {
151
+ enumerable: true,
152
+ get: function () { return chunkZ3TWO2PW_cjs.resolveProduct; }
153
+ });
154
+ Object.defineProperty(exports, "validateExperiments", {
155
+ enumerable: true,
156
+ get: function () { return chunkZ3TWO2PW_cjs.validateExperiments; }
157
+ });
158
+ Object.defineProperty(exports, "weightsOf", {
159
+ enumerable: true,
160
+ get: function () { return chunkZ3TWO2PW_cjs.weightsOf; }
161
+ });
162
+ Object.defineProperty(exports, "INLINE_SURFACES", {
163
+ enumerable: true,
164
+ get: function () { return chunkLJYLGLFS_cjs.INLINE_SURFACES; }
165
+ });
166
+ Object.defineProperty(exports, "PROVIDER_PROFILES", {
167
+ enumerable: true,
168
+ get: function () { return chunkLJYLGLFS_cjs.PROVIDER_PROFILES; }
169
+ });
170
+ Object.defineProperty(exports, "checkoutError", {
171
+ enumerable: true,
172
+ get: function () { return chunkLJYLGLFS_cjs.checkoutError; }
173
+ });
174
+ Object.defineProperty(exports, "isInlineSurface", {
175
+ enumerable: true,
176
+ get: function () { return chunkLJYLGLFS_cjs.isInlineSurface; }
177
+ });
178
+ Object.defineProperty(exports, "isMerchantOfRecord", {
179
+ enumerable: true,
180
+ get: function () { return chunkLJYLGLFS_cjs.isMerchantOfRecord; }
181
+ });
182
+ Object.defineProperty(exports, "isOrchestrator", {
183
+ enumerable: true,
184
+ get: function () { return chunkLJYLGLFS_cjs.isOrchestrator; }
185
+ });
186
+ Object.defineProperty(exports, "surfacesFor", {
187
+ enumerable: true,
188
+ get: function () { return chunkLJYLGLFS_cjs.surfacesFor; }
189
+ });
190
+ Object.defineProperty(exports, "validateCheckout", {
191
+ enumerable: true,
192
+ get: function () { return chunkLJYLGLFS_cjs.validateCheckout; }
193
+ });
194
+ Object.defineProperty(exports, "validateUpsell", {
195
+ enumerable: true,
196
+ get: function () { return chunkLJYLGLFS_cjs.validateUpsell; }
197
+ });
198
+ exports.generateDevEntry = generateDevEntry;
199
+ exports.generateEntryClient = generateEntryClient;
200
+ exports.generateEntryServer = generateEntryServer;
201
+ exports.generateMount = generateMount;
202
+ //# sourceMappingURL=manifest-entry.cjs.map
203
+ //# sourceMappingURL=manifest-entry.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/flow/scaffold.ts"],"names":[],"mappings":"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","file":"manifest-entry.cjs","sourcesContent":["/**\n * Source generators for the funnel build \"machinery\" authors no longer write. `funnel.ts` (the\n * spine: id, responses, products, checkout, and the page list + declarative routing) plus the\n * `pages/` folder are the ONLY authored source. The build (renderer/builder) and the CLI dev server\n * call these to synthesize:\n * - `mount.tsx` — code-split page loaders + `createFunnelTree`\n * - `entry.client.tsx` — hydrate the SSR'd markup from injected data\n * - `entry.server.tsx` — `ssr()` + the compiled `manifest`\n *\n * All string templates, zero runtime deps — this module lives in the pure `@appfunnel-dev/sdk/\n * manifest` entry so tooling imports it without the funnel runtime.\n */\n\nexport interface ScaffoldOptions {\n\t/** Page component keys = `pages/<key>.tsx` filenames (base flow pages AND `@variant` pages). */\n\tpageKeys: string[]\n\t/** Import prefix to reach the funnel root: `'./'` at the root (build), `'../../'` in a subdir (CLI dev). */\n\timportPrefix?: string\n\t/** Whether a `layout.tsx` exists to wrap the pages. */\n\thasLayout?: boolean\n\t/** Whether a `styles.css` exists (client entry imports it). */\n\thasStyles?: boolean\n\t/** Checkout provider from `config.checkout` — wires the driver; omit for none. */\n\tcheckout?: 'stripe' | 'paddle' | null\n}\n\nconst DRIVERS = {\n\tstripe: { name: 'stripeCheckoutDriver', sub: 'driver-stripe' },\n\tpaddle: { name: 'paddleCheckoutDriver', sub: 'driver-paddle' },\n} as const\n\nconst HEADER = '// GENERATED by AppFunnel — do not edit. Built from funnel.ts + the pages/ folder.\\n'\n\n/** `mount.tsx` — the code-split loaders + tree, derived from `config.pages` and the `pages/` files. */\nexport function generateMount(opts: ScaffoldOptions): string {\n\tconst p = opts.importPrefix ?? './'\n\tconst driver = opts.checkout ? DRIVERS[opts.checkout] : null\n\n\tconst imports = [\n\t\t`import { createFunnelTree, type MountOpts, type RuntimePage } from '@appfunnel-dev/sdk'`,\n\t\tdriver && `import { ${driver.name} } from '@appfunnel-dev/sdk/${driver.sub}'`,\n\t\t`import { config } from '${p}funnel'`,\n\t\topts.hasLayout && `import Layout from '${p}layout'`,\n\t]\n\t\t.filter(Boolean)\n\t\t.join('\\n')\n\n\t// A static import() per page file so Vite emits one code-split chunk each.\n\tconst loaders = opts.pageKeys\n\t\t.map(\n\t\t\t(k) => `\\t${JSON.stringify(k)}: () => import(${JSON.stringify(`${p}pages/${k}`)}),`\n\t\t)\n\t\t.join('\\n')\n\n\tconst treeArgs = [\n\t\t'config',\n\t\t'pages',\n\t\topts.hasLayout && 'layout: Layout',\n\t\tdriver && `checkoutDriver: ${driver.name}`,\n\t]\n\t\t.filter(Boolean)\n\t\t.join(', ')\n\n\treturn `${HEADER}${imports}\n\nconst loaders: Record<string, () => Promise<unknown>> = {\n${loaders}\n}\n\n// Flow pages come from funnel.ts (order + meta + routing). Any remaining page file is an off-flow\n// \\`@variant\\` page (wired by experiment records at render time), appended so it's loadable.\nconst decls = config.pages ?? []\nconst flowKeys = new Set(decls.map((d) => d.key))\nexport const pages: RuntimePage[] = [\n\t...decls.map((d) => ({ key: d.key, meta: d, load: loaders[d.key] })),\n\t...Object.keys(loaders)\n\t\t.filter((k) => !flowKeys.has(k))\n\t\t.map((k) => ({ key: k, meta: {}, load: loaders[k] })),\n] as RuntimePage[]\n\nexport const tree = createFunnelTree({ ${treeArgs} })\n\nexport type { MountOpts }\n`\n}\n\n/** `entry.client.tsx` — hydrate the SSR'd markup from the injected `#__af_data`. */\nexport function generateEntryClient(opts: Pick<ScaffoldOptions, 'importPrefix' | 'hasStyles'>): string {\n\tconst p = opts.importPrefix ?? './'\n\tconst styles = opts.hasStyles ? `import '${p}styles.css'\\n` : ''\n\treturn `${HEADER}${styles}import { hydrateRoot } from 'react-dom/client'\nimport { tree, type MountOpts } from './mount'\n\nconst dataEl = document.getElementById('__af_data')\nconst data = (dataEl?.textContent ? JSON.parse(dataEl.textContent) : {}) as MountOpts & {\n\tinitialKey?: string | null\n}\nconst root = document.getElementById('root')\nif (root) hydrateRoot(root, tree({ ...data, initialKey: data.initialKey ?? undefined }))\n`\n}\n\n/** `entry.server.tsx` — `ssr(opts)` HTML + the compiled `manifest` (read by the build). */\nexport function generateEntryServer(opts: Pick<ScaffoldOptions, 'importPrefix'>): string {\n\tconst p = opts.importPrefix ?? './'\n\treturn `${HEADER}import { renderToReadableStream } from 'react-dom/server.browser'\nimport { compileManifest } from '@appfunnel-dev/sdk'\nimport { config } from '${p}funnel'\nimport { tree, pages, type MountOpts } from './mount'\n\nexport const manifest = compileManifest({\n\tfunnel: config,\n\tpages: pages.map((pg) => ({ key: pg.key, meta: pg.meta })),\n})\n\nexport async function ssr(opts: MountOpts): Promise<string> {\n\tconst stream = await renderToReadableStream(tree(opts))\n\tawait stream.allReady\n\treturn await new Response(stream).text()\n}\n`\n}\n\n/** Client-only dev entry (createRoot, no SSR) — for the CLI `dev` server. */\nexport function generateDevEntry(\n\topts: Pick<ScaffoldOptions, 'importPrefix' | 'hasStyles'> & { data: unknown }\n): string {\n\tconst p = opts.importPrefix ?? './'\n\tconst styles = opts.hasStyles ? `import '${p}styles.css'\\n` : ''\n\treturn `${HEADER}${styles}import { createRoot } from 'react-dom/client'\nimport { tree } from './mount'\n\nconst el = document.getElementById('root')\nif (el) createRoot(el).render(tree(${JSON.stringify(opts.data)}))\n`\n}\n"]}
@@ -0,0 +1,184 @@
1
+ export { i as CompileInput, j as Condition, k as ConditionOp, E as EdgeCondition, m as ExperimentIssue, o as ExperimentValidation, p as ExperimentVariant, q as FlowPage, c as FunnelDefinition, r as FunnelLocales, s as FunnelManifest, ai as FunnelPage, b as FunnelSnapshot, G as Gate, t as Interval, M as ManifestEdge, u as ManifestPage, v as ManifestValidation, w as Money, f as PageMeta, x as PageType, y as Predicate, P as Product, e as ProductInput, z as ResolvedProduct, H as Route, R as RuntimeExperiment, K as assignVariant, N as bucketingSeed, T as buildCatalog, W as compileManifest, X as currencyExponent, Y as defineFunnel, a3 as formatMoney, a4 as formatProduct, a6 as isRtl, a7 as isVariantKey, aa as pageMeta, ab as parseSlotKey, ae as resolveLocale, af as resolveProduct, ah as validateExperiments, aj as weightsOf } from './manifest-DQThneiG.cjs';
2
+ import { C as CheckoutError, b as CheckoutIntent, U as UpsellKind, d as CheckoutSurface } from './capabilities-7_hy5f5G.cjs';
3
+ export { a as CheckoutErrorCategory, c as CheckoutProvider, I as INLINE_SURFACES, O as OffSessionReliability, P as PROVIDER_PROFILES, e as ProviderProfile, S as SurfaceCapability, V as ValidationResult, f as checkoutError, i as isInlineSurface, g as isMerchantOfRecord, h as isOrchestrator, s as surfacesFor, v as validateCheckout, j as validateUpsell } from './capabilities-7_hy5f5G.cjs';
4
+ import 'react';
5
+
6
+ /**
7
+ * Source generators for the funnel build "machinery" authors no longer write. `funnel.ts` (the
8
+ * spine: id, responses, products, checkout, and the page list + declarative routing) plus the
9
+ * `pages/` folder are the ONLY authored source. The build (renderer/builder) and the CLI dev server
10
+ * call these to synthesize:
11
+ * - `mount.tsx` — code-split page loaders + `createFunnelTree`
12
+ * - `entry.client.tsx` — hydrate the SSR'd markup from injected data
13
+ * - `entry.server.tsx` — `ssr()` + the compiled `manifest`
14
+ *
15
+ * All string templates, zero runtime deps — this module lives in the pure `@appfunnel-dev/sdk/
16
+ * manifest` entry so tooling imports it without the funnel runtime.
17
+ */
18
+ interface ScaffoldOptions {
19
+ /** Page component keys = `pages/<key>.tsx` filenames (base flow pages AND `@variant` pages). */
20
+ pageKeys: string[];
21
+ /** Import prefix to reach the funnel root: `'./'` at the root (build), `'../../'` in a subdir (CLI dev). */
22
+ importPrefix?: string;
23
+ /** Whether a `layout.tsx` exists to wrap the pages. */
24
+ hasLayout?: boolean;
25
+ /** Whether a `styles.css` exists (client entry imports it). */
26
+ hasStyles?: boolean;
27
+ /** Checkout provider from `config.checkout` — wires the driver; omit for none. */
28
+ checkout?: 'stripe' | 'paddle' | null;
29
+ }
30
+ /** `mount.tsx` — the code-split loaders + tree, derived from `config.pages` and the `pages/` files. */
31
+ declare function generateMount(opts: ScaffoldOptions): string;
32
+ /** `entry.client.tsx` — hydrate the SSR'd markup from the injected `#__af_data`. */
33
+ declare function generateEntryClient(opts: Pick<ScaffoldOptions, 'importPrefix' | 'hasStyles'>): string;
34
+ /** `entry.server.tsx` — `ssr(opts)` HTML + the compiled `manifest` (read by the build). */
35
+ declare function generateEntryServer(opts: Pick<ScaffoldOptions, 'importPrefix'>): string;
36
+ /** Client-only dev entry (createRoot, no SSR) — for the CLI `dev` server. */
37
+ declare function generateDevEntry(opts: Pick<ScaffoldOptions, 'importPrefix' | 'hasStyles'> & {
38
+ data: unknown;
39
+ }): string;
40
+
41
+ /**
42
+ * The v2 checkout WIRE CONTRACT — the request/response types shared by the server
43
+ * services (apps/api, fresh per-flow checkout — v1 purchase.ts is frozen) and the
44
+ * client drivers (driver-stripe/driver-paddle). Both sides import THESE types from
45
+ * the pure manifest entry, so the contract cannot drift between them.
46
+ *
47
+ * Future-proofing rules (Wave-4, Simon 2026-07-02):
48
+ * - Responses discriminate on `step` (what the CLIENT must do next), NOT on the
49
+ * provider — a new provider reuses an existing step (`redirect`,
50
+ * `provider_checkout`) or adds one, without breaking existing drivers.
51
+ * - The server NEVER returns secret credentials — publishable/client tokens only;
52
+ * charges and verification happen server-side against the mode-resolved store.
53
+ * - `correlationId` is the client-minted idempotency key AND the correlation id
54
+ * the server writes into every provider object's metadata — one id links the
55
+ * trial fee to its subscription, the webhook to the funnel session, and the
56
+ * retry to the original attempt (kills v0's 5-minute-webhook-window linking).
57
+ * - Money facts settle SERVER-side: the browser only ever learns the outcome
58
+ * (`CheckoutSettlement`, with the server-minted `eventId` the pixel dedupes on).
59
+ */
60
+
61
+ /** `POST {apiBase}/campaign/{campaignId}/v2/checkout` — open a checkout attempt. */
62
+ interface CheckoutSessionRequest {
63
+ funnelId: string;
64
+ /** Render-time mode (doc 09 §2.4): resolves the product's binding + store credentials. */
65
+ mode: 'test' | 'live';
66
+ /** Logical catalog product key (`monthly`) — never a raw price id. */
67
+ productKey: string;
68
+ intent: CheckoutIntent;
69
+ /** For `upsell` — which off-session kind (validated against the capability matrix). */
70
+ kind?: UpsellKind;
71
+ /** The presenting surface; null/absent = off-session (upsell, no UI). */
72
+ surface?: CheckoutSurface | null;
73
+ /** Funnel session id (analytics + customer continuity), when one exists. */
74
+ sessionId?: string;
75
+ /** Signed-cookie-verified bare visitor id, when known. */
76
+ visitorId?: string;
77
+ /** Buyer email when the funnel collected it (Stripe Customer creation / receipts). */
78
+ email?: string;
79
+ /**
80
+ * Client-minted UUID. Idempotency key for this attempt (safe re-POST on network
81
+ * retry) and the correlation id stamped into provider-object metadata.
82
+ */
83
+ correlationId: string;
84
+ }
85
+ /** What the browser learned when the server settled the charge (or verified it). */
86
+ interface CheckoutSettlement {
87
+ ok: true;
88
+ /** Server-minted dedup id — the SDK emits `purchase.complete` with it (browser↔CAPI dedup). */
89
+ eventId: string;
90
+ amountMinor: number;
91
+ currency: string;
92
+ productKey: string;
93
+ }
94
+ /** Driver confirms in the browser with the provider's JS (Stripe Elements et al.). */
95
+ interface StepClientConfirm {
96
+ step: 'client_confirm';
97
+ provider: string;
98
+ publishableKey: string;
99
+ clientSecret: string;
100
+ /** Which secret this is — payment (charge now) vs setup (vault, e.g. free-trial start). */
101
+ secretKind: 'payment_intent' | 'setup_intent';
102
+ }
103
+ /** Driver mounts the provider-MANAGED inline checkout (Stripe Embedded). */
104
+ interface StepEmbedded {
105
+ step: 'embedded';
106
+ provider: string;
107
+ publishableKey: string;
108
+ clientSecret: string;
109
+ }
110
+ /** Driver navigates to the provider-hosted page (any provider's `redirect`). */
111
+ interface StepRedirect {
112
+ step: 'redirect';
113
+ provider: string;
114
+ url: string;
115
+ }
116
+ /**
117
+ * Driver opens the provider's own checkout UI (Paddle.js popup/inline, Whop later).
118
+ *
119
+ * WHAT the checkout opens is EXACTLY ONE of `items` | `transactionId`:
120
+ * - `items` — open a NEW checkout for these provider-native prices (the purchase shape;
121
+ * every response before 2026-07 carried this, so `items`-only stays valid unchanged);
122
+ * - `transactionId` — open the provider's checkout for an EXISTING server-created
123
+ * transaction (e.g. Paddle's payment-method-change transaction: the on-session
124
+ * re-collect leg of a failed off-session upgrade — `Checkout.open({ transactionId })`).
125
+ * A response carrying both or neither is malformed and the driver rejects it.
126
+ */
127
+ interface StepProviderCheckout {
128
+ step: 'provider_checkout';
129
+ provider: string;
130
+ /** Provider client token / publishable credential for its JS SDK. */
131
+ clientToken: string;
132
+ /** Provider environment the client SDK must target (Paddle sandbox vs production). */
133
+ providerEnvironment: 'sandbox' | 'production';
134
+ /** Provider-native line items (e.g. Paddle price ids), resolved from the binding. */
135
+ items?: {
136
+ priceId: string;
137
+ quantity: number;
138
+ }[];
139
+ /** Provider-side id of an EXISTING transaction to open (see the exactly-one rule above). */
140
+ transactionId?: string;
141
+ /**
142
+ * Echoed into the provider checkout's custom data (carries the correlationId) — `items`
143
+ * path only. A `transactionId` checkout already exists provider-side with its own custom
144
+ * data (Paddle: inherited from the subscription), so the driver does not send this.
145
+ */
146
+ customData: Record<string, string>;
147
+ }
148
+ /** The server completed the charge synchronously (off-session upsell). */
149
+ interface StepSettled {
150
+ step: 'settled';
151
+ result: CheckoutSettlement;
152
+ }
153
+ /** The attempt failed — normalized taxonomy, never a raw provider error. */
154
+ interface StepFailed {
155
+ step: 'failed';
156
+ error: CheckoutError;
157
+ }
158
+ /**
159
+ * The provider hasn't confirmed yet — the charge is in flight and will settle
160
+ * async (webhook). The driver polls `/complete` until `settled`/`failed`. On the
161
+ * OPEN response this is the Paddle off-session tail (its confirmation can outlast
162
+ * the request); money stays truthful either way — the attempt is PENDING
163
+ * server-side and the webhook/poll converge on one outcome.
164
+ */
165
+ interface StepPending {
166
+ step: 'pending';
167
+ }
168
+ type CheckoutSessionResponse = StepClientConfirm | StepEmbedded | StepRedirect | StepProviderCheckout | StepSettled | StepPending | StepFailed;
169
+ /**
170
+ * `POST {apiBase}/campaign/{campaignId}/v2/checkout/{correlationId}/complete` —
171
+ * after a client-side confirm/provider-checkout resolves, the browser asks the
172
+ * server to VERIFY with the provider and write the money facts. The server is the
173
+ * source of truth: it re-fetches the provider object; the browser's claim alone
174
+ * never creates a fact. Idempotent per correlationId (a re-POST returns the same
175
+ * settlement). MoR/async providers (Paddle) may verify via webhook before this
176
+ * call arrives — then it simply returns the already-written settlement.
177
+ */
178
+ interface CheckoutCompleteRequest {
179
+ /** Provider-side handle the client got back, when it has one (e.g. Stripe intent id). */
180
+ providerRef?: string;
181
+ }
182
+ type CheckoutCompleteResponse = StepSettled | StepPending | StepFailed;
183
+
184
+ export { type CheckoutCompleteRequest, type CheckoutCompleteResponse, CheckoutError, CheckoutIntent, type CheckoutSessionRequest, type CheckoutSessionResponse, type CheckoutSettlement, CheckoutSurface, type ScaffoldOptions, type StepClientConfirm, type StepEmbedded, type StepFailed, type StepPending, type StepProviderCheckout, type StepRedirect, type StepSettled, UpsellKind, generateDevEntry, generateEntryClient, generateEntryServer, generateMount };
@@ -0,0 +1,184 @@
1
+ export { i as CompileInput, j as Condition, k as ConditionOp, E as EdgeCondition, m as ExperimentIssue, o as ExperimentValidation, p as ExperimentVariant, q as FlowPage, c as FunnelDefinition, r as FunnelLocales, s as FunnelManifest, ai as FunnelPage, b as FunnelSnapshot, G as Gate, t as Interval, M as ManifestEdge, u as ManifestPage, v as ManifestValidation, w as Money, f as PageMeta, x as PageType, y as Predicate, P as Product, e as ProductInput, z as ResolvedProduct, H as Route, R as RuntimeExperiment, K as assignVariant, N as bucketingSeed, T as buildCatalog, W as compileManifest, X as currencyExponent, Y as defineFunnel, a3 as formatMoney, a4 as formatProduct, a6 as isRtl, a7 as isVariantKey, aa as pageMeta, ab as parseSlotKey, ae as resolveLocale, af as resolveProduct, ah as validateExperiments, aj as weightsOf } from './manifest-DQThneiG.js';
2
+ import { C as CheckoutError, b as CheckoutIntent, U as UpsellKind, d as CheckoutSurface } from './capabilities-7_hy5f5G.js';
3
+ export { a as CheckoutErrorCategory, c as CheckoutProvider, I as INLINE_SURFACES, O as OffSessionReliability, P as PROVIDER_PROFILES, e as ProviderProfile, S as SurfaceCapability, V as ValidationResult, f as checkoutError, i as isInlineSurface, g as isMerchantOfRecord, h as isOrchestrator, s as surfacesFor, v as validateCheckout, j as validateUpsell } from './capabilities-7_hy5f5G.js';
4
+ import 'react';
5
+
6
+ /**
7
+ * Source generators for the funnel build "machinery" authors no longer write. `funnel.ts` (the
8
+ * spine: id, responses, products, checkout, and the page list + declarative routing) plus the
9
+ * `pages/` folder are the ONLY authored source. The build (renderer/builder) and the CLI dev server
10
+ * call these to synthesize:
11
+ * - `mount.tsx` — code-split page loaders + `createFunnelTree`
12
+ * - `entry.client.tsx` — hydrate the SSR'd markup from injected data
13
+ * - `entry.server.tsx` — `ssr()` + the compiled `manifest`
14
+ *
15
+ * All string templates, zero runtime deps — this module lives in the pure `@appfunnel-dev/sdk/
16
+ * manifest` entry so tooling imports it without the funnel runtime.
17
+ */
18
+ interface ScaffoldOptions {
19
+ /** Page component keys = `pages/<key>.tsx` filenames (base flow pages AND `@variant` pages). */
20
+ pageKeys: string[];
21
+ /** Import prefix to reach the funnel root: `'./'` at the root (build), `'../../'` in a subdir (CLI dev). */
22
+ importPrefix?: string;
23
+ /** Whether a `layout.tsx` exists to wrap the pages. */
24
+ hasLayout?: boolean;
25
+ /** Whether a `styles.css` exists (client entry imports it). */
26
+ hasStyles?: boolean;
27
+ /** Checkout provider from `config.checkout` — wires the driver; omit for none. */
28
+ checkout?: 'stripe' | 'paddle' | null;
29
+ }
30
+ /** `mount.tsx` — the code-split loaders + tree, derived from `config.pages` and the `pages/` files. */
31
+ declare function generateMount(opts: ScaffoldOptions): string;
32
+ /** `entry.client.tsx` — hydrate the SSR'd markup from the injected `#__af_data`. */
33
+ declare function generateEntryClient(opts: Pick<ScaffoldOptions, 'importPrefix' | 'hasStyles'>): string;
34
+ /** `entry.server.tsx` — `ssr(opts)` HTML + the compiled `manifest` (read by the build). */
35
+ declare function generateEntryServer(opts: Pick<ScaffoldOptions, 'importPrefix'>): string;
36
+ /** Client-only dev entry (createRoot, no SSR) — for the CLI `dev` server. */
37
+ declare function generateDevEntry(opts: Pick<ScaffoldOptions, 'importPrefix' | 'hasStyles'> & {
38
+ data: unknown;
39
+ }): string;
40
+
41
+ /**
42
+ * The v2 checkout WIRE CONTRACT — the request/response types shared by the server
43
+ * services (apps/api, fresh per-flow checkout — v1 purchase.ts is frozen) and the
44
+ * client drivers (driver-stripe/driver-paddle). Both sides import THESE types from
45
+ * the pure manifest entry, so the contract cannot drift between them.
46
+ *
47
+ * Future-proofing rules (Wave-4, Simon 2026-07-02):
48
+ * - Responses discriminate on `step` (what the CLIENT must do next), NOT on the
49
+ * provider — a new provider reuses an existing step (`redirect`,
50
+ * `provider_checkout`) or adds one, without breaking existing drivers.
51
+ * - The server NEVER returns secret credentials — publishable/client tokens only;
52
+ * charges and verification happen server-side against the mode-resolved store.
53
+ * - `correlationId` is the client-minted idempotency key AND the correlation id
54
+ * the server writes into every provider object's metadata — one id links the
55
+ * trial fee to its subscription, the webhook to the funnel session, and the
56
+ * retry to the original attempt (kills v0's 5-minute-webhook-window linking).
57
+ * - Money facts settle SERVER-side: the browser only ever learns the outcome
58
+ * (`CheckoutSettlement`, with the server-minted `eventId` the pixel dedupes on).
59
+ */
60
+
61
+ /** `POST {apiBase}/campaign/{campaignId}/v2/checkout` — open a checkout attempt. */
62
+ interface CheckoutSessionRequest {
63
+ funnelId: string;
64
+ /** Render-time mode (doc 09 §2.4): resolves the product's binding + store credentials. */
65
+ mode: 'test' | 'live';
66
+ /** Logical catalog product key (`monthly`) — never a raw price id. */
67
+ productKey: string;
68
+ intent: CheckoutIntent;
69
+ /** For `upsell` — which off-session kind (validated against the capability matrix). */
70
+ kind?: UpsellKind;
71
+ /** The presenting surface; null/absent = off-session (upsell, no UI). */
72
+ surface?: CheckoutSurface | null;
73
+ /** Funnel session id (analytics + customer continuity), when one exists. */
74
+ sessionId?: string;
75
+ /** Signed-cookie-verified bare visitor id, when known. */
76
+ visitorId?: string;
77
+ /** Buyer email when the funnel collected it (Stripe Customer creation / receipts). */
78
+ email?: string;
79
+ /**
80
+ * Client-minted UUID. Idempotency key for this attempt (safe re-POST on network
81
+ * retry) and the correlation id stamped into provider-object metadata.
82
+ */
83
+ correlationId: string;
84
+ }
85
+ /** What the browser learned when the server settled the charge (or verified it). */
86
+ interface CheckoutSettlement {
87
+ ok: true;
88
+ /** Server-minted dedup id — the SDK emits `purchase.complete` with it (browser↔CAPI dedup). */
89
+ eventId: string;
90
+ amountMinor: number;
91
+ currency: string;
92
+ productKey: string;
93
+ }
94
+ /** Driver confirms in the browser with the provider's JS (Stripe Elements et al.). */
95
+ interface StepClientConfirm {
96
+ step: 'client_confirm';
97
+ provider: string;
98
+ publishableKey: string;
99
+ clientSecret: string;
100
+ /** Which secret this is — payment (charge now) vs setup (vault, e.g. free-trial start). */
101
+ secretKind: 'payment_intent' | 'setup_intent';
102
+ }
103
+ /** Driver mounts the provider-MANAGED inline checkout (Stripe Embedded). */
104
+ interface StepEmbedded {
105
+ step: 'embedded';
106
+ provider: string;
107
+ publishableKey: string;
108
+ clientSecret: string;
109
+ }
110
+ /** Driver navigates to the provider-hosted page (any provider's `redirect`). */
111
+ interface StepRedirect {
112
+ step: 'redirect';
113
+ provider: string;
114
+ url: string;
115
+ }
116
+ /**
117
+ * Driver opens the provider's own checkout UI (Paddle.js popup/inline, Whop later).
118
+ *
119
+ * WHAT the checkout opens is EXACTLY ONE of `items` | `transactionId`:
120
+ * - `items` — open a NEW checkout for these provider-native prices (the purchase shape;
121
+ * every response before 2026-07 carried this, so `items`-only stays valid unchanged);
122
+ * - `transactionId` — open the provider's checkout for an EXISTING server-created
123
+ * transaction (e.g. Paddle's payment-method-change transaction: the on-session
124
+ * re-collect leg of a failed off-session upgrade — `Checkout.open({ transactionId })`).
125
+ * A response carrying both or neither is malformed and the driver rejects it.
126
+ */
127
+ interface StepProviderCheckout {
128
+ step: 'provider_checkout';
129
+ provider: string;
130
+ /** Provider client token / publishable credential for its JS SDK. */
131
+ clientToken: string;
132
+ /** Provider environment the client SDK must target (Paddle sandbox vs production). */
133
+ providerEnvironment: 'sandbox' | 'production';
134
+ /** Provider-native line items (e.g. Paddle price ids), resolved from the binding. */
135
+ items?: {
136
+ priceId: string;
137
+ quantity: number;
138
+ }[];
139
+ /** Provider-side id of an EXISTING transaction to open (see the exactly-one rule above). */
140
+ transactionId?: string;
141
+ /**
142
+ * Echoed into the provider checkout's custom data (carries the correlationId) — `items`
143
+ * path only. A `transactionId` checkout already exists provider-side with its own custom
144
+ * data (Paddle: inherited from the subscription), so the driver does not send this.
145
+ */
146
+ customData: Record<string, string>;
147
+ }
148
+ /** The server completed the charge synchronously (off-session upsell). */
149
+ interface StepSettled {
150
+ step: 'settled';
151
+ result: CheckoutSettlement;
152
+ }
153
+ /** The attempt failed — normalized taxonomy, never a raw provider error. */
154
+ interface StepFailed {
155
+ step: 'failed';
156
+ error: CheckoutError;
157
+ }
158
+ /**
159
+ * The provider hasn't confirmed yet — the charge is in flight and will settle
160
+ * async (webhook). The driver polls `/complete` until `settled`/`failed`. On the
161
+ * OPEN response this is the Paddle off-session tail (its confirmation can outlast
162
+ * the request); money stays truthful either way — the attempt is PENDING
163
+ * server-side and the webhook/poll converge on one outcome.
164
+ */
165
+ interface StepPending {
166
+ step: 'pending';
167
+ }
168
+ type CheckoutSessionResponse = StepClientConfirm | StepEmbedded | StepRedirect | StepProviderCheckout | StepSettled | StepPending | StepFailed;
169
+ /**
170
+ * `POST {apiBase}/campaign/{campaignId}/v2/checkout/{correlationId}/complete` —
171
+ * after a client-side confirm/provider-checkout resolves, the browser asks the
172
+ * server to VERIFY with the provider and write the money facts. The server is the
173
+ * source of truth: it re-fetches the provider object; the browser's claim alone
174
+ * never creates a fact. Idempotent per correlationId (a re-POST returns the same
175
+ * settlement). MoR/async providers (Paddle) may verify via webhook before this
176
+ * call arrives — then it simply returns the already-written settlement.
177
+ */
178
+ interface CheckoutCompleteRequest {
179
+ /** Provider-side handle the client got back, when it has one (e.g. Stripe intent id). */
180
+ providerRef?: string;
181
+ }
182
+ type CheckoutCompleteResponse = StepSettled | StepPending | StepFailed;
183
+
184
+ export { type CheckoutCompleteRequest, type CheckoutCompleteResponse, CheckoutError, CheckoutIntent, type CheckoutSessionRequest, type CheckoutSessionResponse, type CheckoutSettlement, CheckoutSurface, type ScaffoldOptions, type StepClientConfirm, type StepEmbedded, type StepFailed, type StepPending, type StepProviderCheckout, type StepRedirect, type StepSettled, UpsellKind, generateDevEntry, generateEntryClient, generateEntryServer, generateMount };