@whop/react-native 0.1.14 → 0.2.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/index.ts","../../src/cli/env-bool.ts","../../src/cli/mobile.ts","../../src/cli/file.ts","../../src/cli/sdk.ts","../../src/cli/load-metro-config.ts","../../src/cli/valid-view-type.ts","../../src/cli/web.ts","../../src/cli/reanimated-bable.ts","../../src/cli/strip-flow.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { parseArgs } from \"node:util\";\nimport { findUp } from \"find-up\";\nimport qrcode from \"qrcode-terminal\";\nimport { rimraf } from \"rimraf\";\nimport { envBool } from \"./env-bool\";\nimport { buildAndPublish } from \"./mobile\";\nimport { env } from \"./sdk\";\nimport { buildAndPublish as buildAndPublishWeb } from \"./web\";\n\nasync function main() {\n\tconst args = parseArgs({\n\t\toptions: {\n\t\t\tios: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t},\n\t\t\tandroid: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t},\n\t\t\tweb: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t},\n\t\t},\n\t\tstrict: true,\n\t\tallowPositionals: true,\n\t\targs: process.argv.slice(2),\n\t});\n\n\tconst [command] = args.positionals;\n\n\tif (command === \"install\") {\n\t\tawait handleInstall();\n\t\treturn;\n\t}\n\n\tlet shouldBuild = true;\n\tlet shouldUpload = true;\n\tlet shouldClean = true;\n\tif (command === \"build\") {\n\t\tshouldUpload = false;\n\t} else if (command === \"ship\") {\n\t\tshouldBuild = true;\n\t\tshouldUpload = true;\n\t} else if (command === \"upload\") {\n\t\tshouldBuild = false;\n\t\tshouldClean = false;\n\t} else if (command === \"clean\") {\n\t\tshouldBuild = false;\n\t\tshouldUpload = false;\n\t} else {\n\t\tconsole.error(\n\t\t\t`Usage:\n\twhop-react-native ship [--ios] [--android] [--web] # runs build and then publishes it as a dev build to whop.\n\twhop-react-native build [--ios] [--android] [--web] # builds your app into a distributable bundle in the build/ directory.\n\twhop-react-native upload [--ios] [--android] [--web] # uploads the existing build directory to whop.\n\twhop-react-native clean # cleans the build directory.`,\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\tconst root = await getRootProjectDirectory();\n\n\tif (shouldClean) {\n\t\tif (envBool(\"WRN_FULL_CLEAN\")) {\n\t\t\tawait cleanBuildDirectory(root);\n\t\t} else {\n\t\t\tawait cleanEntrypointsDirectory(root);\n\t\t}\n\t}\n\n\tconst didProvidePlatform =\n\t\targs.values.ios || args.values.android || args.values.web;\n\n\tconst opts = { shouldBuild, shouldUpload };\n\tconst promises: Promise<void>[] = [];\n\n\tif (args.values.ios || !didProvidePlatform) {\n\t\tpromises.push(buildAndPublish(root, \"ios\", opts));\n\t}\n\tif (args.values.android || !didProvidePlatform) {\n\t\tpromises.push(buildAndPublish(root, \"android\", opts));\n\t}\n\tif (args.values.web || !didProvidePlatform) {\n\t\tpromises.push(buildAndPublishWeb(root, opts));\n\t}\n\n\tawait Promise.all(promises);\n}\n\nasync function cleanBuildDirectory(root: string) {\n\tconst buildDirectory = path.join(root, \"build\");\n\tif (existsSync(buildDirectory)) {\n\t\tawait rimraf(buildDirectory);\n\t}\n\tconsole.log(\" ✔︎ cleaned build directory\");\n}\n\nasync function cleanEntrypointsDirectory(root: string) {\n\tconst buildDirectory = path.join(root, \"build\", \"entrypoints\");\n\tif (existsSync(buildDirectory)) {\n\t\tawait rimraf(buildDirectory);\n\t}\n\tconsole.log(\" ✔︎ cleaned build entrypoints directory\");\n}\n\nasync function getRootProjectDirectory() {\n\tconst file = await findUp(\"package.json\", { cwd: process.cwd() });\n\tif (!file) {\n\t\tthrow new Error(\n\t\t\t\"please run this command inside a whop react native project\",\n\t\t);\n\t}\n\tconst root = path.dirname(file);\n\treturn root;\n}\n\nasync function handleInstall() {\n\tconst appId = env(\"NEXT_PUBLIC_WHOP_APP_ID\");\n\tconst installLink = `https://whop.com/apps/${appId}/install`;\n\n\tconsole.log(`\nOpen this link in your browser to install the app into your whop.\n${installLink}\n\nOr scan the QR code with your iPhone:\n\t`);\n\n\tqrcode.generate(installLink, { small: true });\n}\n\nmain()\n\t.catch((err) => {\n\t\tconsole.error(err);\n\t\tprocess.exit(1);\n\t})\n\t.then(() => {\n\t\tprocess.exit(0);\n\t});\n","/**\n * Check if an environment variable is set to a truthy value.\n * Accepts: \"1\", \"true\", \"yes\" (case-insensitive)\n */\nexport function envBool(name: string): boolean {\n\tconst value = process.env[name]?.toLowerCase();\n\treturn value === \"1\" || value === \"true\" || value === \"yes\";\n}\n","import { existsSync, readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { mkdir, rename, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getDefaultConfig, mergeConfig } from \"@react-native/metro-config\";\nimport { findUp } from \"find-up\";\nimport JSZip from \"jszip\";\nimport { type ReportableEvent, type Reporter, runBuild } from \"metro\";\nimport { envBool } from \"./env-bool\";\nimport { getChecksum, uploadFile } from \"./file\";\nimport { loadMetroConfig } from \"./load-metro-config\";\nimport { AI_PROMPT_ID, APP_ID, COMPANY_ID, whopSdk } from \"./sdk\";\nimport { getSupportedAppViewTypes } from \"./valid-view-type\";\n\nexport async function buildAndPublish(\n\troot: string,\n\tplatform: \"ios\" | \"android\",\n\t{\n\t\tshouldBuild = true,\n\t\tshouldUpload = true,\n\t}: { shouldBuild: boolean; shouldUpload: boolean } = {\n\t\tshouldBuild: true,\n\t\tshouldUpload: true,\n\t},\n) {\n\tif (shouldBuild) {\n\t\tawait bundle(root, platform);\n\t}\n\tif (shouldUpload) {\n\t\tawait createMobileBuild(root, platform);\n\t}\n}\n\nexport async function bundle(root: string, platform: \"ios\" | \"android\") {\n\tawait makeEntrypoint(root, platform);\n\n\tconst outputFile = path.join(\n\t\troot,\n\t\t\"build\",\n\t\t\"output\",\n\t\tplatform,\n\t\t\"main_js_bundle\",\n\t);\n\n\tconst cacheDir =\n\t\tprocess.env.WRN_METRO_CACHE_DIRECTORY || path.join(root, \"build\", \"cache\");\n\tconst isCacheDisabled = envBool(\"WRN_DISABLE_METRO_CACHE\");\n\tconst remoteCacheUrl = process.env.WRN_REMOTE_METRO_CACHE_URL;\n\n\tawait mkdir(path.dirname(outputFile), { recursive: true });\n\n\tconst babelLocation = require.resolve(\"@babel/runtime/package\");\n\n\tconst bableNodeModules = await findUp(\"node_modules\", {\n\t\tcwd: babelLocation,\n\t\ttype: \"directory\",\n\t});\n\n\tif (!bableNodeModules) {\n\t\tthrow new Error(\"babel node_modules parent folder not found\");\n\t}\n\n\tconst defaultConfig = getDefaultConfig(root);\n\tconst projectConfig = await loadMetroConfig(root);\n\n\tconst defaultMetroConfig = mergeConfig(defaultConfig, projectConfig);\n\n\tconst metroConfig = mergeConfig(defaultMetroConfig, {\n\t\tprojectRoot: root,\n\t\ttransformer: {\n\t\t\tbabelTransformerPath: require.resolve(\n\t\t\t\t\"./whop-react-native-babel-transformer.js\",\n\t\t\t),\n\t\t},\n\t\tcacheStores: ({ FileStore, HttpStore }) => {\n\t\t\tif (isCacheDisabled) return [];\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: types are cooked here\n\t\t\tconst caches: any[] = [\n\t\t\t\tnew FileStore({\n\t\t\t\t\troot: cacheDir,\n\t\t\t\t}),\n\t\t\t];\n\t\t\tif (remoteCacheUrl) {\n\t\t\t\tcaches.push(new HttpStore({ endpoint: remoteCacheUrl }));\n\t\t\t}\n\t\t\treturn caches;\n\t\t},\n\t\tcacheVersion: process.env.WRN_METRO_CACHE_VERSION,\n\t\twatchFolders: [root, path.resolve(root, \"node_modules\"), bableNodeModules],\n\t\treporter: new CustomReporter(),\n\t\tresolver: {\n\t\t\tnodeModulesPaths: [\n\t\t\t\t...(defaultMetroConfig.resolver?.nodeModulesPaths ?? []),\n\t\t\t\tbableNodeModules,\n\t\t\t],\n\t\t},\n\t});\n\n\tawait runBuild(metroConfig, {\n\t\tdev: false,\n\t\tentry: `build/entrypoints/${platform}/index.js`,\n\t\tminify: false,\n\t\tplatform: platform,\n\t\tsourceMap: false,\n\t\tout: outputFile,\n\t});\n\n\tawait rename(\n\t\t`${outputFile}.js`,\n\t\tpath.join(root, \"build\", \"output\", platform, \"main_js_bundle.hbc\"),\n\t);\n\n\tconsole.log(` ✔︎ [${platform}] bundle created`);\n}\n\n// getSupportedAppViewTypes moved to valid-view-type.ts\n\nasync function makeEntrypoint(\n\troot: string,\n\tplatform: \"ios\" | \"android\",\n): Promise<string> {\n\tconst entrypoint = path.join(\n\t\troot,\n\t\t\"build\",\n\t\t\"entrypoints\",\n\t\tplatform,\n\t\t\"index.js\",\n\t);\n\n\tconst files = await getSupportedAppViewTypes(root);\n\n\tconst pascalCase = (str: string) =>\n\t\tstr\n\t\t\t.split(\"-\")\n\t\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n\t\t\t.join(\"\");\n\n\tconst imports = files.map(\n\t\t(file) =>\n\t\t\t`import { ${pascalCase(file)} } from \"../../../src/views/${file}\";`,\n\t);\n\tconst registry = files.map(\n\t\t(file) =>\n\t\t\t`AppRegistry.registerComponent(\"${pascalCase(file)}\", () => ${pascalCase(\n\t\t\t\tfile,\n\t\t\t)});`,\n\t);\n\n\tconst entrypointContent = `import { AppRegistry } from \"react-native\";\n${imports.join(\"\\n\")}\n\n${registry.join(\"\\n\")}\n`;\n\n\tconst entrypointDir = path.dirname(entrypoint);\n\tawait mkdir(entrypointDir, { recursive: true });\n\tawait writeFile(entrypoint, entrypointContent, \"utf-8\");\n\n\tconsole.log(` ✔︎ [${platform}] entrypoint created`);\n\n\treturn entrypoint;\n}\n\nexport async function createMobileBuild(\n\troot: string,\n\tplatform: \"ios\" | \"android\",\n) {\n\tconst viewTypes = await getSupportedAppViewTypes(root);\n\n\tconst fullDirectory = path.join(root, \"build\", \"output\", platform);\n\n\t// Check if the directory contains a file called `main_js_bundle.hbc`\n\tconst mainJsBundle = path.join(fullDirectory, \"main_js_bundle.hbc\");\n\n\tif (!existsSync(mainJsBundle)) {\n\t\tthrow new Error(`main_js_bundle.hbc not found in ${fullDirectory}`);\n\t}\n\n\t// check that that folder only contains the main_js_bundle.hbc file and an optional `assets` folder\n\tconst files = readdirSync(fullDirectory);\n\tif (\n\t\tfiles.length > 2 ||\n\t\tfiles.length < 1 ||\n\t\t!files.includes(\"main_js_bundle.hbc\")\n\t) {\n\t\tthrow new Error(\n\t\t\t\"Directory must contain only the main_js_bundle.hbc file and an optional `assets` folder\",\n\t\t);\n\t}\n\tif (files.length === 2 && !files.includes(\"assets\")) {\n\t\tthrow new Error(\n\t\t\t\"Directory must contain only the main_js_bundle.hbc file and an optional `assets` folder\",\n\t\t);\n\t}\n\n\t// Zip the directory\n\tconst zipData = await zipDirectory(fullDirectory);\n\n\tconst checksum = await getChecksum(zipData);\n\n\tconsole.log(` ✔︎ [${platform}] build zipped with checksum: ${checksum}`);\n\n\tconst fileName = `app_build_${platform}.zip`;\n\tconst uploadedFile = await uploadFile(zipData, fileName, \"application/zip\");\n\n\tconsole.log(\n\t\t` ✔︎ [${platform}] uploaded build: ${fileName} (${(\n\t\t\tzipData.length / 1024\n\t\t).toFixed(0)} KB)`,\n\t);\n\n\tconst build = await whopSdk.appBuilds.create({\n\t\tattachment: { id: uploadedFile.id },\n\t\tchecksum,\n\t\tapp_id: APP_ID,\n\t\tplatform,\n\t\tai_prompt_id: AI_PROMPT_ID,\n\t\tsupported_app_view_types: viewTypes.map(\n\t\t\t(view) =>\n\t\t\t\t({\n\t\t\t\t\t\"experience-view\": \"hub\" as const,\n\t\t\t\t\t\"discover-view\": \"discover\" as const,\n\t\t\t\t\t\"dashboard-view\": \"dashboard\" as const,\n\t\t\t\t})[view],\n\t\t),\n\t});\n\n\tif (!build) {\n\t\tthrow new Error(\"Failed to create app build\");\n\t}\n\n\tconst companyPart = COMPANY_ID ? `${COMPANY_ID}/` : \"\";\n\tconst dashboardUrl = `https://whop.com/dashboard/${companyPart}developer/apps/${APP_ID}/builds/?platform=${platform}`;\n\n\tconsole.log(`\\n ✔︎ [${platform}] deployed as development build ✔︎\n - build id: ${build.id}\n - view types: ${build.supported_app_view_types.join(\", \")}\n - promote to production here: ${dashboardUrl}\\n`);\n\n\treturn build;\n}\n\nasync function zipDirectory(\n\tdirectory: string,\n): Promise<Buffer<ArrayBufferLike>> {\n\tconst zip = new JSZip();\n\n\t// Recursively add files to zip\n\tfunction addFilesToZip(currentPath: string, relativePath = \"\") {\n\t\tconst items = readdirSync(currentPath);\n\n\t\tfor (const item of items) {\n\t\t\tconst fullPath = path.join(currentPath, item);\n\t\t\tconst zipPath = relativePath ? path.join(relativePath, item) : item;\n\t\t\tconst stats = statSync(fullPath);\n\n\t\t\tif (stats.isDirectory()) {\n\t\t\t\taddFilesToZip(fullPath, zipPath);\n\t\t\t} else {\n\t\t\t\tconst fileContent = readFileSync(fullPath);\n\t\t\t\tzip.file(zipPath, fileContent);\n\t\t\t}\n\t\t}\n\t}\n\n\taddFilesToZip(directory);\n\n\t// Generate zip file\n\tconst zipData = await zip.generateAsync({ type: \"nodebuffer\" });\n\n\treturn zipData;\n}\n\nclass CustomReporter implements Reporter {\n\tupdate(event: ReportableEvent) {\n\t\t// Do nothing.\n\t}\n}\n","import { createHash } from \"node:crypto\";\nimport { whopSdk } from \"./sdk\";\n\nexport async function uploadFile(\n\tdata: Buffer<ArrayBufferLike>,\n\tname: string,\n\t_contentType: string,\n) {\n\tconst uploadedFile = await whopSdk.files.upload(data, {\n\t\tfilename: name,\n\t});\n\n\treturn uploadedFile;\n}\n\nexport async function getChecksum(data: Buffer<ArrayBufferLike>) {\n\tconst hash = createHash(\"sha256\");\n\thash.update(data);\n\treturn hash.digest(\"hex\");\n}\n","import Whop from \"@whop/sdk\";\nimport { config } from \"dotenv\";\n\nconfig({\n path: [\".env\", \".env.local\", \".env.development\", \".env.production\"],\n});\n\nexport function env(key: string) {\n const value = process.env[key];\n if (!value) {\n throw new Error(`Missing environment variable: ${key}`);\n }\n return value;\n}\n\nconst BASE_URL = process.env.WHOP_BASE_URL;\n\nexport const COMPANY_ID = process.env.NEXT_PUBLIC_WHOP_COMPANY_ID;\nexport const APP_ID = env(\"NEXT_PUBLIC_WHOP_APP_ID\");\nexport const AI_PROMPT_ID = process.env.AI_PROMPT_ID;\n\nconst headersJSON = process.env.WHOP_EXTRA_API_HEADERS_JSON;\nlet parsedExtraHeaders: Record<string, string> | undefined = undefined;\n\ntry {\n if (headersJSON) {\n parsedExtraHeaders = JSON.parse(headersJSON);\n }\n} catch (e) {\n console.error(\"FAILED TO PARSE EXTRA WHOP API HEADERS\", e);\n}\n\nexport const whopSdk = new Whop({\n appID: APP_ID,\n baseURL: BASE_URL ? new URL(\"/api/v1\", BASE_URL).href : undefined,\n defaultHeaders: parsedExtraHeaders,\n});\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { loadConfig } from \"metro\";\n\nexport async function loadMetroConfig(projectRoot: string) {\n\tconst file = fs.existsSync(path.join(projectRoot, \"metro.config.js\"));\n\tif (!file) return {};\n\treturn await loadConfig({ cwd: projectRoot }, {});\n}\n","import { readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport const VALID_VIEW_TYPES = [\n\t\"experience-view\",\n\t\"discover-view\",\n\t\"dashboard-view\",\n] as const;\n\nexport async function getSupportedAppViewTypes(\n\troot: string,\n): Promise<(typeof VALID_VIEW_TYPES)[number][]> {\n\tconst views = await readdir(path.join(root, \"src\", \"views\"), {\n\t\twithFileTypes: true,\n\t\trecursive: false,\n\t});\n\tconst files = views\n\t\t.filter((file) => file.isFile())\n\t\t.map((file) => file.name.split(\".\")[0])\n\t\t.filter((file) => !!file);\n\n\tconst validViews = files.filter((file) =>\n\t\tVALID_VIEW_TYPES.includes(file as (typeof VALID_VIEW_TYPES)[number]),\n\t) as (typeof VALID_VIEW_TYPES)[number][];\n\n\tif (validViews.length === 0) {\n\t\tthrow new Error(\n\t\t\t`No valid views found, please create a view in the src/views folder and name it with a valid view type: ${VALID_VIEW_TYPES.join(\", \")}`,\n\t\t);\n\t}\n\n\treturn validViews;\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { build } from \"esbuild\";\nimport { getChecksum, uploadFile } from \"./file\";\nimport { reanimatedBabelPlugin } from \"./reanimated-bable\";\nimport { AI_PROMPT_ID, APP_ID, COMPANY_ID, whopSdk } from \"./sdk\";\nimport { stripFlowWithBabel } from \"./strip-flow\";\nimport { getSupportedAppViewTypes } from \"./valid-view-type\";\n\nfunction aliasReactNativePlugin() {\n\treturn {\n\t\tname: \"alias-react-native\",\n\t\tsetup(b: import(\"esbuild\").PluginBuild) {\n\t\t\tb.onResolve({ filter: /^react-native$/ }, () => ({\n\t\t\t\tpath: require.resolve(\"react-native-web\"),\n\t\t\t}));\n\t\t},\n\t} satisfies import(\"esbuild\").Plugin;\n}\n\nfunction forceSingleReact() {\n\tconst map = new Map<string, string>([\n\t\t[\"react\", require.resolve(\"react\")],\n\t\t[\"react/jsx-runtime\", require.resolve(\"react/jsx-runtime\")],\n\t\t[\"react/jsx-dev-runtime\", require.resolve(\"react/jsx-dev-runtime\")],\n\t\t[\"react-dom\", require.resolve(\"react-dom\")],\n\t\t[\"react-dom/client\", require.resolve(\"react-dom/client\")],\n\t]);\n\n\tconst rx = /^(react(?:\\/jsx-(?:dev-)?runtime)?|react-dom(?:\\/client)?)$/;\n\n\treturn {\n\t\tname: \"force-single-react\",\n\t\tsetup(b: import(\"esbuild\").PluginBuild) {\n\t\t\t// biome-ignore lint/style/noNonNullAssertion: <explanation>\n\t\t\tb.onResolve({ filter: rx }, (args) => ({ path: map.get(args.path)! }));\n\t\t},\n\t} satisfies import(\"esbuild\").Plugin;\n}\n\nfunction toPascalCase(str: string) {\n\treturn str\n\t\t.split(\"-\")\n\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n\t\t.join(\"\");\n}\n\nasync function makeWebEntrypoint(root: string) {\n\tconst files = await getSupportedAppViewTypes(root);\n\n\tconst packageJsonPath = path.join(root, \"package.json\");\n\tconst packageJson = JSON.parse(await readFile(packageJsonPath, \"utf-8\"));\n\tconst hasReactNativeReanimated =\n\t\tpackageJson.dependencies?.[\"react-native-reanimated\"];\n\n\tconst imports = files.map(\n\t\t(file) =>\n\t\t\t`import { ${toPascalCase(file)} } from \"../../../src/views/${file}\";`,\n\t);\n\tconst registry = files.map(\n\t\t(file) =>\n\t\t\t`AppRegistry.registerComponent(\"${toPascalCase(\n\t\t\t\tfile,\n\t\t\t)}\", () => WhopNavigationWrapper(React, \"${toPascalCase(\n\t\t\t\tfile,\n\t\t\t)}\", ${toPascalCase(file)}));`,\n\t);\n\n\tconst defaultKey = toPascalCase(files[0] ?? \"experience-view\");\n\tconst reanimatedImport = hasReactNativeReanimated\n\t\t? `import \"react-native-reanimated\";`\n\t\t: \"\";\n\n\tconst entry = `import { AppRegistry } from \"react-native\";\nimport * as React from \"react\";\nimport { WhopNavigationWrapper } from \"@whop/react-native/web\";\n${reanimatedImport}\n\n${imports.join(\"\\n\")}\n\n${registry.join(\"\\n\")}\n\nconst viewType = new URLSearchParams(window.location.search).get(\"app_view\") ?? \"${defaultKey}\";\n\nconst root = document.getElementById(\"root\") || (() => {\n\tconst d = document.createElement(\"div\");\n\td.id = \"root\";\n\tdocument.body.appendChild(d);\n\treturn d;\n})();\nAppRegistry.runApplication(viewType, { rootTag: root });\n`;\n\n\tconst entryFile = path.join(root, \"build\", \"entrypoints\", \"web\", \"index.tsx\");\n\tawait mkdir(path.dirname(entryFile), { recursive: true });\n\tawait writeFile(entryFile, entry, \"utf-8\");\n\n\treturn entryFile;\n}\n\nexport async function bundleWeb(root: string) {\n\tconst entry = await makeWebEntrypoint(root);\n\n\tconst outDir = path.join(root, \"build\", \"output\", \"web\");\n\tawait mkdir(outDir, { recursive: true });\n\n\tawait build({\n\t\tentryPoints: [entry],\n\t\toutfile: path.join(outDir, \"main.js\"),\n\t\tbundle: true,\n\t\tminify: false,\n\t\tformat: \"esm\",\n\t\tplatform: \"browser\",\n\t\tsourcemap: false,\n\t\tjsx: \"automatic\",\n\t\tmainFields: [\"browser\", \"module\", \"main\"],\n\t\tconditions: [\"browser\", \"import\", \"default\"],\n\t\tdefine: {\n\t\t\tprocess: \"{}\",\n\t\t\t\"process.env\": \"{}\",\n\t\t\t\"process.env.NODE_ENV\": '\"production\"',\n\t\t\t__DEV__: \"false\",\n\t\t\t\"process.env.NEXT_PUBLIC_WHOP_APP_ID\": `\"${APP_ID}\"`,\n\t\t\t// Some RN libraries (e.g., RNGH) expect a Node-like global in the browser\n\t\t\tglobal: \"globalThis\",\n\t\t},\n\t\tresolveExtensions: [\n\t\t\t\".web.tsx\",\n\t\t\t\".web.ts\",\n\t\t\t\".web.js\",\n\t\t\t\".tsx\",\n\t\t\t\".ts\",\n\t\t\t\".jsx\",\n\t\t\t\".js\",\n\t\t\t\".mjs\",\n\t\t],\n\t\tloader: {\n\t\t\t\".png\": \"dataurl\",\n\t\t\t\".jpg\": \"dataurl\",\n\t\t\t\".jpeg\": \"dataurl\",\n\t\t\t\".svg\": \"dataurl\",\n\t\t\t\".ttf\": \"dataurl\",\n\t\t\t\".woff\": \"dataurl\",\n\t\t\t\".woff2\": \"dataurl\",\n\t\t\t\".js\": \"jsx\",\n\t\t\t\".jsx\": \"jsx\",\n\t\t\t\".mjs\": \"jsx\",\n\t\t},\n\t\tplugins: [\n\t\t\tforceSingleReact(),\n\t\t\taliasReactNativePlugin(),\n\t\t\treanimatedBabelPlugin(),\n\t\t\tstripFlowWithBabel(),\n\t\t\t{\n\t\t\t\tname: \"force-native-web-stub\",\n\t\t\t\tsetup(b) {\n\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: <explanation>\n\t\t\t\t\tb.onResolve({ filter: /^\\.\\/native-whop-core$/ }, (args: any) => {\n\t\t\t\t\t\t// Always resolve the local source file so extension resolution (.web.ts) applies\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tpath: path.join(args.resolveDir, \"native-whop-core\"),\n\t\t\t\t\t\t\tnamespace: \"file\",\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t});\n\n\tconst html = `<!doctype html>\n<html>\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\t\t<title>Whop App (Web)</title>\n\t\t<style>\n\t\t\t#root {\n\t\t\t\twidth: 100vw;\n\t\t\t\theight: 100vh;\n\t\t\t\tmargin: 0;\n\t\t\t\tpadding: 0;\n\t\t\t\toverflow: hidden;\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-direction: column;\n\t\t\t\talign-items: stretch;\n\t\t\t\tjustify-content: start;\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div id=\"root\"></div>\n\t\t<script type=\"module\" src=\"./main.js\"></script>\n\t</body>\n</html>`;\n\tawait writeFile(path.join(outDir, \"index.html\"), html, \"utf-8\");\n\n\tconsole.log(\" ✔︎ [web] bundle created at build/output/web/main.js\");\n}\n\nexport async function buildAndPublish(\n\troot: string,\n\t{\n\t\tshouldBuild = true,\n\t\tshouldUpload = true,\n\t}: { shouldBuild: boolean; shouldUpload: boolean } = {\n\t\tshouldBuild: true,\n\t\tshouldUpload: true,\n\t},\n) {\n\tif (shouldBuild) {\n\t\tawait bundleWeb(root);\n\t}\n\tif (shouldUpload) {\n\t\tawait createWebBuild(root);\n\t}\n}\n\nexport async function createWebBuild(root: string) {\n\tconst viewTypes = await getSupportedAppViewTypes(root);\n\n\tconst fullDirectory = path.join(root, \"build\", \"output\", \"web\");\n\tconst mainJsFile = path.join(fullDirectory, \"main.js\");\n\n\t// Verify bundle exists\n\ttry {\n\t\tawait readFile(mainJsFile);\n\t} catch {\n\t\tthrow new Error(`main.js not found in ${fullDirectory}`);\n\t}\n\n\tconst buf = await readFile(mainJsFile);\n\tconst checksum = await getChecksum(buf);\n\n\tconsole.log(` ✔︎ [web] build checksummed: ${checksum}`);\n\n\tconst fileName = `rnweb_${checksum}.js`;\n\tconst uploadedFile = await uploadFile(\n\t\tbuf,\n\t\tfileName,\n\t\t\"application/javascript\",\n\t);\n\n\tconsole.log(\n\t\t` ✔︎ [web] uploaded build: ${fileName} (${(buf.length / 1024).toFixed(\n\t\t\t0,\n\t\t)} KB)`,\n\t);\n\n\tconst build = await whopSdk.appBuilds.create({\n\t\tattachment: { id: uploadedFile.id },\n\t\tchecksum,\n\t\tapp_id: APP_ID,\n\t\tplatform: \"web\",\n\t\tai_prompt_id: AI_PROMPT_ID,\n\t\tsupported_app_view_types: viewTypes.map(\n\t\t\t(view) =>\n\t\t\t\t({\n\t\t\t\t\t\"experience-view\": \"hub\" as const,\n\t\t\t\t\t\"discover-view\": \"discover\" as const,\n\t\t\t\t\t\"dashboard-view\": \"dashboard\" as const,\n\t\t\t\t})[view],\n\t\t),\n\t});\n\n\tif (!build) {\n\t\tthrow new Error(\"Failed to create app build\");\n\t}\n\n\tconst companyPart = COMPANY_ID ? `${COMPANY_ID}/` : \"\";\n\tconst dashboardUrl = `https://whop.com/dashboard/${companyPart}developer/apps/${APP_ID}/builds/?platform=web`;\n\n\tconsole.log(\n\t\t`\\n ✔︎ [web] deployed as development build ✔︎\\n - build id: ${\n\t\t\tbuild.id\n\t\t}\\n - view types: ${build.supported_app_view_types.join(\n\t\t\t\", \",\n\t\t)}\\n - promote to production here: ${dashboardUrl}\\n`,\n\t);\n\n\treturn build;\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\n// build/plugins/reanimatedBabel.ts\nimport * as babel from \"@babel/core\";\n\nconst JS_RE = /\\.(m|c)?(t|j)sx?$/;\n\nexport function reanimatedBabelPlugin() {\n\t// Transform only: your app source (outside node_modules) and reanimated itself.\n\tconst shouldTransform = (p: string) => {\n\t\tif (!JS_RE.test(p)) return false;\n\t\t// Always run on reanimated’s files\n\t\tif (p.includes(`${path.sep}react-native-reanimated${path.sep}`))\n\t\t\treturn true;\n\t\t// Never touch third-party deps\n\t\tif (p.includes(`${path.sep}node_modules${path.sep}`)) return false;\n\t\t// Run on app code under src/\n\t\treturn p.includes(`${path.sep}src${path.sep}`);\n\t};\n\n\treturn {\n\t\tname: \"reanimated-babel\",\n\t\tsetup(b: import(\"esbuild\").PluginBuild) {\n\t\t\tb.onLoad({ filter: JS_RE }, async (args) => {\n\t\t\t\tif (!shouldTransform(args.path)) {\n\t\t\t\t\t// Skip non-target files so other plugins (and esbuild) can process them\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst code = await fs.readFile(args.path, \"utf8\");\n\t\t\t\tconst result = await babel.transformAsync(code, {\n\t\t\t\t\tfilename: args.path,\n\t\t\t\t\tsourceMaps: false,\n\t\t\t\t\tbabelrc: false,\n\t\t\t\t\tconfigFile: false,\n\t\t\t\t\t// ORDER MATTERS: Reanimated plugin MUST BE LAST\n\t\t\t\t\tplugins: [\n\t\t\t\t\t\t// Needed by Reanimated on web per docs\n\t\t\t\t\t\t\"@babel/plugin-transform-export-namespace-from\",\n\t\t\t\t\t\t// Handle Flow types present in some RN libs\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"@babel/plugin-transform-flow-strip-types\",\n\t\t\t\t\t\t\t{ allowDeclareFields: true },\n\t\t\t\t\t\t],\n\t\t\t\t\t\t// MUST be last\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"react-native-reanimated/plugin\",\n\t\t\t\t\t\t\t{ relativeSourceLocation: true },\n\t\t\t\t\t\t],\n\t\t\t\t\t],\n\t\t\t\t\tpresets: [], // esbuild handles TS/JSX syntax; no preset-env/preset-react\n\t\t\t\t\tcaller: { name: \"esbuild\" },\n\t\t\t\t\t// Let Babel parse TS/JSX/Flow; keep it broad\n\t\t\t\t\tparserOpts: { plugins: [\"jsx\", \"typescript\"] },\n\t\t\t\t\tgeneratorOpts: { decoratorsBeforeExport: true },\n\t\t\t\t});\n\n\t\t\t\treturn {\n\t\t\t\t\t// biome-ignore lint/style/noNonNullAssertion: <explanation>\n\t\t\t\t\tcontents: result!.code!,\n\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: <explanation>\n\t\t\t\t\tloader: pickLoader(args.path) as any,\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t};\n}\n\nfunction pickLoader(file: string) {\n\tconst ext = path.extname(file).toLowerCase();\n\tif (ext === \".tsx\") return \"tsx\";\n\tif (ext === \".ts\") return \"ts\";\n\tif (ext === \".jsx\") return \"jsx\";\n\t// For .js: many RN libs contain JSX; be permissive\n\treturn \"jsx\";\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\n// stripFlowWithBabel.ts\nimport * as babel from \"@babel/core\";\n\nexport function stripFlowWithBabel() {\n\tconst filter = /\\.(m|c)?jsx?$/;\n\treturn {\n\t\tname: \"strip-flow-with-babel\",\n\t\t// biome-ignore lint/suspicious/noExplicitAny: <explanation>\n\t\tsetup(b: any) {\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: <explanation>\n\t\t\tb.onLoad({ filter }, async (args: any) => {\n\t\t\t\t// Only process react-native core files that contain Flow\n\t\t\t\tif (!args.path.includes(`${path.sep}react-native${path.sep}`)) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst code = await fs.readFile(args.path, \"utf8\");\n\t\t\t\tconst out = await babel.transformAsync(code, {\n\t\t\t\t\tfilename: args.path,\n\t\t\t\t\tbabelrc: false,\n\t\t\t\t\tconfigFile: false,\n\t\t\t\t\tplugins: [\n\t\t\t\t\t\t// Use Hermes parser to handle modern Flow syntax (as casts, type predicates, mapped types, etc.)\n\t\t\t\t\t\t\"babel-plugin-syntax-hermes-parser\",\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"@babel/plugin-transform-flow-strip-types\",\n\t\t\t\t\t\t\t{ allowDeclareFields: true },\n\t\t\t\t\t\t],\n\t\t\t\t\t],\n\t\t\t\t\tsourceMaps: false,\n\t\t\t\t});\n\t\t\t\t// biome-ignore lint/style/noNonNullAssertion: <explanation>\n\t\t\t\treturn { contents: out!.code!, loader: \"jsx\" };\n\t\t\t});\n\t\t},\n\t};\n}\n"],"mappings":"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","names":["existsSync","path","findUp","path","path","path","build","mkdir","readFile","writeFile","path","fs","path","fs","path","babel","path","readFile","mkdir","writeFile","buildAndPublish","build","buildAndPublish","path","existsSync","findUp"]}
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/cli/env-bool.ts","../../src/cli/mobile.ts","../../src/cli/file.ts","../../src/cli/sdk.ts","../../src/cli/load-metro-config.ts","../../src/cli/valid-view-type.ts","../../src/cli/mobile-rspack.ts","../../src/cli/web.ts","../../src/cli/reanimated-bable.ts","../../src/cli/strip-flow.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { parseArgs } from \"node:util\";\nimport { findUp } from \"find-up\";\nimport qrcode from \"qrcode-terminal\";\nimport { rimraf } from \"rimraf\";\nimport { envBool } from \"./env-bool\";\nimport { buildAndPublish, createMobileBuild } from \"./mobile\";\nimport { bundleWithRspack } from \"./mobile-rspack\";\nimport { env } from \"./sdk\";\nimport { buildAndPublish as buildAndPublishWeb } from \"./web\";\n\nasync function main() {\n\tconst args = parseArgs({\n\t\toptions: {\n\t\t\tios: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t},\n\t\t\tandroid: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t},\n\t\t\tweb: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t},\n\t\t\tmetro: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t},\n\t\t},\n\t\tstrict: true,\n\t\tallowPositionals: true,\n\t\targs: process.argv.slice(2),\n\t});\n\n\tconst [command] = args.positionals;\n\n\tif (command === \"install\") {\n\t\tawait handleInstall();\n\t\treturn;\n\t}\n\n\tlet shouldBuild = true;\n\tlet shouldUpload = true;\n\tlet shouldClean = true;\n\tif (command === \"build\") {\n\t\tshouldUpload = false;\n\t} else if (command === \"ship\") {\n\t\tshouldBuild = true;\n\t\tshouldUpload = true;\n\t} else if (command === \"upload\") {\n\t\tshouldBuild = false;\n\t\tshouldClean = false;\n\t} else if (command === \"clean\") {\n\t\tshouldBuild = false;\n\t\tshouldUpload = false;\n\t} else {\n\t\tconsole.error(\n\t\t\t`Usage:\n\twhop-react-native ship [--ios] [--android] [--web] [--metro] # runs build and then publishes it as a dev build to whop.\n\twhop-react-native build [--ios] [--android] [--web] [--metro] # builds your app into a distributable bundle in the build/ directory.\n\twhop-react-native upload [--ios] [--android] [--web] # uploads the existing build directory to whop.\n\twhop-react-native clean # cleans the build directory.\n\nOptions:\n\t--metro Use Metro instead of Rspack for mobile builds (slower, for compatibility)`,\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\tconst root = await getRootProjectDirectory();\n\n\tif (shouldClean) {\n\t\tif (envBool(\"WRN_FULL_CLEAN\")) {\n\t\t\tawait cleanBuildDirectory(root);\n\t\t} else {\n\t\t\tawait cleanEntrypointsDirectory(root);\n\t\t}\n\t}\n\n\tconst didProvidePlatform =\n\t\targs.values.ios || args.values.android || args.values.web;\n\n\t// Rspack is the default bundler (faster), Metro is fallback for compatibility\n\tconst useMetro = args.values.metro || envBool(\"WRN_USE_METRO\");\n\tconst opts = { shouldBuild, shouldUpload };\n\tconst promises: Promise<void>[] = [];\n\n\t// Determine bundler (rspack by default, metro as fallback)\n\tconst bundler = useMetro ? \"metro\" : \"rspack\";\n\tif (shouldBuild) {\n\t\tconsole.log(` ℹ︎ using ${bundler} for mobile builds`);\n\t}\n\n\tif (args.values.ios || !didProvidePlatform) {\n\t\tif (useMetro) {\n\t\t\tpromises.push(buildAndPublish(root, \"ios\", opts));\n\t\t} else {\n\t\t\tpromises.push(buildAndPublishWithRspack(root, \"ios\", opts));\n\t\t}\n\t}\n\tif (args.values.android || !didProvidePlatform) {\n\t\tif (useMetro) {\n\t\t\tpromises.push(buildAndPublish(root, \"android\", opts));\n\t\t} else {\n\t\t\tpromises.push(buildAndPublishWithRspack(root, \"android\", opts));\n\t\t}\n\t}\n\tif (args.values.web || !didProvidePlatform) {\n\t\tpromises.push(buildAndPublishWeb(root, opts));\n\t}\n\n\tawait Promise.all(promises);\n}\n\nasync function buildAndPublishWithRspack(\n\troot: string,\n\tplatform: \"ios\" | \"android\",\n\t{\n\t\tshouldBuild = true,\n\t\tshouldUpload = true,\n\t}: { shouldBuild: boolean; shouldUpload: boolean },\n) {\n\tif (shouldBuild) {\n\t\tawait bundleWithRspack(root, platform);\n\t}\n\tif (shouldUpload) {\n\t\tawait createMobileBuild(root, platform);\n\t}\n}\n\nasync function cleanBuildDirectory(root: string) {\n\tconst buildDirectory = path.join(root, \"build\");\n\tif (existsSync(buildDirectory)) {\n\t\tawait rimraf(buildDirectory);\n\t}\n\tconsole.log(\" ✔︎ cleaned build directory\");\n}\n\nasync function cleanEntrypointsDirectory(root: string) {\n\tconst buildDirectory = path.join(root, \"build\", \"entrypoints\");\n\tif (existsSync(buildDirectory)) {\n\t\tawait rimraf(buildDirectory);\n\t}\n\tconsole.log(\" ✔︎ cleaned build entrypoints directory\");\n}\n\nasync function getRootProjectDirectory() {\n\tconst file = await findUp(\"package.json\", { cwd: process.cwd() });\n\tif (!file) {\n\t\tthrow new Error(\n\t\t\t\"please run this command inside a whop react native project\",\n\t\t);\n\t}\n\tconst root = path.dirname(file);\n\treturn root;\n}\n\nasync function handleInstall() {\n\tconst appId = env(\"NEXT_PUBLIC_WHOP_APP_ID\");\n\tconst installLink = `https://whop.com/apps/${appId}/install`;\n\n\tconsole.log(`\nOpen this link in your browser to install the app into your whop.\n${installLink}\n\nOr scan the QR code with your iPhone:\n\t`);\n\n\tqrcode.generate(installLink, { small: true });\n}\n\nmain()\n\t.catch((err) => {\n\t\tconsole.error(err);\n\t\tprocess.exit(1);\n\t})\n\t.then(() => {\n\t\tprocess.exit(0);\n\t});\n","/**\n * Check if an environment variable is set to a truthy value.\n * Accepts: \"1\", \"true\", \"yes\" (case-insensitive)\n */\nexport function envBool(name: string): boolean {\n\tconst value = process.env[name]?.toLowerCase();\n\treturn value === \"1\" || value === \"true\" || value === \"yes\";\n}\n","import { existsSync, readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { mkdir, rename, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getDefaultConfig, mergeConfig } from \"@react-native/metro-config\";\nimport { findUp } from \"find-up\";\nimport JSZip from \"jszip\";\nimport { type ReportableEvent, type Reporter, runBuild } from \"metro\";\nimport { envBool } from \"./env-bool\";\nimport { getChecksum, uploadFile } from \"./file\";\nimport { loadMetroConfig } from \"./load-metro-config\";\nimport { AI_PROMPT_ID, APP_ID, COMPANY_ID, whopSdk } from \"./sdk\";\nimport { getSupportedAppViewTypes } from \"./valid-view-type\";\n\nexport async function buildAndPublish(\n\troot: string,\n\tplatform: \"ios\" | \"android\",\n\t{\n\t\tshouldBuild = true,\n\t\tshouldUpload = true,\n\t}: { shouldBuild: boolean; shouldUpload: boolean } = {\n\t\tshouldBuild: true,\n\t\tshouldUpload: true,\n\t},\n) {\n\tif (shouldBuild) {\n\t\tawait bundle(root, platform);\n\t}\n\tif (shouldUpload) {\n\t\tawait createMobileBuild(root, platform);\n\t}\n}\n\nexport async function bundle(root: string, platform: \"ios\" | \"android\") {\n\tawait makeEntrypoint(root, platform);\n\n\tconst outputFile = path.join(\n\t\troot,\n\t\t\"build\",\n\t\t\"output\",\n\t\tplatform,\n\t\t\"main_js_bundle\",\n\t);\n\n\tconst cacheDir =\n\t\tprocess.env.WRN_METRO_CACHE_DIRECTORY || path.join(root, \"build\", \"cache\");\n\tconst isCacheDisabled = envBool(\"WRN_DISABLE_METRO_CACHE\");\n\tconst remoteCacheUrl = process.env.WRN_REMOTE_METRO_CACHE_URL;\n\n\tawait mkdir(path.dirname(outputFile), { recursive: true });\n\n\tconst babelLocation = require.resolve(\"@babel/runtime/package\");\n\n\tconst bableNodeModules = await findUp(\"node_modules\", {\n\t\tcwd: babelLocation,\n\t\ttype: \"directory\",\n\t});\n\n\tif (!bableNodeModules) {\n\t\tthrow new Error(\"babel node_modules parent folder not found\");\n\t}\n\n\tconst defaultConfig = getDefaultConfig(root);\n\tconst projectConfig = await loadMetroConfig(root);\n\n\tconst defaultMetroConfig = mergeConfig(defaultConfig, projectConfig);\n\n\tconst metroConfig = mergeConfig(defaultMetroConfig, {\n\t\tprojectRoot: root,\n\t\ttransformer: {\n\t\t\tbabelTransformerPath: require.resolve(\n\t\t\t\t\"./whop-react-native-babel-transformer.js\",\n\t\t\t),\n\t\t},\n\t\tcacheStores: ({ FileStore, HttpStore }) => {\n\t\t\tif (isCacheDisabled) return [];\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: types are cooked here\n\t\t\tconst caches: any[] = [\n\t\t\t\tnew FileStore({\n\t\t\t\t\troot: cacheDir,\n\t\t\t\t}),\n\t\t\t];\n\t\t\tif (remoteCacheUrl) {\n\t\t\t\tcaches.push(new HttpStore({ endpoint: remoteCacheUrl }));\n\t\t\t}\n\t\t\treturn caches;\n\t\t},\n\t\tcacheVersion: process.env.WRN_METRO_CACHE_VERSION,\n\t\twatchFolders: [root, path.resolve(root, \"node_modules\"), bableNodeModules],\n\t\treporter: new CustomReporter(),\n\t\tresolver: {\n\t\t\tnodeModulesPaths: [\n\t\t\t\t...(defaultMetroConfig.resolver?.nodeModulesPaths ?? []),\n\t\t\t\tbableNodeModules,\n\t\t\t],\n\t\t},\n\t});\n\n\tawait runBuild(metroConfig, {\n\t\tdev: false,\n\t\tentry: `build/entrypoints/${platform}/index.js`,\n\t\tminify: false,\n\t\tplatform: platform,\n\t\tsourceMap: false,\n\t\tout: outputFile,\n\t});\n\n\tawait rename(\n\t\t`${outputFile}.js`,\n\t\tpath.join(root, \"build\", \"output\", platform, \"main_js_bundle.hbc\"),\n\t);\n\n\tconsole.log(` ✔︎ [${platform}] bundle created`);\n}\n\n// getSupportedAppViewTypes moved to valid-view-type.ts\n\nasync function makeEntrypoint(\n\troot: string,\n\tplatform: \"ios\" | \"android\",\n): Promise<string> {\n\tconst entrypoint = path.join(\n\t\troot,\n\t\t\"build\",\n\t\t\"entrypoints\",\n\t\tplatform,\n\t\t\"index.js\",\n\t);\n\n\tconst files = await getSupportedAppViewTypes(root);\n\n\tconst pascalCase = (str: string) =>\n\t\tstr\n\t\t\t.split(\"-\")\n\t\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n\t\t\t.join(\"\");\n\n\tconst imports = files.map(\n\t\t(file) =>\n\t\t\t`import { ${pascalCase(file)} } from \"../../../src/views/${file}\";`,\n\t);\n\tconst registry = files.map(\n\t\t(file) =>\n\t\t\t`AppRegistry.registerComponent(\"${pascalCase(file)}\", () => ${pascalCase(\n\t\t\t\tfile,\n\t\t\t)});`,\n\t);\n\n\tconst entrypointContent = `import { AppRegistry } from \"react-native\";\n${imports.join(\"\\n\")}\n\n${registry.join(\"\\n\")}\n`;\n\n\tconst entrypointDir = path.dirname(entrypoint);\n\tawait mkdir(entrypointDir, { recursive: true });\n\tawait writeFile(entrypoint, entrypointContent, \"utf-8\");\n\n\tconsole.log(` ✔︎ [${platform}] entrypoint created`);\n\n\treturn entrypoint;\n}\n\nexport async function createMobileBuild(\n\troot: string,\n\tplatform: \"ios\" | \"android\",\n) {\n\tconst viewTypes = await getSupportedAppViewTypes(root);\n\n\tconst fullDirectory = path.join(root, \"build\", \"output\", platform);\n\n\t// Check if the directory contains a file called `main_js_bundle.hbc`\n\tconst mainJsBundle = path.join(fullDirectory, \"main_js_bundle.hbc\");\n\n\tif (!existsSync(mainJsBundle)) {\n\t\tthrow new Error(`main_js_bundle.hbc not found in ${fullDirectory}`);\n\t}\n\n\t// check that that folder only contains the main_js_bundle.hbc file and an optional `assets` folder\n\tconst files = readdirSync(fullDirectory);\n\tif (\n\t\tfiles.length > 2 ||\n\t\tfiles.length < 1 ||\n\t\t!files.includes(\"main_js_bundle.hbc\")\n\t) {\n\t\tthrow new Error(\n\t\t\t\"Directory must contain only the main_js_bundle.hbc file and an optional `assets` folder\",\n\t\t);\n\t}\n\tif (files.length === 2 && !files.includes(\"assets\")) {\n\t\tthrow new Error(\n\t\t\t\"Directory must contain only the main_js_bundle.hbc file and an optional `assets` folder\",\n\t\t);\n\t}\n\n\t// Zip the directory\n\tconst zipData = await zipDirectory(fullDirectory);\n\n\tconst checksum = await getChecksum(zipData);\n\n\tconsole.log(` ✔︎ [${platform}] build zipped with checksum: ${checksum}`);\n\n\tconst fileName = `app_build_${platform}.zip`;\n\tconst uploadedFile = await uploadFile(zipData, fileName, \"application/zip\");\n\n\tconsole.log(\n\t\t` ✔︎ [${platform}] uploaded build: ${fileName} (${(\n\t\t\tzipData.length / 1024\n\t\t).toFixed(0)} KB)`,\n\t);\n\n\tconst build = await whopSdk.appBuilds.create({\n\t\tattachment: { id: uploadedFile.id },\n\t\tchecksum,\n\t\tapp_id: APP_ID,\n\t\tplatform,\n\t\tai_prompt_id: AI_PROMPT_ID,\n\t\tsupported_app_view_types: viewTypes.map(\n\t\t\t(view) =>\n\t\t\t\t({\n\t\t\t\t\t\"experience-view\": \"hub\" as const,\n\t\t\t\t\t\"discover-view\": \"discover\" as const,\n\t\t\t\t\t\"dashboard-view\": \"dashboard\" as const,\n\t\t\t\t})[view],\n\t\t),\n\t});\n\n\tif (!build) {\n\t\tthrow new Error(\"Failed to create app build\");\n\t}\n\n\tconst companyPart = COMPANY_ID ? `${COMPANY_ID}/` : \"\";\n\tconst dashboardUrl = `https://whop.com/dashboard/${companyPart}developer/apps/${APP_ID}/builds/?platform=${platform}`;\n\n\tconsole.log(`\\n ✔︎ [${platform}] deployed as development build ✔︎\n - build id: ${build.id}\n - view types: ${build.supported_app_view_types.join(\", \")}\n - promote to production here: ${dashboardUrl}\\n`);\n\n\treturn build;\n}\n\nasync function zipDirectory(\n\tdirectory: string,\n): Promise<Buffer<ArrayBufferLike>> {\n\tconst zip = new JSZip();\n\n\t// Recursively add files to zip\n\tfunction addFilesToZip(currentPath: string, relativePath = \"\") {\n\t\tconst items = readdirSync(currentPath);\n\n\t\tfor (const item of items) {\n\t\t\tconst fullPath = path.join(currentPath, item);\n\t\t\tconst zipPath = relativePath ? path.join(relativePath, item) : item;\n\t\t\tconst stats = statSync(fullPath);\n\n\t\t\tif (stats.isDirectory()) {\n\t\t\t\taddFilesToZip(fullPath, zipPath);\n\t\t\t} else {\n\t\t\t\tconst fileContent = readFileSync(fullPath);\n\t\t\t\tzip.file(zipPath, fileContent);\n\t\t\t}\n\t\t}\n\t}\n\n\taddFilesToZip(directory);\n\n\t// Generate zip file\n\tconst zipData = await zip.generateAsync({ type: \"nodebuffer\" });\n\n\treturn zipData;\n}\n\nclass CustomReporter implements Reporter {\n\tupdate(event: ReportableEvent) {\n\t\t// Do nothing.\n\t}\n}\n","import { createHash } from \"node:crypto\";\nimport { whopSdk } from \"./sdk\";\n\nexport async function uploadFile(\n\tdata: Buffer<ArrayBufferLike>,\n\tname: string,\n\t_contentType: string,\n) {\n\tconst uploadedFile = await whopSdk.files.upload(data, {\n\t\tfilename: name,\n\t});\n\n\treturn uploadedFile;\n}\n\nexport async function getChecksum(data: Buffer<ArrayBufferLike>) {\n\tconst hash = createHash(\"sha256\");\n\thash.update(data);\n\treturn hash.digest(\"hex\");\n}\n","import Whop from \"@whop/sdk\";\nimport { config } from \"dotenv\";\n\nconfig({\n path: [\".env\", \".env.local\", \".env.development\", \".env.production\"],\n});\n\nexport function env(key: string) {\n const value = process.env[key];\n if (!value) {\n throw new Error(`Missing environment variable: ${key}`);\n }\n return value;\n}\n\nconst BASE_URL = process.env.WHOP_BASE_URL;\n\nexport const COMPANY_ID = process.env.NEXT_PUBLIC_WHOP_COMPANY_ID;\nexport const APP_ID = env(\"NEXT_PUBLIC_WHOP_APP_ID\");\nexport const AI_PROMPT_ID = process.env.AI_PROMPT_ID;\n\nconst headersJSON = process.env.WHOP_EXTRA_API_HEADERS_JSON;\nlet parsedExtraHeaders: Record<string, string> | undefined = undefined;\n\ntry {\n if (headersJSON) {\n parsedExtraHeaders = JSON.parse(headersJSON);\n }\n} catch (e) {\n console.error(\"FAILED TO PARSE EXTRA WHOP API HEADERS\", e);\n}\n\nexport const whopSdk = new Whop({\n appID: APP_ID,\n baseURL: BASE_URL ? new URL(\"/api/v1\", BASE_URL).href : undefined,\n defaultHeaders: parsedExtraHeaders,\n});\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { loadConfig } from \"metro\";\n\nexport async function loadMetroConfig(projectRoot: string) {\n\tconst file = fs.existsSync(path.join(projectRoot, \"metro.config.js\"));\n\tif (!file) return {};\n\treturn await loadConfig({ cwd: projectRoot }, {});\n}\n","import { readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport const VALID_VIEW_TYPES = [\n\t\"experience-view\",\n\t\"discover-view\",\n\t\"dashboard-view\",\n] as const;\n\nexport async function getSupportedAppViewTypes(\n\troot: string,\n): Promise<(typeof VALID_VIEW_TYPES)[number][]> {\n\tconst views = await readdir(path.join(root, \"src\", \"views\"), {\n\t\twithFileTypes: true,\n\t\trecursive: false,\n\t});\n\tconst files = views\n\t\t.filter((file) => file.isFile())\n\t\t.map((file) => file.name.split(\".\")[0])\n\t\t.filter((file) => !!file);\n\n\tconst validViews = files.filter((file) =>\n\t\tVALID_VIEW_TYPES.includes(file as (typeof VALID_VIEW_TYPES)[number]),\n\t) as (typeof VALID_VIEW_TYPES)[number][];\n\n\tif (validViews.length === 0) {\n\t\tthrow new Error(\n\t\t\t`No valid views found, please create a view in the src/views folder and name it with a valid view type: ${VALID_VIEW_TYPES.join(\", \")}`,\n\t\t);\n\t}\n\n\treturn validViews;\n}\n","import { existsSync, readdirSync } from \"node:fs\";\nimport { mkdir, rename, unlink, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getSupportedAppViewTypes } from \"./valid-view-type\";\n\n// Path to our custom Flow loader (in the CLI package's dist)\nconst flowLoaderPath = path.join(__dirname, \"rspack-flow-loader.js\");\n\n// Path to our custom Reanimated loader (transforms worklets with Babel)\nconst reanimatedLoaderPath = path.join(__dirname, \"rspack-reanimated-loader.js\");\n\n// Dynamic import of @rspack/core to avoid requiring it at CLI startup\n// This allows the CLI to work even if @rspack/core is not installed (e.g., when using --metro)\nasync function loadRspack(root: string) {\n\ttry {\n\t\t// Try to resolve from the app's node_modules first\n\t\tconst rspackPath = require.resolve(\"@rspack/core\", { paths: [root] });\n\t\treturn require(rspackPath);\n\t} catch {\n\t\t// Fall back to the CLI package's node_modules\n\t\treturn require(\"@rspack/core\");\n\t}\n}\n\n// Dynamic import of @callstack/repack for RepackTargetPlugin\nasync function loadRepack(root: string) {\n\ttry {\n\t\tconst repackPath = require.resolve(\"@callstack/repack\", { paths: [root] });\n\t\treturn require(repackPath);\n\t} catch {\n\t\treturn require(\"@callstack/repack\");\n\t}\n}\n\n/**\n * Check if Flow files were pre-transformed at Docker build time.\n * If so, we can skip the Babel Flow loader and use SWC directly.\n */\nfunction isFlowPreTransformed(root: string): boolean {\n\tconst markerFile = path.join(root, \"node_modules/.flow-pretransformed\");\n\treturn existsSync(markerFile);\n}\n\n/**\n * Get React Native's initialization modules that must run before app code.\n * These set up console, global, error handling, etc.\n */\nfunction getReactNativeInitModules(root: string): string[] {\n\tconst reactNativePath = path.dirname(\n\t\trequire.resolve(\"react-native/package.json\", { paths: [root] })\n\t);\n\t\n\t// Get polyfills (console.js, error-guard.js)\n\tconst getPolyfills = require(path.join(reactNativePath, \"rn-get-polyfills.js\"));\n\tconst polyfills: string[] = getPolyfills();\n\t\n\t// InitializeCore sets up the runtime (global, __DEV__, etc.)\n\tconst initializeCore = path.join(reactNativePath, \"Libraries/Core/InitializeCore.js\");\n\t\n\treturn [...polyfills, initializeCore];\n}\n\n/**\n * Create a polyfill file for Web APIs not available in Hermes.\n * This runs after RN init (so global/self exist) but before app code.\n * Uses platform-specific path to avoid race conditions when iOS/Android build in parallel.\n */\nasync function createHermesPolyfills(root: string, platform: \"ios\" | \"android\"): Promise<string> {\n\tconst polyfillDir = path.join(root, \"build\", \"entrypoints\", platform);\n\tawait mkdir(polyfillDir, { recursive: true });\n\tconst polyfillPath = path.join(polyfillDir, \"hermes-polyfills.js\");\n\t\n\tconst polyfillCode = `\n// Polyfills for Web APIs not available in Hermes\n// This runs after React Native's InitializeCore, so 'global' is available\n\n(function(g) {\n // TextDecoder/TextEncoder (needed by jose/JWT libraries)\n if (typeof g.TextDecoder === 'undefined') {\n g.TextDecoder = function TextDecoder(encoding) {\n if (encoding && encoding !== 'utf-8' && encoding !== 'utf8') {\n throw new Error('TextDecoder polyfill only supports UTF-8');\n }\n };\n g.TextDecoder.prototype.decode = function(input) {\n if (!input) return '';\n var bytes = new Uint8Array(input.buffer || input);\n var result = '';\n for (var i = 0; i < bytes.length; i++) {\n result += String.fromCharCode(bytes[i]);\n }\n try {\n return decodeURIComponent(escape(result));\n } catch (e) {\n return result;\n }\n };\n }\n \n if (typeof g.TextEncoder === 'undefined') {\n g.TextEncoder = function TextEncoder() {};\n g.TextEncoder.prototype.encode = function(str) {\n var utf8 = unescape(encodeURIComponent(str || ''));\n var result = new Uint8Array(utf8.length);\n for (var i = 0; i < utf8.length; i++) {\n result[i] = utf8.charCodeAt(i);\n }\n return result;\n };\n }\n \n // URL polyfill (minimal, for libraries that need it before RN's kicks in)\n if (typeof g.URL === 'undefined') {\n g.URL = function URL(url, base) {\n if (base && typeof base === 'string' && !/^[a-z][a-z0-9+.-]*:/i.test(url)) {\n url = base.replace(/\\\\/[^\\\\/]*$/, '/') + url;\n }\n this.href = url || '';\n var match = this.href.match(/^([a-z][a-z0-9+.-]*:)?\\\\/\\\\/([^\\\\/:]*)(:[0-9]+)?(\\\\/[^?#]*)?(\\\\?[^#]*)?(#.*)?$/i);\n if (match) {\n this.protocol = match[1] || '';\n this.hostname = match[2] || '';\n this.port = (match[3] || '').slice(1);\n this.pathname = match[4] || '/';\n this.search = match[5] || '';\n this.hash = match[6] || '';\n this.host = this.hostname + (this.port ? ':' + this.port : '');\n this.origin = this.protocol + '//' + this.host;\n } else {\n this.protocol = ''; this.hostname = ''; this.port = '';\n this.pathname = this.href; this.search = ''; this.hash = '';\n this.host = ''; this.origin = '';\n }\n };\n g.URL.prototype.toString = function() { return this.href; };\n }\n \n // URLSearchParams polyfill (minimal)\n if (typeof g.URLSearchParams === 'undefined') {\n g.URLSearchParams = function URLSearchParams(init) {\n this._params = [];\n if (typeof init === 'string') {\n init = init.replace(/^\\\\?/, '');\n var pairs = init.split('&');\n for (var i = 0; i < pairs.length; i++) {\n var pair = pairs[i].split('=');\n if (pair[0]) {\n this._params.push([decodeURIComponent(pair[0]), decodeURIComponent(pair[1] || '')]);\n }\n }\n }\n };\n g.URLSearchParams.prototype.get = function(name) {\n for (var i = 0; i < this._params.length; i++) {\n if (this._params[i][0] === name) return this._params[i][1];\n }\n return null;\n };\n g.URLSearchParams.prototype.toString = function() {\n return this._params.map(function(p) {\n return encodeURIComponent(p[0]) + '=' + encodeURIComponent(p[1]);\n }).join('&');\n };\n }\n})(typeof globalThis !== 'undefined' ? globalThis : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : this);\n`;\n\t\n\tawait writeFile(polyfillPath, polyfillCode);\n\treturn polyfillPath;\n}\n\nexport async function bundleWithRspack(\n\troot: string,\n\tplatform: \"ios\" | \"android\",\n) {\n\t// Load rspack and repack dynamically from the app's node_modules\n\tconst rspackModule = await loadRspack(root);\n\tconst { rspack } = rspackModule;\n\tconst Repack = await loadRepack(root);\n\n\tconst entryFile = await makeEntrypoint(root, platform);\n\t\n\t// Get React Native initialization modules\n\tconst rnInitModules = getReactNativeInitModules(root);\n\t\n\t// Create Hermes polyfills (TextDecoder, URL, etc.)\n\t// Uses platform-specific path to avoid race conditions during parallel builds\n\tconst hermesPolyfills = await createHermesPolyfills(root, platform);\n\n\tconst outputDir = path.join(root, \"build\", \"output\", platform);\n\tawait mkdir(outputDir, { recursive: true });\n\n\tconst outputFile = path.join(outputDir, \"main_js_bundle.js\");\n\n\t// Check if Flow files were pre-transformed at Docker build time\n\tconst flowPreTransformed = isFlowPreTransformed(root);\n\tif (flowPreTransformed) {\n\t\tconsole.log(` ℹ︎ [${platform}] using pre-transformed Flow files (fast path)`);\n\t}\n\n\t// Build module rules based on whether Flow was pre-transformed\n\t// biome-ignore lint/suspicious/noExplicitAny: dynamic rspack types\n\tconst moduleRules: any[] = [\n\t\t// Allow extensionless imports in ESM modules (e.g., @rn-primitives)\n\t\t{\n\t\t\ttest: /\\.m?js$/,\n\t\t\tresolve: {\n\t\t\t\tfullySpecified: false,\n\t\t\t},\n\t\t},\n\t];\n\n\tif (flowPreTransformed) {\n\t\t// Fast path: Flow already stripped, use SWC for everything\n\t\tmoduleRules.push({\n\t\t\ttest: /\\.[cm]?[jt]sx?$/,\n\t\t\tuse: {\n\t\t\t\tloader: \"builtin:swc-loader\",\n\t\t\t\toptions: {\n\t\t\t\t\tjsc: {\n\t\t\t\t\t\tparser: {\n\t\t\t\t\t\t\tsyntax: \"typescript\",\n\t\t\t\t\t\t\ttsx: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttransform: {\n\t\t\t\t\t\t\treact: {\n\t\t\t\t\t\t\t\truntime: \"automatic\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\ttype: \"javascript/auto\",\n\t\t});\n\t} else {\n\t\t// Slow path: Need Babel to strip Flow from react-native core\n\t\tmoduleRules.push(\n\t\t\t// Strip Flow types from react-native core files FIRST\n\t\t\t{\n\t\t\t\ttest: /\\.jsx?$/,\n\t\t\t\tinclude: [\n\t\t\t\t\t/node_modules[/\\\\]react-native[/\\\\]/,\n\t\t\t\t\t/node_modules[/\\\\]@react-native[/\\\\]/,\n\t\t\t\t],\n\t\t\t\tuse: [\n\t\t\t\t\t// Then process with SWC\n\t\t\t\t\t{\n\t\t\t\t\t\tloader: \"builtin:swc-loader\",\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tjsc: {\n\t\t\t\t\t\t\t\tparser: {\n\t\t\t\t\t\t\t\t\tsyntax: \"ecmascript\",\n\t\t\t\t\t\t\t\t\tjsx: true,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\ttransform: {\n\t\t\t\t\t\t\t\t\treact: {\n\t\t\t\t\t\t\t\t\t\truntime: \"automatic\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t// First strip Flow types with Babel\n\t\t\t\t\t{\n\t\t\t\t\t\tloader: flowLoaderPath,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\ttype: \"javascript/auto\",\n\t\t\t},\n\t\t\t// App code and other node_modules: JS/TS/JSX/TSX via SWC\n\t\t\t{\n\t\t\t\ttest: /\\.[cm]?[jt]sx?$/,\n\t\t\t\texclude: [\n\t\t\t\t\t/node_modules[/\\\\]react-native[/\\\\]/,\n\t\t\t\t\t/node_modules[/\\\\]@react-native[/\\\\]/,\n\t\t\t\t],\n\t\t\t\tuse: {\n\t\t\t\t\tloader: \"builtin:swc-loader\",\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tjsc: {\n\t\t\t\t\t\t\tparser: {\n\t\t\t\t\t\t\t\tsyntax: \"typescript\",\n\t\t\t\t\t\t\t\ttsx: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttransform: {\n\t\t\t\t\t\t\t\treact: {\n\t\t\t\t\t\t\t\t\truntime: \"automatic\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttype: \"javascript/auto\",\n\t\t\t},\n\t\t);\n\t}\n\n\t// Reanimated worklet transformation (must run before SWC)\n\t// This transforms files containing 'worklet' directive using Babel\n\tmoduleRules.unshift({\n\t\ttest: /\\.[jt]sx?$/,\n\t\tinclude: [\n\t\t\t/node_modules[/\\\\]react-native-reanimated[/\\\\]/,\n\t\t\t// Also include app code that might have worklets\n\t\t\tpath.join(root, \"src\"),\n\t\t],\n\t\tuse: {\n\t\t\tloader: reanimatedLoaderPath,\n\t\t},\n\t\tenforce: \"pre\", // Run before other loaders\n\t});\n\n\t// Assets - inline as data URLs\n\tmoduleRules.push({\n\t\ttest: /\\.(png|jpg|jpeg|gif|webp|svg)$/,\n\t\ttype: \"asset/inline\",\n\t});\n\n\t// Check if we have a pre-warmed cache from Docker build\n\tconst cacheDir = path.join(root, \"node_modules/.cache/rspack\");\n\tconst hasCacheDir = existsSync(cacheDir);\n\tif (hasCacheDir) {\n\t\tconsole.log(` ℹ︎ [${platform}] using pre-warmed Rspack cache`);\n\t}\n\n\t// biome-ignore lint/suspicious/noExplicitAny: dynamic rspack types\n\tconst config: any = {\n\t\tmode: \"production\",\n\t\tcontext: root,\n\t\t// Disable default target - we're targeting React Native's Hermes runtime\n\t\ttarget: false,\n\t\t// Entry order: RN init -> Hermes polyfills -> app code\n\t\tentry: [...rnInitModules, hermesPolyfills, entryFile],\n\t\toutput: {\n\t\t\tpath: outputDir,\n\t\t\tfilename: \"main_js_bundle.js\",\n\t\t\tpublicPath: \"/\",\n\t\t\tclean: false,\n\t\t\t// Use 'self' as global object (initialized by our banner)\n\t\t\tglobalObject: \"self\",\n\t\t\t// Disable async chunk loading - RN needs single bundle\n\t\t\tchunkLoading: false,\n\t\t\tchunkFormat: false,\n\t\t},\n\t\t// Enable caching (required for experiments.cache)\n\t\tcache: true,\n\t\t// Persistent filesystem cache (Rspack 1.3+ format)\n\t\texperiments: {\n\t\t\tcache: {\n\t\t\t\ttype: \"persistent\",\n\t\t\t\tversion: \"rspack-rn-v2\",\n\t\t\t\tstorage: {\n\t\t\t\t\ttype: \"filesystem\",\n\t\t\t\t\tdirectory: cacheDir,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tresolve: {\n\t\t\t// Get Re.Pack's resolve options for React Native\n\t\t\t...Repack.getResolveOptions({ platform }),\n\t\t\t// Ensure we can resolve from the app's node_modules\n\t\t\tmodules: [\n\t\t\t\tpath.join(root, \"node_modules\"),\n\t\t\t\t\"node_modules\",\n\t\t\t],\n\t\t\t// Use react-native field first in package.json\n\t\t\tmainFields: [\"react-native\", \"browser\", \"module\", \"main\"],\n\t\t\t// Re-enable exports field resolution (Re.Pack disables it)\n\t\t\tconditionNames: [\"react-native\", \"import\", \"require\", \"default\"],\n\t\t\texportsFields: [\"exports\"],\n\t\t\t// Platform-specific extensions - order matters! Most specific first\n\t\t\t// Re.Pack's extensions have literal [platform] which doesn't work\n\t\t\textensions: [\n\t\t\t\t`.${platform}.ts`,\n\t\t\t\t`.${platform}.tsx`,\n\t\t\t\t`.${platform}.js`,\n\t\t\t\t`.${platform}.jsx`,\n\t\t\t\t\".native.ts\",\n\t\t\t\t\".native.tsx\",\n\t\t\t\t\".native.js\",\n\t\t\t\t\".native.jsx\",\n\t\t\t\t\".ts\",\n\t\t\t\t\".tsx\",\n\t\t\t\t\".js\",\n\t\t\t\t\".jsx\",\n\t\t\t\t\".json\",\n\t\t\t],\n\t\t\t// Alias react-native-reanimated to lib/module to avoid TypeScript source\n\t\t\talias: {\n\t\t\t\t...Repack.getResolveOptions({ platform }).alias,\n\t\t\t\t\"react-native-reanimated\": path.join(root, \"node_modules/react-native-reanimated/lib/module\"),\n\t\t\t},\n\t\t},\n\t\tresolveLoader: {\n\t\t\t// Allow resolving loaders from the CLI package's node_modules\n\t\t\tmodules: [\n\t\t\t\tpath.join(__dirname, \"..\"), // dist/ folder\n\t\t\t\tpath.dirname(__dirname), // package root\n\t\t\t\t\"node_modules\",\n\t\t\t],\n\t\t},\n\t\tmodule: {\n\t\t\trules: moduleRules,\n\t\t},\n\t\tplugins: [\n\t\t\t// NOTE: We intentionally do NOT use RepackTargetPlugin because it sets\n\t\t\t// chunkLoading: 'jsonp' which creates separate chunk files that can't be\n\t\t\t// loaded in React Native. Instead, we manually set up what we need.\n\t\t\t\n\t\t\t// Initialize 'self' global (normally done by RepackTargetPlugin)\n\t\t\tnew rspack.BannerPlugin({\n\t\t\t\traw: true,\n\t\t\t\tentryOnly: true,\n\t\t\t\tbanner: `var self = self || this || new Function(\"return this\")() || {};`,\n\t\t\t}),\n\t\t\t// Define globals for React Native\n\t\t\tnew rspack.DefinePlugin({\n\t\t\t\t__DEV__: JSON.stringify(false),\n\t\t\t\t\"process.env.NODE_ENV\": JSON.stringify(\"production\"),\n\t\t\t}),\n\t\t],\n\t\toptimization: {\n\t\t\tminimize: false, // Keep readable for debugging\n\t\t\t// Disable code splitting - React Native needs a single bundle\n\t\t\tsplitChunks: false,\n\t\t\truntimeChunk: false,\n\t\t},\n\t\tdevtool: false,\n\t\tstats: \"errors-warnings\",\n\t};\n\n\tawait new Promise<void>((resolve, reject) => {\n\t\trspack(config, (err, stats) => {\n\t\t\tif (err) {\n\t\t\t\treject(err);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (stats?.hasErrors()) {\n\t\t\t\tconst info = stats.toJson();\n\t\t\t\tconsole.error(info.errors);\n\t\t\t\treject(new Error(\"Rspack build failed\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve();\n\t\t});\n\t});\n\n\t// Rename to .hbc extension for compatibility\n\tconst finalFile = path.join(outputDir, \"main_js_bundle.hbc\");\n\tif (!existsSync(outputFile)) {\n\t\tthrow new Error(\n\t\t\t`[${platform}] Rspack completed but bundle file was not created at ${outputFile}. ` +\n\t\t\t`Check the build output for warnings or errors.`\n\t\t);\n\t}\n\tawait rename(outputFile, finalFile);\n\n\t// Log all files created for debugging\n\tconst outputFiles = readdirSync(outputDir);\n\tconsole.log(` ℹ︎ [${platform}] files created:`, outputFiles.join(\", \"));\n\t\n\t// Clean up any extra files Rspack might have created (e.g., LICENSE.txt, .map files)\n\t// The upload expects only main_js_bundle.hbc and optionally an assets folder\n\tfor (const file of outputFiles) {\n\t\tif (file !== \"main_js_bundle.hbc\" && file !== \"assets\") {\n\t\t\tawait unlink(path.join(outputDir, file));\n\t\t}\n\t}\n\n\tconsole.log(` ✔︎ [${platform}] bundle created (rspack)`);\n}\n\nasync function makeEntrypoint(\n\troot: string,\n\tplatform: \"ios\" | \"android\",\n): Promise<string> {\n\tconst entrypoint = path.join(\n\t\troot,\n\t\t\"build\",\n\t\t\"entrypoints\",\n\t\tplatform,\n\t\t\"index.js\",\n\t);\n\n\tconst files = await getSupportedAppViewTypes(root);\n\n\tconst pascalCase = (str: string) =>\n\t\tstr\n\t\t\t.split(\"-\")\n\t\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n\t\t\t.join(\"\");\n\n\tconst imports = files.map(\n\t\t(file) =>\n\t\t\t`import { ${pascalCase(file)} } from \"../../../src/views/${file}\";`,\n\t);\n\tconst registry = files.map(\n\t\t(file) =>\n\t\t\t`AppRegistry.registerComponent(\"${pascalCase(file)}\", () => ${pascalCase(\n\t\t\t\tfile,\n\t\t\t)});`,\n\t);\n\n\tconst entrypointContent = `import { AppRegistry } from \"react-native\";\n${imports.join(\"\\n\")}\n\n${registry.join(\"\\n\")}\n`;\n\n\tconst entrypointDir = path.dirname(entrypoint);\n\tawait mkdir(entrypointDir, { recursive: true });\n\tawait writeFile(entrypoint, entrypointContent, \"utf-8\");\n\n\tconsole.log(` ✔︎ [${platform}] entrypoint created`);\n\n\treturn entrypoint;\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { build } from \"esbuild\";\nimport { getChecksum, uploadFile } from \"./file\";\nimport { reanimatedBabelPlugin } from \"./reanimated-bable\";\nimport { AI_PROMPT_ID, APP_ID, COMPANY_ID, whopSdk } from \"./sdk\";\nimport { stripFlowWithBabel } from \"./strip-flow\";\nimport { getSupportedAppViewTypes } from \"./valid-view-type\";\n\nfunction aliasReactNativePlugin() {\n\treturn {\n\t\tname: \"alias-react-native\",\n\t\tsetup(b: import(\"esbuild\").PluginBuild) {\n\t\t\tb.onResolve({ filter: /^react-native$/ }, () => ({\n\t\t\t\tpath: require.resolve(\"react-native-web\"),\n\t\t\t}));\n\t\t},\n\t} satisfies import(\"esbuild\").Plugin;\n}\n\nfunction forceSingleReact() {\n\tconst map = new Map<string, string>([\n\t\t[\"react\", require.resolve(\"react\")],\n\t\t[\"react/jsx-runtime\", require.resolve(\"react/jsx-runtime\")],\n\t\t[\"react/jsx-dev-runtime\", require.resolve(\"react/jsx-dev-runtime\")],\n\t\t[\"react-dom\", require.resolve(\"react-dom\")],\n\t\t[\"react-dom/client\", require.resolve(\"react-dom/client\")],\n\t]);\n\n\tconst rx = /^(react(?:\\/jsx-(?:dev-)?runtime)?|react-dom(?:\\/client)?)$/;\n\n\treturn {\n\t\tname: \"force-single-react\",\n\t\tsetup(b: import(\"esbuild\").PluginBuild) {\n\t\t\t// biome-ignore lint/style/noNonNullAssertion: <explanation>\n\t\t\tb.onResolve({ filter: rx }, (args) => ({ path: map.get(args.path)! }));\n\t\t},\n\t} satisfies import(\"esbuild\").Plugin;\n}\n\nfunction toPascalCase(str: string) {\n\treturn str\n\t\t.split(\"-\")\n\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n\t\t.join(\"\");\n}\n\nasync function makeWebEntrypoint(root: string) {\n\tconst files = await getSupportedAppViewTypes(root);\n\n\tconst packageJsonPath = path.join(root, \"package.json\");\n\tconst packageJson = JSON.parse(await readFile(packageJsonPath, \"utf-8\"));\n\tconst hasReactNativeReanimated =\n\t\tpackageJson.dependencies?.[\"react-native-reanimated\"];\n\n\tconst imports = files.map(\n\t\t(file) =>\n\t\t\t`import { ${toPascalCase(file)} } from \"../../../src/views/${file}\";`,\n\t);\n\tconst registry = files.map(\n\t\t(file) =>\n\t\t\t`AppRegistry.registerComponent(\"${toPascalCase(\n\t\t\t\tfile,\n\t\t\t)}\", () => WhopNavigationWrapper(React, \"${toPascalCase(\n\t\t\t\tfile,\n\t\t\t)}\", ${toPascalCase(file)}));`,\n\t);\n\n\tconst defaultKey = toPascalCase(files[0] ?? \"experience-view\");\n\tconst reanimatedImport = hasReactNativeReanimated\n\t\t? `import \"react-native-reanimated\";`\n\t\t: \"\";\n\n\tconst entry = `import { AppRegistry } from \"react-native\";\nimport * as React from \"react\";\nimport { WhopNavigationWrapper } from \"@whop/react-native/web\";\n${reanimatedImport}\n\n${imports.join(\"\\n\")}\n\n${registry.join(\"\\n\")}\n\nconst viewType = new URLSearchParams(window.location.search).get(\"app_view\") ?? \"${defaultKey}\";\n\nconst root = document.getElementById(\"root\") || (() => {\n\tconst d = document.createElement(\"div\");\n\td.id = \"root\";\n\tdocument.body.appendChild(d);\n\treturn d;\n})();\nAppRegistry.runApplication(viewType, { rootTag: root });\n`;\n\n\tconst entryFile = path.join(root, \"build\", \"entrypoints\", \"web\", \"index.tsx\");\n\tawait mkdir(path.dirname(entryFile), { recursive: true });\n\tawait writeFile(entryFile, entry, \"utf-8\");\n\n\treturn entryFile;\n}\n\nexport async function bundleWeb(root: string) {\n\tconst entry = await makeWebEntrypoint(root);\n\n\tconst outDir = path.join(root, \"build\", \"output\", \"web\");\n\tawait mkdir(outDir, { recursive: true });\n\n\tawait build({\n\t\tentryPoints: [entry],\n\t\toutfile: path.join(outDir, \"main.js\"),\n\t\tbundle: true,\n\t\tminify: false,\n\t\tformat: \"esm\",\n\t\tplatform: \"browser\",\n\t\tsourcemap: false,\n\t\tjsx: \"automatic\",\n\t\tmainFields: [\"browser\", \"module\", \"main\"],\n\t\tconditions: [\"browser\", \"import\", \"default\"],\n\t\tdefine: {\n\t\t\tprocess: \"{}\",\n\t\t\t\"process.env\": \"{}\",\n\t\t\t\"process.env.NODE_ENV\": '\"production\"',\n\t\t\t__DEV__: \"false\",\n\t\t\t\"process.env.NEXT_PUBLIC_WHOP_APP_ID\": `\"${APP_ID}\"`,\n\t\t\t// Some RN libraries (e.g., RNGH) expect a Node-like global in the browser\n\t\t\tglobal: \"globalThis\",\n\t\t},\n\t\tresolveExtensions: [\n\t\t\t\".web.tsx\",\n\t\t\t\".web.ts\",\n\t\t\t\".web.js\",\n\t\t\t\".tsx\",\n\t\t\t\".ts\",\n\t\t\t\".jsx\",\n\t\t\t\".js\",\n\t\t\t\".mjs\",\n\t\t],\n\t\tloader: {\n\t\t\t\".png\": \"dataurl\",\n\t\t\t\".jpg\": \"dataurl\",\n\t\t\t\".jpeg\": \"dataurl\",\n\t\t\t\".svg\": \"dataurl\",\n\t\t\t\".ttf\": \"dataurl\",\n\t\t\t\".woff\": \"dataurl\",\n\t\t\t\".woff2\": \"dataurl\",\n\t\t\t\".js\": \"jsx\",\n\t\t\t\".jsx\": \"jsx\",\n\t\t\t\".mjs\": \"jsx\",\n\t\t},\n\t\tplugins: [\n\t\t\tforceSingleReact(),\n\t\t\taliasReactNativePlugin(),\n\t\t\treanimatedBabelPlugin(),\n\t\t\tstripFlowWithBabel(),\n\t\t\t{\n\t\t\t\tname: \"force-native-web-stub\",\n\t\t\t\tsetup(b) {\n\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: <explanation>\n\t\t\t\t\tb.onResolve({ filter: /^\\.\\/native-whop-core$/ }, (args: any) => {\n\t\t\t\t\t\t// Always resolve the local source file so extension resolution (.web.ts) applies\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tpath: path.join(args.resolveDir, \"native-whop-core\"),\n\t\t\t\t\t\t\tnamespace: \"file\",\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t});\n\n\tconst html = `<!doctype html>\n<html>\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\t\t<title>Whop App (Web)</title>\n\t\t<style>\n\t\t\t#root {\n\t\t\t\twidth: 100vw;\n\t\t\t\theight: 100vh;\n\t\t\t\tmargin: 0;\n\t\t\t\tpadding: 0;\n\t\t\t\toverflow: hidden;\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-direction: column;\n\t\t\t\talign-items: stretch;\n\t\t\t\tjustify-content: start;\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div id=\"root\"></div>\n\t\t<script type=\"module\" src=\"./main.js\"></script>\n\t</body>\n</html>`;\n\tawait writeFile(path.join(outDir, \"index.html\"), html, \"utf-8\");\n\n\tconsole.log(\" ✔︎ [web] bundle created at build/output/web/main.js\");\n}\n\nexport async function buildAndPublish(\n\troot: string,\n\t{\n\t\tshouldBuild = true,\n\t\tshouldUpload = true,\n\t}: { shouldBuild: boolean; shouldUpload: boolean } = {\n\t\tshouldBuild: true,\n\t\tshouldUpload: true,\n\t},\n) {\n\tif (shouldBuild) {\n\t\tawait bundleWeb(root);\n\t}\n\tif (shouldUpload) {\n\t\tawait createWebBuild(root);\n\t}\n}\n\nexport async function createWebBuild(root: string) {\n\tconst viewTypes = await getSupportedAppViewTypes(root);\n\n\tconst fullDirectory = path.join(root, \"build\", \"output\", \"web\");\n\tconst mainJsFile = path.join(fullDirectory, \"main.js\");\n\n\t// Verify bundle exists\n\ttry {\n\t\tawait readFile(mainJsFile);\n\t} catch {\n\t\tthrow new Error(`main.js not found in ${fullDirectory}`);\n\t}\n\n\tconst buf = await readFile(mainJsFile);\n\tconst checksum = await getChecksum(buf);\n\n\tconsole.log(` ✔︎ [web] build checksummed: ${checksum}`);\n\n\tconst fileName = `rnweb_${checksum}.js`;\n\tconst uploadedFile = await uploadFile(\n\t\tbuf,\n\t\tfileName,\n\t\t\"application/javascript\",\n\t);\n\n\tconsole.log(\n\t\t` ✔︎ [web] uploaded build: ${fileName} (${(buf.length / 1024).toFixed(\n\t\t\t0,\n\t\t)} KB)`,\n\t);\n\n\tconst build = await whopSdk.appBuilds.create({\n\t\tattachment: { id: uploadedFile.id },\n\t\tchecksum,\n\t\tapp_id: APP_ID,\n\t\tplatform: \"web\",\n\t\tai_prompt_id: AI_PROMPT_ID,\n\t\tsupported_app_view_types: viewTypes.map(\n\t\t\t(view) =>\n\t\t\t\t({\n\t\t\t\t\t\"experience-view\": \"hub\" as const,\n\t\t\t\t\t\"discover-view\": \"discover\" as const,\n\t\t\t\t\t\"dashboard-view\": \"dashboard\" as const,\n\t\t\t\t})[view],\n\t\t),\n\t});\n\n\tif (!build) {\n\t\tthrow new Error(\"Failed to create app build\");\n\t}\n\n\tconst companyPart = COMPANY_ID ? `${COMPANY_ID}/` : \"\";\n\tconst dashboardUrl = `https://whop.com/dashboard/${companyPart}developer/apps/${APP_ID}/builds/?platform=web`;\n\n\tconsole.log(\n\t\t`\\n ✔︎ [web] deployed as development build ✔︎\\n - build id: ${\n\t\t\tbuild.id\n\t\t}\\n - view types: ${build.supported_app_view_types.join(\n\t\t\t\", \",\n\t\t)}\\n - promote to production here: ${dashboardUrl}\\n`,\n\t);\n\n\treturn build;\n}\n","/**\n * esbuild plugin that runs Babel with react-native-reanimated/plugin\n * on files containing worklet directives.\n */\nimport * as babel from \"@babel/core\";\nimport type { Plugin } from \"esbuild\";\n\n// Regex to detect worklet directives\nconst WORKLET_DIRECTIVE_RX = /['\"]worklet['\"]/;\n\nexport function reanimatedBabelPlugin(): Plugin {\n\treturn {\n\t\tname: \"reanimated-babel\",\n\t\tsetup(b: import(\"esbuild\").PluginBuild) {\n\t\t\tb.onLoad({ filter: /\\.[jt]sx?$/ }, async (args) => {\n\t\t\t\t// Skip non-target files so other plugins (and esbuild) can process them\n\t\t\t\tconst fs = await import(\"node:fs/promises\");\n\t\t\t\tconst source = await fs.readFile(args.path, \"utf8\");\n\n\t\t\t\t// Only transform files with worklet directives\n\t\t\t\tif (!WORKLET_DIRECTIVE_RX.test(source)) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\tconst isTS = args.path.endsWith(\".ts\") || args.path.endsWith(\".tsx\");\n\t\t\t\tconst hasJSX = args.path.endsWith(\"x\") || args.path.endsWith(\".js\");\n\n\t\t\t\t// Build syntax plugins based on file type\n\t\t\t\tconst syntaxPlugins: babel.PluginItem[] = [];\n\t\t\t\tif (isTS) {\n\t\t\t\t\tsyntaxPlugins.push([\"@babel/plugin-syntax-typescript\", { isTSX: args.path.endsWith(\"x\") }]);\n\t\t\t\t} else if (hasJSX) {\n\t\t\t\t\t// For .js files that may contain JSX (like react-native-reanimated's lib/module)\n\t\t\t\t\tsyntaxPlugins.push(\"@babel/plugin-syntax-jsx\");\n\t\t\t\t}\n\n\t\t\t\tconst result = await babel.transformAsync(source, {\n\t\t\t\t\tfilename: args.path,\n\t\t\t\t\tbabelrc: false,\n\t\t\t\t\tconfigFile: false,\n\t\t\t\t\tplugins: [\n\t\t\t\t\t\t...syntaxPlugins,\n\t\t\t\t\t\t// Transform worklets\n\t\t\t\t\t\t\"react-native-reanimated/plugin\",\n\t\t\t\t\t],\n\t\t\t\t\tpresets: [], // esbuild handles TS/JSX syntax; no preset-env/preset-react\n\t\t\t\t\tcaller: { name: \"esbuild\" },\n\t\t\t\t\tsourceMaps: \"inline\",\n\t\t\t\t});\n\n\t\t\t\tif (!result?.code) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\t// Map file extension to esbuild loader\n\t\t\t\tconst ext = args.path.split(\".\").pop() ?? \"ts\";\n\t\t\t\tconst loaderMap: Record<string, \"tsx\" | \"jsx\" | \"ts\"> = {\n\t\t\t\t\ttsx: \"tsx\",\n\t\t\t\t\tjsx: \"jsx\",\n\t\t\t\t\tts: \"ts\",\n\t\t\t\t\tjs: \"jsx\", // .js files in RN often contain JSX\n\t\t\t\t};\n\n\t\t\t\treturn {\n\t\t\t\t\tcontents: result.code,\n\t\t\t\t\tloader: loaderMap[ext] ?? \"ts\",\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t};\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\n// stripFlowWithBabel.ts\nimport * as babel from \"@babel/core\";\n\nexport function stripFlowWithBabel() {\n\tconst filter = /\\.(m|c)?jsx?$/;\n\treturn {\n\t\tname: \"strip-flow-with-babel\",\n\t\t// biome-ignore lint/suspicious/noExplicitAny: <explanation>\n\t\tsetup(b: any) {\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: <explanation>\n\t\t\tb.onLoad({ filter }, async (args: any) => {\n\t\t\t\t// Only process react-native core files that contain Flow\n\t\t\t\tconst isReactNative =\n\t\t\t\t\targs.path.includes(`${path.sep}react-native${path.sep}`) ||\n\t\t\t\t\targs.path.includes(`${path.sep}@react-native${path.sep}`);\n\t\t\t\tif (!isReactNative) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst code = await fs.readFile(args.path, \"utf8\");\n\t\t\t\tconst out = await babel.transformAsync(code, {\n\t\t\t\t\tfilename: args.path,\n\t\t\t\t\tbabelrc: false,\n\t\t\t\t\tconfigFile: false,\n\t\t\t\t\tplugins: [\n\t\t\t\t\t\t// Use Hermes parser to handle modern Flow syntax (as casts, type predicates, mapped types, etc.)\n\t\t\t\t\t\t\"babel-plugin-syntax-hermes-parser\",\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"@babel/plugin-transform-flow-strip-types\",\n\t\t\t\t\t\t\t{ allowDeclareFields: true },\n\t\t\t\t\t\t],\n\t\t\t\t\t],\n\t\t\t\t\tsourceMaps: false,\n\t\t\t\t});\n\t\t\t\t// biome-ignore lint/style/noNonNullAssertion: <explanation>\n\t\t\t\treturn { contents: out!.code!, loader: \"jsx\" };\n\t\t\t});\n\t\t},\n\t};\n}\n"],"mappings":"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","names":["existsSync","path","findUp","path","path","path","build","existsSync","readdirSync","mkdir","rename","writeFile","path","path","existsSync","mkdir","writeFile","makeEntrypoint","config","rename","readdirSync","mkdir","readFile","writeFile","path","fs","fs","path","babel","path","readFile","mkdir","writeFile","buildAndPublish","build","buildAndPublish","path","existsSync","findUp"]}
@@ -0,0 +1,30 @@
1
+ // Custom loader to strip Flow types from react-native core files
2
+ // This runs in the CLI package's context where @babel/core is available
3
+
4
+ const babel = require("@babel/core");
5
+
6
+ module.exports = function flowLoader(source) {
7
+ const callback = this.async();
8
+
9
+ babel.transformAsync(source, {
10
+ filename: this.resourcePath,
11
+ babelrc: false,
12
+ configFile: false,
13
+ plugins: [
14
+ // Use Hermes parser to handle modern Flow syntax
15
+ "babel-plugin-syntax-hermes-parser",
16
+ [
17
+ "@babel/plugin-transform-flow-strip-types",
18
+ { allowDeclareFields: true },
19
+ ],
20
+ ],
21
+ sourceMaps: false,
22
+ })
23
+ .then((result) => {
24
+ // Fall back to original source if Babel returns null/undefined
25
+ callback(null, result?.code || source);
26
+ })
27
+ .catch((err) => {
28
+ callback(err);
29
+ });
30
+ };
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Rspack loader that transforms react-native-reanimated worklets using Babel.
3
+ * Only processes files that contain 'worklet' directive.
4
+ */
5
+ const babel = require("@babel/core");
6
+
7
+ // Regex to detect worklet directives
8
+ const WORKLET_DIRECTIVE_RX = /['"]worklet['"]/;
9
+
10
+ module.exports = function reanimatedLoader(source) {
11
+ const callback = this.async();
12
+
13
+ // Only transform files with worklet directives
14
+ if (!WORKLET_DIRECTIVE_RX.test(source)) {
15
+ callback(null, source);
16
+ return;
17
+ }
18
+
19
+ const filename = this.resourcePath;
20
+ const isTS = filename.endsWith(".ts") || filename.endsWith(".tsx");
21
+ const hasJSX = filename.endsWith("x") || filename.endsWith(".js");
22
+
23
+ // Build syntax plugins based on file type
24
+ const syntaxPlugins = [];
25
+ if (isTS) {
26
+ syntaxPlugins.push(["@babel/plugin-syntax-typescript", { isTSX: filename.endsWith("x") }]);
27
+ } else if (hasJSX) {
28
+ // For .js files that may contain JSX (like react-native-reanimated's lib/module)
29
+ syntaxPlugins.push("@babel/plugin-syntax-jsx");
30
+ }
31
+
32
+ babel.transform(
33
+ source,
34
+ {
35
+ filename,
36
+ babelrc: false,
37
+ configFile: false,
38
+ plugins: [
39
+ ...syntaxPlugins,
40
+ // Transform worklets
41
+ "react-native-reanimated/plugin",
42
+ ],
43
+ presets: [],
44
+ caller: { name: "rspack" },
45
+ sourceMaps: false,
46
+ },
47
+ (err, result) => {
48
+ if (err) {
49
+ callback(err);
50
+ return;
51
+ }
52
+ callback(null, result?.code || source);
53
+ }
54
+ );
55
+ };
package/dist/lib/web.mjs CHANGED
@@ -187,25 +187,10 @@ function makeModalComponent(R) {
187
187
  { className: "whop-rn-modal-panel-inner" },
188
188
  [route ? props.render(route) : null]
189
189
  );
190
- const closeButton = R.createElement(
191
- "button",
192
- {
193
- type: "button",
194
- className: "whop-rn-modal-close",
195
- "aria-label": "Close modal",
196
- onClick: dismiss
197
- },
198
- "\xD7"
199
- );
200
- const header = R.createElement(
201
- "div",
202
- { className: "whop-rn-modal-header" },
203
- [closeButton]
204
- );
205
190
  const panel = R.createElement(
206
191
  "div",
207
192
  { className: "whop-rn-modal-panel", role: "document" },
208
- [header, panelInner]
193
+ [panelInner]
209
194
  );
210
195
  const onOverlayClick = (e) => {
211
196
  if (e.target === e.currentTarget) dismiss();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/web-router.ts"],"sourcesContent":["import type React from \"react\";\nimport type { FC } from \"react\";\nimport type { TWhopCoreNavigation } from \"./native-whop-core-stub\";\nimport type {\n\tDashboardViewProps,\n\tDiscoverViewProps,\n\tExperienceViewProps,\n} from \"./props\";\n\ntype AppReactComponent = {\n\tExperienceView: FC<ExperienceViewProps>;\n\tDiscoverView: FC<DiscoverViewProps>;\n\tDashboardView: FC<DashboardViewProps>;\n};\n\nfunction getNavigation(): TWhopCoreNavigation {\n\t// biome-ignore lint/suspicious/noExplicitAny: <explanation>\n\tconst anyWindow = window as any;\n\tif (typeof anyWindow !== \"undefined\" && anyWindow.whopCoreNavigation) {\n\t\treturn anyWindow.whopCoreNavigation;\n\t}\n\n\tthrow new Error(\n\t\t\"window.whopCoreNavigation is not defined. this method is only available in a web build\",\n\t);\n}\n\nfunction parseQueryParams() {\n\tconst params = new URLSearchParams(window.location.search);\n\tconst experienceId = params.get(\"experienceId\");\n\tconst companyId = params.get(\"companyId\");\n\tconst currentUserId = params.get(\"currentUserId\");\n\tconst restPath = params.get(\"restPath\");\n\tconst queryStr = params.get(\"query\");\n\n\tlet path: string[] = [];\n\tif (restPath) path = restPath.split(\"/\").filter(Boolean);\n\n\tconst appParams: Record<string, string> = {};\n\tif (queryStr) {\n\t\tconst obj = new URLSearchParams(queryStr);\n\t\tfor (const [key, value] of obj.entries()) {\n\t\t\tappParams[key] = value;\n\t\t}\n\t}\n\n\treturn {\n\t\texperienceId,\n\t\tcompanyId,\n\t\tcurrentUserId,\n\t\tpath,\n\t\tparams: appParams,\n\t};\n}\n\nfunction usePath(\n\tR: typeof React,\n\tinitialPath: string[],\n\tinitialParams: Record<string, string>,\n): { path: string[]; params: Record<string, string> } {\n\tconst navigation = getNavigation();\n\tconst path = R.useSyncExternalStore(\n\t\tnavigation.subscribeToPath,\n\t\tnavigation.getFullStack,\n\t);\n\tconst route = path.at(path.length - 1);\n\tconst actualPath = route ?? { path: initialPath, params: initialParams };\n\treturn actualPath;\n}\n\nfunction useSheet(R: typeof React) {\n\tconst navigation = getNavigation();\n\tconst sheet = R.useSyncExternalStore(\n\t\tnavigation.subscribeToSheet,\n\t\tnavigation.getCurrentSheet,\n\t);\n\treturn sheet;\n}\n\nexport function WhopNavigationWrapper<T extends keyof AppReactComponent>(\n\tR: typeof React,\n\tname: T,\n\tComponent: AppReactComponent[T],\n) {\n\tconst {\n\t\texperienceId,\n\t\tcompanyId,\n\t\tcurrentUserId,\n\t\tpath: initialPath,\n\t\tparams,\n\t} = parseQueryParams();\n\n\tconst ModalComponent = makeModalComponent(R);\n\n\tlet render: (route: {\n\t\tpath: string[];\n\t\tparams: Record<string, string>;\n\t}) => React.ReactNode;\n\n\tif (name === \"ExperienceView\") {\n\t\tif (!experienceId || !companyId) {\n\t\t\tthrow new Error(\"Missing required query params\");\n\t\t}\n\n\t\tconst C = Component as FC<ExperienceViewProps>;\n\n\t\trender = (route: {\n\t\t\tpath: string[];\n\t\t\tparams: Record<string, string>;\n\t\t}) => {\n\t\t\treturn R.createElement(C, {\n\t\t\t\texperienceId,\n\t\t\t\tcompanyId,\n\t\t\t\tcurrentUserId,\n\t\t\t\tpath: route.path,\n\t\t\t\tparams: route.params,\n\t\t\t});\n\t\t};\n\t}\n\n\tif (name === \"DashboardView\") {\n\t\tif (!companyId) {\n\t\t\tthrow new Error(\"Missing required query params\");\n\t\t}\n\n\t\tconst C = Component as FC<DashboardViewProps>;\n\n\t\trender = (route: {\n\t\t\tpath: string[];\n\t\t\tparams: Record<string, string>;\n\t\t}) => {\n\t\t\treturn R.createElement(C, {\n\t\t\t\tcompanyId,\n\t\t\t\tcurrentUserId,\n\t\t\t\tpath: route.path,\n\t\t\t\tparams: route.params,\n\t\t\t});\n\t\t};\n\t}\n\n\tif (name === \"DiscoverView\") {\n\t\tconst C = Component as FC<DiscoverViewProps>;\n\t\trender = (route: {\n\t\t\tpath: string[];\n\t\t\tparams: Record<string, string>;\n\t\t}) => {\n\t\t\treturn R.createElement(C, {\n\t\t\t\tcurrentUserId,\n\t\t\t\tpath: route.path,\n\t\t\t\tparams: route.params,\n\t\t\t});\n\t\t};\n\t}\n\n\treturn function AppWrapper() {\n\t\tconst path = usePath(R, initialPath, params);\n\t\tconst sheet = useSheet(R);\n\t\tconst sheetElement = R.createElement(ModalComponent, {\n\t\t\troute: sheet,\n\t\t\trender,\n\t\t});\n\t\treturn R.createElement(R.Fragment, null, [render(path), sheetElement]);\n\t};\n}\n\nfunction makeModalComponent(R: typeof React) {\n\tconst STYLE_ID = \"whop-rn-modal-styles\";\n\tconst ANIMATION_MS = 220;\n\n\tfunction ensureStylesInjected() {\n\t\tif (typeof document === \"undefined\") return;\n\t\tif (document.getElementById(STYLE_ID)) return;\n\t\tconst styleEl = document.createElement(\"style\");\n\t\tstyleEl.id = STYLE_ID;\n\t\tstyleEl.textContent = `\n\t\t\t.whop-rn-modal-overlay{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.45);opacity:0;pointer-events:none;transition:opacity ${ANIMATION_MS}ms ease;z-index:2147483647}\n\t\t\t.whop-rn-modal-overlay.open{opacity:1;pointer-events:auto}\n\t\t\t.whop-rn-modal-panel{background:var(--modal-bg,#fff);color:var(--modal-fg,#111);border-radius:12px;box-shadow:0 10px 30px rgba(0,0,0,0.2);max-width:min(calc(100vw - 32px),720px);width:100%;max-height:min(calc(100vh - 32px),85vh);overflow:auto;transform:translateY(8px) scale(0.98);opacity:0.98;transition:transform ${ANIMATION_MS + 20}ms ease,opacity ${ANIMATION_MS + 20}ms ease}\n\t\t\t.whop-rn-modal-overlay.open .whop-rn-modal-panel{transform:translateY(0) scale(1);opacity:1}\n\t\t\t.whop-rn-modal-header{display:flex;justify-content:flex-end}\n\t\t\t.whop-rn-modal-close{height:36px;width:36px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:8px;background:rgba(0,0,0,0.04);color:inherit;cursor:pointer;transition:background ${ANIMATION_MS}ms ease}\n\t\t\t.whop-rn-modal-close:hover{background:rgba(0,0,0,0.08)}\n\t\t\t.whop-rn-modal-close:focus{outline:2px solid rgba(59,130,246,0.6);outline-offset:2px}\n\t\t\t.whop-rn-modal-panel-inner{padding:0}\n\t\t\t@media (prefers-color-scheme: dark){.whop-rn-modal-panel{--modal-bg:#111416;--modal-fg:#e6e7e8;box-shadow:0 10px 30px rgba(0,0,0,0.7)}}\n\t\t`;\n\t\tdocument.head.appendChild(styleEl);\n\t}\n\n\treturn function ModalComponent(props: {\n\t\troute:\n\t\t\t| {\n\t\t\t\t\tpath: string[];\n\t\t\t\t\tparams: Record<string, string>;\n\t\t\t }\n\t\t\t| undefined\n\t\t\t| null;\n\t\trender: (route: {\n\t\t\tpath: string[];\n\t\t\tparams: Record<string, string>;\n\t\t}) => React.ReactNode;\n\t}) {\n\t\t// Manage mount/unmount to allow exit animations\n\t\tconst isOpen = !!props.route;\n\t\tconst [shouldRender, setShouldRender] = R.useState<boolean>(isOpen);\n\t\tconst [isVisible, setIsVisible] = R.useState<boolean>(isOpen);\n\t\tconst closeTimerRef = R.useRef<number | null>(null);\n\t\tconst mostRecentRouteRef = R.useRef<{\n\t\t\tpath: string[];\n\t\t\tparams: Record<string, string>;\n\t\t} | null>(null);\n\n\t\tif (props.route) mostRecentRouteRef.current = props.route;\n\n\t\tR.useEffect(() => {\n\t\t\tensureStylesInjected();\n\t\t\treturn () => {\n\t\t\t\tif (closeTimerRef.current !== null) {\n\t\t\t\t\twindow.clearTimeout(closeTimerRef.current);\n\t\t\t\t}\n\t\t\t};\n\t\t}, []);\n\n\t\tR.useEffect(() => {\n\t\t\tif (isOpen) {\n\t\t\t\tsetShouldRender(true);\n\t\t\t\t// Ensure next frame so transitions apply\n\t\t\t\twindow.requestAnimationFrame(() => setIsVisible(true));\n\t\t\t\tif (closeTimerRef.current !== null) {\n\t\t\t\t\twindow.clearTimeout(closeTimerRef.current);\n\t\t\t\t\tcloseTimerRef.current = null;\n\t\t\t\t}\n\t\t\t} else if (shouldRender) {\n\t\t\t\tsetIsVisible(false);\n\t\t\t\tif (closeTimerRef.current !== null) {\n\t\t\t\t\twindow.clearTimeout(closeTimerRef.current);\n\t\t\t\t}\n\t\t\t\tcloseTimerRef.current = window.setTimeout(() => {\n\t\t\t\t\tsetShouldRender(false);\n\t\t\t\t\tcloseTimerRef.current = null;\n\t\t\t\t}, ANIMATION_MS);\n\t\t\t}\n\t\t}, [isOpen, shouldRender]);\n\n\t\tconst overlayClass = isVisible\n\t\t\t? \"whop-rn-modal-overlay open\"\n\t\t\t: \"whop-rn-modal-overlay\";\n\n\t\tconst dismiss = R.useCallback((): void => {\n\t\t\ttry {\n\t\t\t\tgetNavigation().dismissSheet();\n\t\t\t} catch {\n\t\t\t\t// no-op when navigation is not available\n\t\t\t}\n\t\t}, []);\n\n\t\tR.useEffect(() => {\n\t\t\tif (!isOpen) return;\n\t\t\tconst onKeyDown = (e: KeyboardEvent) => {\n\t\t\t\tif (e.key === \"Escape\") dismiss();\n\t\t\t};\n\t\t\tdocument.addEventListener(\"keydown\", onKeyDown);\n\t\t\treturn () => document.removeEventListener(\"keydown\", onKeyDown);\n\t\t}, [isOpen, dismiss]);\n\n\t\tif (!shouldRender) return null;\n\n\t\tconst route = mostRecentRouteRef.current;\n\n\t\tconst panelInner = R.createElement(\n\t\t\t\"div\",\n\t\t\t{ className: \"whop-rn-modal-panel-inner\" },\n\t\t\t[route ? props.render(route) : null],\n\t\t);\n\n\t\tconst closeButton = R.createElement(\n\t\t\t\"button\",\n\t\t\t{\n\t\t\t\ttype: \"button\",\n\t\t\t\tclassName: \"whop-rn-modal-close\",\n\t\t\t\t\"aria-label\": \"Close modal\",\n\t\t\t\tonClick: dismiss,\n\t\t\t},\n\t\t\t\"×\",\n\t\t);\n\n\t\tconst header = R.createElement(\n\t\t\t\"div\",\n\t\t\t{ className: \"whop-rn-modal-header\" },\n\t\t\t[closeButton],\n\t\t);\n\n\t\tconst panel = R.createElement(\n\t\t\t\"div\",\n\t\t\t{ className: \"whop-rn-modal-panel\", role: \"document\" },\n\t\t\t[header, panelInner],\n\t\t);\n\n\t\tconst onOverlayClick = (e: React.MouseEvent<HTMLDivElement>): void => {\n\t\t\tif (e.target === e.currentTarget) dismiss();\n\t\t};\n\n\t\treturn R.createElement(\n\t\t\t\"div\",\n\t\t\t{\n\t\t\t\tclassName: overlayClass,\n\t\t\t\trole: \"dialog\",\n\t\t\t\t\"aria-modal\": \"true\",\n\t\t\t\tonClick: onOverlayClick,\n\t\t\t},\n\t\t\t[panel],\n\t\t);\n\t};\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/lib/web-router.ts"],"sourcesContent":["import type React from \"react\";\nimport type { FC } from \"react\";\nimport type { TWhopCoreNavigation } from \"./native-whop-core-stub\";\nimport type {\n\tDashboardViewProps,\n\tDiscoverViewProps,\n\tExperienceViewProps,\n} from \"./props\";\n\ntype AppReactComponent = {\n\tExperienceView: FC<ExperienceViewProps>;\n\tDiscoverView: FC<DiscoverViewProps>;\n\tDashboardView: FC<DashboardViewProps>;\n};\n\nfunction getNavigation(): TWhopCoreNavigation {\n\t// biome-ignore lint/suspicious/noExplicitAny: <explanation>\n\tconst anyWindow = window as any;\n\tif (typeof anyWindow !== \"undefined\" && anyWindow.whopCoreNavigation) {\n\t\treturn anyWindow.whopCoreNavigation;\n\t}\n\n\tthrow new Error(\n\t\t\"window.whopCoreNavigation is not defined. this method is only available in a web build\",\n\t);\n}\n\nfunction parseQueryParams() {\n\tconst params = new URLSearchParams(window.location.search);\n\tconst experienceId = params.get(\"experienceId\");\n\tconst companyId = params.get(\"companyId\");\n\tconst currentUserId = params.get(\"currentUserId\");\n\tconst restPath = params.get(\"restPath\");\n\tconst queryStr = params.get(\"query\");\n\n\tlet path: string[] = [];\n\tif (restPath) path = restPath.split(\"/\").filter(Boolean);\n\n\tconst appParams: Record<string, string> = {};\n\tif (queryStr) {\n\t\tconst obj = new URLSearchParams(queryStr);\n\t\tfor (const [key, value] of obj.entries()) {\n\t\t\tappParams[key] = value;\n\t\t}\n\t}\n\n\treturn {\n\t\texperienceId,\n\t\tcompanyId,\n\t\tcurrentUserId,\n\t\tpath,\n\t\tparams: appParams,\n\t};\n}\n\nfunction usePath(\n\tR: typeof React,\n\tinitialPath: string[],\n\tinitialParams: Record<string, string>,\n): { path: string[]; params: Record<string, string> } {\n\tconst navigation = getNavigation();\n\tconst path = R.useSyncExternalStore(\n\t\tnavigation.subscribeToPath,\n\t\tnavigation.getFullStack,\n\t);\n\tconst route = path.at(path.length - 1);\n\tconst actualPath = route ?? { path: initialPath, params: initialParams };\n\treturn actualPath;\n}\n\nfunction useSheet(R: typeof React) {\n\tconst navigation = getNavigation();\n\tconst sheet = R.useSyncExternalStore(\n\t\tnavigation.subscribeToSheet,\n\t\tnavigation.getCurrentSheet,\n\t);\n\treturn sheet;\n}\n\nexport function WhopNavigationWrapper<T extends keyof AppReactComponent>(\n\tR: typeof React,\n\tname: T,\n\tComponent: AppReactComponent[T],\n) {\n\tconst {\n\t\texperienceId,\n\t\tcompanyId,\n\t\tcurrentUserId,\n\t\tpath: initialPath,\n\t\tparams,\n\t} = parseQueryParams();\n\n\tconst ModalComponent = makeModalComponent(R);\n\n\tlet render: (route: {\n\t\tpath: string[];\n\t\tparams: Record<string, string>;\n\t}) => React.ReactNode;\n\n\tif (name === \"ExperienceView\") {\n\t\tif (!experienceId || !companyId) {\n\t\t\tthrow new Error(\"Missing required query params\");\n\t\t}\n\n\t\tconst C = Component as FC<ExperienceViewProps>;\n\n\t\trender = (route: {\n\t\t\tpath: string[];\n\t\t\tparams: Record<string, string>;\n\t\t}) => {\n\t\t\treturn R.createElement(C, {\n\t\t\t\texperienceId,\n\t\t\t\tcompanyId,\n\t\t\t\tcurrentUserId,\n\t\t\t\tpath: route.path,\n\t\t\t\tparams: route.params,\n\t\t\t});\n\t\t};\n\t}\n\n\tif (name === \"DashboardView\") {\n\t\tif (!companyId) {\n\t\t\tthrow new Error(\"Missing required query params\");\n\t\t}\n\n\t\tconst C = Component as FC<DashboardViewProps>;\n\n\t\trender = (route: {\n\t\t\tpath: string[];\n\t\t\tparams: Record<string, string>;\n\t\t}) => {\n\t\t\treturn R.createElement(C, {\n\t\t\t\tcompanyId,\n\t\t\t\tcurrentUserId,\n\t\t\t\tpath: route.path,\n\t\t\t\tparams: route.params,\n\t\t\t});\n\t\t};\n\t}\n\n\tif (name === \"DiscoverView\") {\n\t\tconst C = Component as FC<DiscoverViewProps>;\n\t\trender = (route: {\n\t\t\tpath: string[];\n\t\t\tparams: Record<string, string>;\n\t\t}) => {\n\t\t\treturn R.createElement(C, {\n\t\t\t\tcurrentUserId,\n\t\t\t\tpath: route.path,\n\t\t\t\tparams: route.params,\n\t\t\t});\n\t\t};\n\t}\n\n\treturn function AppWrapper() {\n\t\tconst path = usePath(R, initialPath, params);\n\t\tconst sheet = useSheet(R);\n\t\tconst sheetElement = R.createElement(ModalComponent, {\n\t\t\troute: sheet,\n\t\t\trender,\n\t\t});\n\t\treturn R.createElement(R.Fragment, null, [render(path), sheetElement]);\n\t};\n}\n\nfunction makeModalComponent(R: typeof React) {\n\tconst STYLE_ID = \"whop-rn-modal-styles\";\n\tconst ANIMATION_MS = 220;\n\n\tfunction ensureStylesInjected() {\n\t\tif (typeof document === \"undefined\") return;\n\t\tif (document.getElementById(STYLE_ID)) return;\n\t\tconst styleEl = document.createElement(\"style\");\n\t\tstyleEl.id = STYLE_ID;\n\t\tstyleEl.textContent = `\n\t\t\t.whop-rn-modal-overlay{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.45);opacity:0;pointer-events:none;transition:opacity ${ANIMATION_MS}ms ease;z-index:2147483647}\n\t\t\t.whop-rn-modal-overlay.open{opacity:1;pointer-events:auto}\n\t\t\t.whop-rn-modal-panel{background:var(--modal-bg,#fff);color:var(--modal-fg,#111);border-radius:12px;box-shadow:0 10px 30px rgba(0,0,0,0.2);max-width:min(calc(100vw - 32px),720px);width:100%;max-height:min(calc(100vh - 32px),85vh);overflow:auto;transform:translateY(8px) scale(0.98);opacity:0.98;transition:transform ${ANIMATION_MS + 20}ms ease,opacity ${ANIMATION_MS + 20}ms ease}\n\t\t\t.whop-rn-modal-overlay.open .whop-rn-modal-panel{transform:translateY(0) scale(1);opacity:1}\n\t\t\t.whop-rn-modal-header{display:flex;justify-content:flex-end}\n\t\t\t.whop-rn-modal-close{height:36px;width:36px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:8px;background:rgba(0,0,0,0.04);color:inherit;cursor:pointer;transition:background ${ANIMATION_MS}ms ease}\n\t\t\t.whop-rn-modal-close:hover{background:rgba(0,0,0,0.08)}\n\t\t\t.whop-rn-modal-close:focus{outline:2px solid rgba(59,130,246,0.6);outline-offset:2px}\n\t\t\t.whop-rn-modal-panel-inner{padding:0}\n\t\t\t@media (prefers-color-scheme: dark){.whop-rn-modal-panel{--modal-bg:#111416;--modal-fg:#e6e7e8;box-shadow:0 10px 30px rgba(0,0,0,0.7)}}\n\t\t`;\n\t\tdocument.head.appendChild(styleEl);\n\t}\n\n\treturn function ModalComponent(props: {\n\t\troute:\n\t\t\t| {\n\t\t\t\t\tpath: string[];\n\t\t\t\t\tparams: Record<string, string>;\n\t\t\t }\n\t\t\t| undefined\n\t\t\t| null;\n\t\trender: (route: {\n\t\t\tpath: string[];\n\t\t\tparams: Record<string, string>;\n\t\t}) => React.ReactNode;\n\t}) {\n\t\t// Manage mount/unmount to allow exit animations\n\t\tconst isOpen = !!props.route;\n\t\tconst [shouldRender, setShouldRender] = R.useState<boolean>(isOpen);\n\t\tconst [isVisible, setIsVisible] = R.useState<boolean>(isOpen);\n\t\tconst closeTimerRef = R.useRef<number | null>(null);\n\t\tconst mostRecentRouteRef = R.useRef<{\n\t\t\tpath: string[];\n\t\t\tparams: Record<string, string>;\n\t\t} | null>(null);\n\n\t\tif (props.route) mostRecentRouteRef.current = props.route;\n\n\t\tR.useEffect(() => {\n\t\t\tensureStylesInjected();\n\t\t\treturn () => {\n\t\t\t\tif (closeTimerRef.current !== null) {\n\t\t\t\t\twindow.clearTimeout(closeTimerRef.current);\n\t\t\t\t}\n\t\t\t};\n\t\t}, []);\n\n\t\tR.useEffect(() => {\n\t\t\tif (isOpen) {\n\t\t\t\tsetShouldRender(true);\n\t\t\t\t// Ensure next frame so transitions apply\n\t\t\t\twindow.requestAnimationFrame(() => setIsVisible(true));\n\t\t\t\tif (closeTimerRef.current !== null) {\n\t\t\t\t\twindow.clearTimeout(closeTimerRef.current);\n\t\t\t\t\tcloseTimerRef.current = null;\n\t\t\t\t}\n\t\t\t} else if (shouldRender) {\n\t\t\t\tsetIsVisible(false);\n\t\t\t\tif (closeTimerRef.current !== null) {\n\t\t\t\t\twindow.clearTimeout(closeTimerRef.current);\n\t\t\t\t}\n\t\t\t\tcloseTimerRef.current = window.setTimeout(() => {\n\t\t\t\t\tsetShouldRender(false);\n\t\t\t\t\tcloseTimerRef.current = null;\n\t\t\t\t}, ANIMATION_MS);\n\t\t\t}\n\t\t}, [isOpen, shouldRender]);\n\n\t\tconst overlayClass = isVisible\n\t\t\t? \"whop-rn-modal-overlay open\"\n\t\t\t: \"whop-rn-modal-overlay\";\n\n\t\tconst dismiss = R.useCallback((): void => {\n\t\t\ttry {\n\t\t\t\tgetNavigation().dismissSheet();\n\t\t\t} catch {\n\t\t\t\t// no-op when navigation is not available\n\t\t\t}\n\t\t}, []);\n\n\t\tR.useEffect(() => {\n\t\t\tif (!isOpen) return;\n\t\t\tconst onKeyDown = (e: KeyboardEvent) => {\n\t\t\t\tif (e.key === \"Escape\") dismiss();\n\t\t\t};\n\t\t\tdocument.addEventListener(\"keydown\", onKeyDown);\n\t\t\treturn () => document.removeEventListener(\"keydown\", onKeyDown);\n\t\t}, [isOpen, dismiss]);\n\n\t\tif (!shouldRender) return null;\n\n\t\tconst route = mostRecentRouteRef.current;\n\n\t\tconst panelInner = R.createElement(\n\t\t\t\"div\",\n\t\t\t{ className: \"whop-rn-modal-panel-inner\" },\n\t\t\t[route ? props.render(route) : null],\n\t\t);\n\n\t\tconst panel = R.createElement(\n\t\t\t\"div\",\n\t\t\t{ className: \"whop-rn-modal-panel\", role: \"document\" },\n\t\t\t[panelInner],\n\t\t);\n\n\t\tconst onOverlayClick = (e: React.MouseEvent<HTMLDivElement>): void => {\n\t\t\tif (e.target === e.currentTarget) dismiss();\n\t\t};\n\n\t\treturn R.createElement(\n\t\t\t\"div\",\n\t\t\t{\n\t\t\t\tclassName: overlayClass,\n\t\t\t\trole: \"dialog\",\n\t\t\t\t\"aria-modal\": \"true\",\n\t\t\t\tonClick: onOverlayClick,\n\t\t\t},\n\t\t\t[panel],\n\t\t);\n\t};\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@whop/react-native",
3
3
  "description": "React Native SDK for building embedded apps on Whop",
4
- "version": "0.1.14",
4
+ "version": "0.2.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/whopio/whop-sdk-ts",
@@ -43,8 +43,11 @@
43
43
  "@babel/plugin-transform-export-namespace-from": "7.27.1",
44
44
  "@babel/preset-env": "7.28.0",
45
45
  "@babel/runtime": "7.27.6",
46
+ "@callstack/repack": "5.2.3",
47
+ "@callstack/repack-plugin-reanimated": "5.2.3",
46
48
  "@react-native/babel-preset": "0.80.1",
47
49
  "@react-native/metro-config": "0.80.1",
50
+ "@rspack/core": "1.3.12",
48
51
  "@whop/sdk": "0.0.23",
49
52
  "dotenv": "16.5.0",
50
53
  "esbuild": "0.25.9",