@appfunnel-dev/sdk 2.0.0-canary.1 → 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.
- package/dist/capabilities-7_hy5f5G.d.cts +114 -0
- package/dist/capabilities-7_hy5f5G.d.ts +114 -0
- package/dist/checkout-CZmEvWfC.d.cts +317 -0
- package/dist/checkout-DiQvRT5q.d.ts +317 -0
- package/dist/chunk-7UC5VXOR.js +446 -0
- package/dist/chunk-7UC5VXOR.js.map +1 -0
- package/dist/chunk-LJYLGLFS.cjs +153 -0
- package/dist/chunk-LJYLGLFS.cjs.map +1 -0
- package/dist/chunk-UIR6TGEW.js +97 -0
- package/dist/chunk-UIR6TGEW.js.map +1 -0
- package/dist/chunk-VQOD2Z6Q.cjs +104 -0
- package/dist/chunk-VQOD2Z6Q.cjs.map +1 -0
- package/dist/chunk-YY375F2B.js +140 -0
- package/dist/chunk-YY375F2B.js.map +1 -0
- package/dist/chunk-Z3TWO2PW.cjs +475 -0
- package/dist/chunk-Z3TWO2PW.cjs.map +1 -0
- package/dist/driver-paddle.cjs +814 -0
- package/dist/driver-paddle.cjs.map +1 -0
- package/dist/driver-paddle.d.cts +10 -0
- package/dist/driver-paddle.d.ts +10 -0
- package/dist/driver-paddle.js +811 -0
- package/dist/driver-paddle.js.map +1 -0
- package/dist/driver-stripe.cjs +2253 -0
- package/dist/driver-stripe.cjs.map +1 -0
- package/dist/driver-stripe.d.cts +8 -0
- package/dist/driver-stripe.d.ts +8 -0
- package/dist/driver-stripe.js +2247 -0
- package/dist/driver-stripe.js.map +1 -0
- package/dist/index.cjs +1949 -811
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +175 -933
- package/dist/index.d.ts +175 -933
- package/dist/index.js +1669 -652
- package/dist/index.js.map +1 -1
- package/dist/manifest-DQThneiG.d.cts +777 -0
- package/dist/manifest-DQThneiG.d.ts +777 -0
- package/dist/manifest-entry.cjs +203 -0
- package/dist/manifest-entry.cjs.map +1 -0
- package/dist/manifest-entry.d.cts +184 -0
- package/dist/manifest-entry.d.ts +184 -0
- package/dist/manifest-entry.js +98 -0
- package/dist/manifest-entry.js.map +1 -0
- package/package.json +37 -4
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
export { assignVariant, bucketingSeed, buildCatalog, compileManifest, currencyExponent, defineFunnel, formatMoney, formatProduct, isRtl, isVariantKey, pageMeta, parseSlotKey, resolveLocale, resolveProduct, validateExperiments, weightsOf } from './chunk-7UC5VXOR.js';
|
|
2
|
+
export { INLINE_SURFACES, PROVIDER_PROFILES, checkoutError, isInlineSurface, isMerchantOfRecord, isOrchestrator, surfacesFor, validateCheckout, validateUpsell } from './chunk-YY375F2B.js';
|
|
3
|
+
|
|
4
|
+
// src/flow/scaffold.ts
|
|
5
|
+
var DRIVERS = {
|
|
6
|
+
stripe: { name: "stripeCheckoutDriver", sub: "driver-stripe" },
|
|
7
|
+
paddle: { name: "paddleCheckoutDriver", sub: "driver-paddle" }
|
|
8
|
+
};
|
|
9
|
+
var HEADER = "// GENERATED by AppFunnel \u2014 do not edit. Built from funnel.ts + the pages/ folder.\n";
|
|
10
|
+
function generateMount(opts) {
|
|
11
|
+
const p = opts.importPrefix ?? "./";
|
|
12
|
+
const driver = opts.checkout ? DRIVERS[opts.checkout] : null;
|
|
13
|
+
const imports = [
|
|
14
|
+
`import { createFunnelTree, type MountOpts, type RuntimePage } from '@appfunnel-dev/sdk'`,
|
|
15
|
+
driver && `import { ${driver.name} } from '@appfunnel-dev/sdk/${driver.sub}'`,
|
|
16
|
+
`import { config } from '${p}funnel'`,
|
|
17
|
+
opts.hasLayout && `import Layout from '${p}layout'`
|
|
18
|
+
].filter(Boolean).join("\n");
|
|
19
|
+
const loaders = opts.pageKeys.map(
|
|
20
|
+
(k) => ` ${JSON.stringify(k)}: () => import(${JSON.stringify(`${p}pages/${k}`)}),`
|
|
21
|
+
).join("\n");
|
|
22
|
+
const treeArgs = [
|
|
23
|
+
"config",
|
|
24
|
+
"pages",
|
|
25
|
+
opts.hasLayout && "layout: Layout",
|
|
26
|
+
driver && `checkoutDriver: ${driver.name}`
|
|
27
|
+
].filter(Boolean).join(", ");
|
|
28
|
+
return `${HEADER}${imports}
|
|
29
|
+
|
|
30
|
+
const loaders: Record<string, () => Promise<unknown>> = {
|
|
31
|
+
${loaders}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Flow pages come from funnel.ts (order + meta + routing). Any remaining page file is an off-flow
|
|
35
|
+
// \`@variant\` page (wired by experiment records at render time), appended so it's loadable.
|
|
36
|
+
const decls = config.pages ?? []
|
|
37
|
+
const flowKeys = new Set(decls.map((d) => d.key))
|
|
38
|
+
export const pages: RuntimePage[] = [
|
|
39
|
+
...decls.map((d) => ({ key: d.key, meta: d, load: loaders[d.key] })),
|
|
40
|
+
...Object.keys(loaders)
|
|
41
|
+
.filter((k) => !flowKeys.has(k))
|
|
42
|
+
.map((k) => ({ key: k, meta: {}, load: loaders[k] })),
|
|
43
|
+
] as RuntimePage[]
|
|
44
|
+
|
|
45
|
+
export const tree = createFunnelTree({ ${treeArgs} })
|
|
46
|
+
|
|
47
|
+
export type { MountOpts }
|
|
48
|
+
`;
|
|
49
|
+
}
|
|
50
|
+
function generateEntryClient(opts) {
|
|
51
|
+
const p = opts.importPrefix ?? "./";
|
|
52
|
+
const styles = opts.hasStyles ? `import '${p}styles.css'
|
|
53
|
+
` : "";
|
|
54
|
+
return `${HEADER}${styles}import { hydrateRoot } from 'react-dom/client'
|
|
55
|
+
import { tree, type MountOpts } from './mount'
|
|
56
|
+
|
|
57
|
+
const dataEl = document.getElementById('__af_data')
|
|
58
|
+
const data = (dataEl?.textContent ? JSON.parse(dataEl.textContent) : {}) as MountOpts & {
|
|
59
|
+
initialKey?: string | null
|
|
60
|
+
}
|
|
61
|
+
const root = document.getElementById('root')
|
|
62
|
+
if (root) hydrateRoot(root, tree({ ...data, initialKey: data.initialKey ?? undefined }))
|
|
63
|
+
`;
|
|
64
|
+
}
|
|
65
|
+
function generateEntryServer(opts) {
|
|
66
|
+
const p = opts.importPrefix ?? "./";
|
|
67
|
+
return `${HEADER}import { renderToReadableStream } from 'react-dom/server.browser'
|
|
68
|
+
import { compileManifest } from '@appfunnel-dev/sdk'
|
|
69
|
+
import { config } from '${p}funnel'
|
|
70
|
+
import { tree, pages, type MountOpts } from './mount'
|
|
71
|
+
|
|
72
|
+
export const manifest = compileManifest({
|
|
73
|
+
funnel: config,
|
|
74
|
+
pages: pages.map((pg) => ({ key: pg.key, meta: pg.meta })),
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
export async function ssr(opts: MountOpts): Promise<string> {
|
|
78
|
+
const stream = await renderToReadableStream(tree(opts))
|
|
79
|
+
await stream.allReady
|
|
80
|
+
return await new Response(stream).text()
|
|
81
|
+
}
|
|
82
|
+
`;
|
|
83
|
+
}
|
|
84
|
+
function generateDevEntry(opts) {
|
|
85
|
+
const p = opts.importPrefix ?? "./";
|
|
86
|
+
const styles = opts.hasStyles ? `import '${p}styles.css'
|
|
87
|
+
` : "";
|
|
88
|
+
return `${HEADER}${styles}import { createRoot } from 'react-dom/client'
|
|
89
|
+
import { tree } from './mount'
|
|
90
|
+
|
|
91
|
+
const el = document.getElementById('root')
|
|
92
|
+
if (el) createRoot(el).render(tree(${JSON.stringify(opts.data)}))
|
|
93
|
+
`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export { generateDevEntry, generateEntryClient, generateEntryServer, generateMount };
|
|
97
|
+
//# sourceMappingURL=manifest-entry.js.map
|
|
98
|
+
//# sourceMappingURL=manifest-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/flow/scaffold.ts"],"names":[],"mappings":"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","file":"manifest-entry.js","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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appfunnel-dev/sdk",
|
|
3
|
-
"version": "2.0.0-canary.
|
|
3
|
+
"version": "2.0.0-canary.2",
|
|
4
4
|
"description": "The AppFunnel funnel framework — typed namespaces, routing, commerce, modals, i18n for React funnels",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -20,6 +20,36 @@
|
|
|
20
20
|
"types": "./dist/index.d.cts",
|
|
21
21
|
"default": "./dist/index.cjs"
|
|
22
22
|
}
|
|
23
|
+
},
|
|
24
|
+
"./manifest": {
|
|
25
|
+
"import": {
|
|
26
|
+
"types": "./dist/manifest-entry.d.ts",
|
|
27
|
+
"default": "./dist/manifest-entry.js"
|
|
28
|
+
},
|
|
29
|
+
"require": {
|
|
30
|
+
"types": "./dist/manifest-entry.d.cts",
|
|
31
|
+
"default": "./dist/manifest-entry.cjs"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"./driver-stripe": {
|
|
35
|
+
"import": {
|
|
36
|
+
"types": "./dist/driver-stripe.d.ts",
|
|
37
|
+
"default": "./dist/driver-stripe.js"
|
|
38
|
+
},
|
|
39
|
+
"require": {
|
|
40
|
+
"types": "./dist/driver-stripe.d.cts",
|
|
41
|
+
"default": "./dist/driver-stripe.cjs"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"./driver-paddle": {
|
|
45
|
+
"import": {
|
|
46
|
+
"types": "./dist/driver-paddle.d.ts",
|
|
47
|
+
"default": "./dist/driver-paddle.js"
|
|
48
|
+
},
|
|
49
|
+
"require": {
|
|
50
|
+
"types": "./dist/driver-paddle.d.cts",
|
|
51
|
+
"default": "./dist/driver-paddle.cjs"
|
|
52
|
+
}
|
|
23
53
|
}
|
|
24
54
|
},
|
|
25
55
|
"files": [
|
|
@@ -49,15 +79,18 @@
|
|
|
49
79
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
50
80
|
},
|
|
51
81
|
"dependencies": {
|
|
52
|
-
"sonner": "^2.0.7"
|
|
82
|
+
"sonner": "^2.0.7",
|
|
83
|
+
"@stripe/stripe-js": "^9.9.0",
|
|
84
|
+
"@stripe/react-stripe-js": "^6.7.0",
|
|
85
|
+
"@paddle/paddle-js": "^1.6.4"
|
|
53
86
|
},
|
|
54
87
|
"devDependencies": {
|
|
88
|
+
"@testing-library/react": "^16.1.0",
|
|
55
89
|
"@types/react": "^19.0.0",
|
|
56
90
|
"@types/react-dom": "^19.0.0",
|
|
91
|
+
"happy-dom": "^15.11.0",
|
|
57
92
|
"react": "^19.0.0",
|
|
58
93
|
"react-dom": "^19.0.0",
|
|
59
|
-
"@testing-library/react": "^16.1.0",
|
|
60
|
-
"happy-dom": "^15.11.0",
|
|
61
94
|
"tsup": "^8.0.0",
|
|
62
95
|
"typescript": "^5.4.0",
|
|
63
96
|
"vitest": "^2.1.0"
|