@tanstack/create 0.63.9 → 0.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/add-to-app.js +5 -0
  3. package/dist/create-app.js +74 -16
  4. package/dist/custom-add-ons/shared.js +2 -0
  5. package/dist/file-helpers.js +14 -0
  6. package/dist/frameworks/react/add-ons/ai/info.json +1 -1
  7. package/dist/frameworks/react/add-ons/better-auth/info.json +1 -1
  8. package/dist/frameworks/react/add-ons/clerk/README.md +42 -1
  9. package/dist/frameworks/react/add-ons/clerk/assets/src/routes/demo/clerk.tsx +94 -11
  10. package/dist/frameworks/react/add-ons/clerk/info.json +1 -1
  11. package/dist/frameworks/react/add-ons/compiler/info.json +1 -1
  12. package/dist/frameworks/react/add-ons/convex/info.json +1 -1
  13. package/dist/frameworks/react/add-ons/drizzle/info.json +1 -1
  14. package/dist/frameworks/react/add-ons/mcp/info.json +1 -1
  15. package/dist/frameworks/react/add-ons/neon/info.json +1 -1
  16. package/dist/frameworks/react/add-ons/paraglide/info.json +1 -1
  17. package/dist/frameworks/react/add-ons/prisma/info.json +1 -1
  18. package/dist/frameworks/react/add-ons/shadcn/info.json +1 -1
  19. package/dist/frameworks/react/add-ons/strapi/info.json +1 -1
  20. package/dist/frameworks/react/add-ons/t3env/info.json +1 -1
  21. package/dist/frameworks/react/add-ons/workos/info.json +1 -1
  22. package/dist/frameworks/react/hosts/cloudflare/README.md +11 -0
  23. package/dist/frameworks/react/hosts/cloudflare/info.json +1 -1
  24. package/dist/frameworks/react/hosts/netlify/README.md +11 -0
  25. package/dist/frameworks/react/hosts/netlify/info.json +1 -1
  26. package/dist/frameworks/react/hosts/nitro/README.md +12 -0
  27. package/dist/frameworks/react/hosts/nitro/info.json +1 -1
  28. package/dist/frameworks/react/hosts/railway/README.md +10 -0
  29. package/dist/frameworks/react/hosts/railway/info.json +1 -1
  30. package/dist/frameworks/solid/add-ons/better-auth/info.json +1 -1
  31. package/dist/frameworks/solid/add-ons/convex/info.json +1 -1
  32. package/dist/frameworks/solid/add-ons/solid-ui/info.json +1 -1
  33. package/dist/frameworks/solid/add-ons/strapi/info.json +1 -1
  34. package/dist/frameworks/solid/add-ons/t3env/info.json +1 -1
  35. package/dist/frameworks/solid/hosts/cloudflare/README.md +11 -0
  36. package/dist/frameworks/solid/hosts/cloudflare/info.json +1 -1
  37. package/dist/frameworks/solid/hosts/netlify/README.md +11 -0
  38. package/dist/frameworks/solid/hosts/netlify/info.json +1 -1
  39. package/dist/frameworks/solid/hosts/nitro/README.md +12 -0
  40. package/dist/frameworks/solid/hosts/nitro/info.json +1 -1
  41. package/dist/frameworks/solid/hosts/railway/README.md +10 -0
  42. package/dist/frameworks/solid/hosts/railway/info.json +1 -1
  43. package/dist/index.js +1 -1
  44. package/dist/integrations/intent.js +25 -0
  45. package/dist/types/add-to-app.d.ts +1 -0
  46. package/dist/types/file-helpers.d.ts +1 -0
  47. package/dist/types/index.d.ts +1 -1
  48. package/dist/types/integrations/intent.d.ts +2 -0
  49. package/dist/types/types.d.ts +1 -0
  50. package/package.json +1 -1
  51. package/src/add-to-app.ts +7 -0
  52. package/src/create-app.ts +89 -22
  53. package/src/custom-add-ons/shared.ts +2 -0
  54. package/src/file-helpers.ts +20 -0
  55. package/src/frameworks/react/add-ons/ai/info.json +1 -1
  56. package/src/frameworks/react/add-ons/better-auth/info.json +1 -1
  57. package/src/frameworks/react/add-ons/clerk/README.md +42 -1
  58. package/src/frameworks/react/add-ons/clerk/assets/src/routes/demo/clerk.tsx +94 -11
  59. package/src/frameworks/react/add-ons/clerk/info.json +1 -1
  60. package/src/frameworks/react/add-ons/compiler/info.json +1 -1
  61. package/src/frameworks/react/add-ons/convex/info.json +1 -1
  62. package/src/frameworks/react/add-ons/drizzle/info.json +1 -1
  63. package/src/frameworks/react/add-ons/mcp/info.json +1 -1
  64. package/src/frameworks/react/add-ons/neon/info.json +1 -1
  65. package/src/frameworks/react/add-ons/paraglide/info.json +1 -1
  66. package/src/frameworks/react/add-ons/prisma/info.json +1 -1
  67. package/src/frameworks/react/add-ons/shadcn/info.json +1 -1
  68. package/src/frameworks/react/add-ons/strapi/info.json +1 -1
  69. package/src/frameworks/react/add-ons/t3env/info.json +1 -1
  70. package/src/frameworks/react/add-ons/workos/info.json +1 -1
  71. package/src/frameworks/react/hosts/cloudflare/README.md +11 -0
  72. package/src/frameworks/react/hosts/cloudflare/info.json +1 -1
  73. package/src/frameworks/react/hosts/netlify/README.md +11 -0
  74. package/src/frameworks/react/hosts/netlify/info.json +1 -1
  75. package/src/frameworks/react/hosts/nitro/README.md +12 -0
  76. package/src/frameworks/react/hosts/nitro/info.json +1 -1
  77. package/src/frameworks/react/hosts/railway/README.md +10 -0
  78. package/src/frameworks/react/hosts/railway/info.json +1 -1
  79. package/src/frameworks/solid/add-ons/better-auth/info.json +1 -1
  80. package/src/frameworks/solid/add-ons/convex/info.json +1 -1
  81. package/src/frameworks/solid/add-ons/solid-ui/info.json +1 -1
  82. package/src/frameworks/solid/add-ons/strapi/info.json +1 -1
  83. package/src/frameworks/solid/add-ons/t3env/info.json +1 -1
  84. package/src/frameworks/solid/hosts/cloudflare/README.md +11 -0
  85. package/src/frameworks/solid/hosts/cloudflare/info.json +1 -1
  86. package/src/frameworks/solid/hosts/netlify/README.md +11 -0
  87. package/src/frameworks/solid/hosts/netlify/info.json +1 -1
  88. package/src/frameworks/solid/hosts/nitro/README.md +12 -0
  89. package/src/frameworks/solid/hosts/nitro/info.json +1 -1
  90. package/src/frameworks/solid/hosts/railway/README.md +10 -0
  91. package/src/frameworks/solid/hosts/railway/info.json +1 -1
  92. package/src/index.ts +1 -0
  93. package/src/integrations/intent.ts +47 -0
  94. package/src/types.ts +1 -0
  95. package/tests/create-app.test.ts +95 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "MCP",
3
3
  "phase": "setup",
4
- "description": "Add Model Context Protocol (MCP) support.",
4
+ "description": "Expose your app as an MCP server so AI clients (Claude, Cursor) can call into it.",
5
5
  "link": "https://mcp.dev",
6
6
  "modes": ["file-router"],
7
7
  "type": "add-on",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Neon",
3
- "description": "Add the Neon database to your application.",
3
+ "description": "Serverless Postgres (auto-scales to zero, branchable per environment).",
4
4
  "link": "https://neon.com",
5
5
  "phase": "add-on",
6
6
  "type": "add-on",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Paraglide (i18n)",
3
- "description": "i18n with localized routing",
3
+ "description": "Type-safe i18n with localized routing and message bundles.",
4
4
  "phase": "add-on",
5
5
  "modes": ["file-router"],
6
6
  "type": "add-on",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Prisma",
3
- "description": "Add Prisma Postgres, or Prisma ORM with other DBs to your application.",
3
+ "description": "Type-safe database client with schema migrations (Postgres, MySQL, SQLite, MongoDB).",
4
4
  "phase": "add-on",
5
5
  "type": "add-on",
6
6
  "category": "orm",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Shadcn",
3
- "description": "Add Shadcn UI to your application.",
3
+ "description": "Copy-paste accessible UI components (Tailwind + Radix primitives).",
4
4
  "phase": "add-on",
5
5
  "modes": ["file-router", "code-router"],
6
6
  "link": "https://ui.shadcn.com/",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Strapi",
3
- "description": "Use the Strapi CMS to manage your content.",
3
+ "description": "Headless CMS with admin UI (self-hosted, content models in TypeScript).",
4
4
  "link": "https://strapi.io/",
5
5
  "phase": "add-on",
6
6
  "type": "add-on",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "T3Env",
3
- "description": "Add type safety to your environment variables",
3
+ "description": "Validate process.env at build time (catch missing/wrong env vars before runtime).",
4
4
  "phase": "add-on",
5
5
  "type": "add-on",
6
6
  "category": "tooling",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "WorkOS",
3
- "description": "Add WorkOS authentication to your application.",
3
+ "description": "Enterprise SSO, SAML, and directory sync (good for B2B apps).",
4
4
  "phase": "add-on",
5
5
  "modes": ["file-router"],
6
6
  "type": "add-on",
@@ -0,0 +1,11 @@
1
+ ## Deploy to Cloudflare Workers
2
+
3
+ This project uses the Cloudflare Vite plugin (configured in `vite.config.ts`) and `wrangler.jsonc`:
4
+
5
+ 1. Install Wrangler: `npm install -g wrangler`
6
+ 2. Authenticate: `wrangler login`
7
+ 3. Deploy: `npx wrangler deploy`
8
+
9
+ For production env vars, run `wrangler secret put MY_VAR` for each secret listed in `.env.example`. Public (non-secret) vars go in `wrangler.jsonc` under `vars`.
10
+
11
+ KV, D1, R2, and Durable Object bindings are configured in `wrangler.jsonc` — see https://developers.cloudflare.com/workers/wrangler/configuration/.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Cloudflare",
3
- "description": "Cloudflare deployment setup",
3
+ "description": "Deploy to Cloudflare Workers (edge runtime, KV/D1/R2 bindings).",
4
4
  "link": "https://developers.cloudflare.com/workers/vite-plugin/",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
@@ -0,0 +1,11 @@
1
+ ## Deploy to Netlify
2
+
3
+ This project ships with `netlify.toml` configured for a Netlify site:
4
+
5
+ 1. Push this repo to GitHub
6
+ 2. Visit https://app.netlify.com/start and import the repo
7
+ 3. Netlify auto-detects the build (`vite build` → `dist/client`)
8
+ 4. Open **Site settings → Environment variables** and add anything from `.env.example` that needs a real value in production
9
+ 5. Trigger the first deploy
10
+
11
+ Server functions and API routes run on Netlify Functions. For lower-latency request handling, see Netlify Edge Functions: https://docs.netlify.com/edge-functions/overview.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Netlify",
3
- "description": "Netlify deployment setup",
3
+ "description": "Deploy to Netlify (Functions and Edge Functions, GitHub-driven).",
4
4
  "link": "https://docs.netlify.com",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
@@ -0,0 +1,12 @@
1
+ ## Deploy with Nitro
2
+
3
+ This project uses Nitro as a generic server adapter, so it can run on any Node-compatible host.
4
+
5
+ ```bash
6
+ npm run build
7
+ node dist/server/index.mjs
8
+ ```
9
+
10
+ The build output is a self-contained Node server. To deploy, push the `dist/` directory to your host (Render, Fly.io, your own VPS, etc.) and run the server command above.
11
+
12
+ For host-specific presets (Vercel, Netlify, Cloudflare, AWS Lambda, etc.) and tuning, see https://v3.nitro.build/deploy.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Nitro (agnostic)",
3
- "description": "Nitro deployment setup",
3
+ "description": "Generic Nitro adapter (deploy to any Node-compatible host).",
4
4
  "link": "https://v3.nitro.build/",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
@@ -0,0 +1,10 @@
1
+ ## Deploy to Railway
2
+
3
+ This project ships with `nixpacks.toml` so Railway detects the build automatically:
4
+
5
+ 1. Push this repo to GitHub
6
+ 2. Visit https://railway.com/new and create a project from your repo
7
+ 3. In the **Variables** tab, add the entries from `.env.example` with their production values
8
+ 4. Railway runs `vite build` and serves from `dist/client`
9
+
10
+ Need a database? Click **+ New** in your project to provision Postgres, MySQL, or Redis directly into the same environment — the connection string is auto-injected as `DATABASE_URL`.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Railway",
3
- "description": "Railway deployment setup",
3
+ "description": "Deploy to Railway (full-stack PaaS for Node + databases).",
4
4
  "link": "https://railway.com/",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Better Auth",
3
- "description": "Add Better Auth authentication to your application.",
3
+ "description": "Self-hosted user accounts and sessions (open source, full control).",
4
4
  "phase": "add-on",
5
5
  "type": "add-on",
6
6
  "category": "auth",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Convex",
3
- "description": "Add the Convex database to your application.",
3
+ "description": "Reactive document database with real-time queries and serverless functions.",
4
4
  "link": "https://convex.dev",
5
5
  "phase": "add-on",
6
6
  "type": "add-on",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Solid-UI",
3
- "description": "Add Solid-UI to your application.",
3
+ "description": "Copy-paste accessible UI components for Solid (Tailwind + Radix-style primitives).",
4
4
  "phase": "add-on",
5
5
  "link": "https://ui.shadcn.com/",
6
6
  "modes": ["file-router", "code-router"],
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Strapi",
3
- "description": "Use the Strapi CMS to manage your content.",
3
+ "description": "Headless CMS with admin UI (self-hosted, content models in TypeScript).",
4
4
  "link": "https://strapi.io/",
5
5
  "phase": "add-on",
6
6
  "type": "add-on",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "T3Env",
3
- "description": "Add type safety to your environment variables",
3
+ "description": "Validate process.env at build time (catch missing/wrong env vars before runtime).",
4
4
  "phase": "add-on",
5
5
  "link": "https://github.com/t3-oss/t3-env",
6
6
  "type": "add-on",
@@ -0,0 +1,11 @@
1
+ ## Deploy to Cloudflare Workers
2
+
3
+ This project uses the Cloudflare Vite plugin (configured in `vite.config.ts`) and `wrangler.jsonc`:
4
+
5
+ 1. Install Wrangler: `npm install -g wrangler`
6
+ 2. Authenticate: `wrangler login`
7
+ 3. Deploy: `npx wrangler deploy`
8
+
9
+ For production env vars, run `wrangler secret put MY_VAR` for each secret listed in `.env.example`. Public (non-secret) vars go in `wrangler.jsonc` under `vars`.
10
+
11
+ KV, D1, R2, and Durable Object bindings are configured in `wrangler.jsonc` — see https://developers.cloudflare.com/workers/wrangler/configuration/.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Cloudflare",
3
- "description": "Cloudflare deployment setup",
3
+ "description": "Deploy to Cloudflare Workers (edge runtime, KV/D1/R2 bindings).",
4
4
  "link": "https://developers.cloudflare.com/workers/vite-plugin/",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
@@ -0,0 +1,11 @@
1
+ ## Deploy to Netlify
2
+
3
+ This project ships with `netlify.toml` configured for a Netlify site:
4
+
5
+ 1. Push this repo to GitHub
6
+ 2. Visit https://app.netlify.com/start and import the repo
7
+ 3. Netlify auto-detects the build (`vite build` → `dist/client`)
8
+ 4. Open **Site settings → Environment variables** and add anything from `.env.example` that needs a real value in production
9
+ 5. Trigger the first deploy
10
+
11
+ Server functions and API routes run on Netlify Functions. For lower-latency request handling, see Netlify Edge Functions: https://docs.netlify.com/edge-functions/overview.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Netlify",
3
- "description": "Netlify deployment setup",
3
+ "description": "Deploy to Netlify (Functions and Edge Functions, GitHub-driven).",
4
4
  "link": "https://docs.netlify.com",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
@@ -0,0 +1,12 @@
1
+ ## Deploy with Nitro
2
+
3
+ This project uses Nitro as a generic server adapter, so it can run on any Node-compatible host.
4
+
5
+ ```bash
6
+ npm run build
7
+ node dist/server/index.mjs
8
+ ```
9
+
10
+ The build output is a self-contained Node server. To deploy, push the `dist/` directory to your host (Render, Fly.io, your own VPS, etc.) and run the server command above.
11
+
12
+ For host-specific presets (Vercel, Netlify, Cloudflare, AWS Lambda, etc.) and tuning, see https://v3.nitro.build/deploy.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Nitro (agnostic)",
3
- "description": "Nitro deployment setup",
3
+ "description": "Generic Nitro adapter (deploy to any Node-compatible host).",
4
4
  "link": "https://v3.nitro.build/",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
@@ -0,0 +1,10 @@
1
+ ## Deploy to Railway
2
+
3
+ This project ships with `nixpacks.toml` so Railway detects the build automatically:
4
+
5
+ 1. Push this repo to GitHub
6
+ 2. Visit https://railway.com/new and create a project from your repo
7
+ 3. In the **Variables** tab, add the entries from `.env.example` with their production values
8
+ 4. Railway runs `vite build` and serves from `dist/client`
9
+
10
+ Need a database? Click **+ New** in your project to provision Postgres, MySQL, or Redis directly into the same environment — the connection string is auto-injected as `DATABASE_URL`.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Railway",
3
- "description": "Railway deployment setup",
3
+ "description": "Deploy to Railway (full-stack PaaS for Node + databases).",
4
4
  "link": "https://railway.com/",
5
5
  "phase": "add-on",
6
6
  "modes": ["file-router", "code-router"],
package/src/index.ts CHANGED
@@ -51,6 +51,7 @@ export {
51
51
  export {
52
52
  cleanUpFiles,
53
53
  cleanUpFileArray,
54
+ isDemoFilePath,
54
55
  readFileHelper,
55
56
  getBinaryFile,
56
57
  recursivelyGatherFiles,
@@ -0,0 +1,47 @@
1
+ import { resolve } from 'node:path'
2
+
3
+ import { packageManagerExecute } from '../package-manager.js'
4
+
5
+ import type { Environment, Options } from '../types.js'
6
+
7
+ export async function setupIntent(
8
+ environment: Environment,
9
+ targetDir: string,
10
+ options: Options,
11
+ ) {
12
+ if (!options.intent) {
13
+ return
14
+ }
15
+
16
+ const s = environment.spinner()
17
+ s.start('Setting up TanStack Intent skill mappings...')
18
+ environment.startStep({
19
+ id: 'setup-intent',
20
+ type: 'command',
21
+ message: 'Setting up TanStack Intent skill mappings...',
22
+ })
23
+
24
+ try {
25
+ await packageManagerExecute(
26
+ environment,
27
+ resolve(targetDir),
28
+ options.packageManager,
29
+ '@tanstack/intent',
30
+ ['install', '--map'],
31
+ )
32
+ environment.finishStep('setup-intent', 'TanStack Intent configured')
33
+ s.stop('TanStack Intent configured')
34
+ } catch (error) {
35
+ const message =
36
+ error instanceof Error ? error.message : 'Unknown error'
37
+ environment.finishStep(
38
+ 'setup-intent',
39
+ `TanStack Intent setup skipped: ${message}`,
40
+ )
41
+ s.stop('TanStack Intent setup skipped')
42
+ environment.warn(
43
+ 'TanStack Intent setup failed',
44
+ `Continuing without it. You can run it later with: npx @tanstack/intent install\n\n${message}`,
45
+ )
46
+ }
47
+ }
package/src/types.ts CHANGED
@@ -214,6 +214,7 @@ export interface Options {
214
214
  packageManager: PackageManager
215
215
  git: boolean
216
216
  install?: boolean
217
+ intent: boolean
217
218
 
218
219
  chosenAddOns: Array<AddOn>
219
220
  addOnOptions: Record<string, Record<string, any>>
@@ -194,4 +194,99 @@ describe('createApp', () => {
194
194
 
195
195
  expect(output.files['/src/components/demo-AIAssistant.tsx']).toBeDefined()
196
196
  })
197
+
198
+ it('writes .env.example from add-on envVars metadata', async () => {
199
+ const { environment, output } = createMemoryEnvironment()
200
+
201
+ await createApp(environment, {
202
+ ...simpleOptions,
203
+ chosenAddOns: [
204
+ {
205
+ id: 'fake-auth',
206
+ name: 'Fake Auth',
207
+ type: 'add-on',
208
+ phase: 'add-on',
209
+ packageAdditions: { dependencies: {}, devDependencies: {} },
210
+ routes: [],
211
+ integrations: [],
212
+ envVars: [
213
+ {
214
+ name: 'AUTH_SECRET',
215
+ description: 'Random secret used to sign sessions',
216
+ required: true,
217
+ },
218
+ {
219
+ name: 'AUTH_URL',
220
+ description: 'Base URL for auth callbacks',
221
+ required: false,
222
+ },
223
+ ],
224
+ getFiles: () => [],
225
+ getFileContents: () => '',
226
+ getDeletedFiles: () => [],
227
+ } as unknown as AddOn,
228
+ ],
229
+ } as Options)
230
+
231
+ const envExample = output.files['/.env.example']
232
+ expect(envExample).toBeDefined()
233
+ expect(envExample).toContain('# Fake Auth')
234
+ expect(envExample).toContain(
235
+ '# Random secret used to sign sessions (required)',
236
+ )
237
+ expect(envExample).toContain('AUTH_SECRET=')
238
+ expect(envExample).toContain('# Base URL for auth callbacks')
239
+ expect(envExample).toContain('AUTH_URL=')
240
+ })
241
+
242
+ it('does not write .env.example when no add-on declares envVars', async () => {
243
+ const { environment, output } = createMemoryEnvironment()
244
+
245
+ await createApp(environment, {
246
+ ...simpleOptions,
247
+ chosenAddOns: [],
248
+ } as Options)
249
+
250
+ expect(output.files['/.env.example']).toBeUndefined()
251
+ })
252
+
253
+ it('dedupes env vars across add-ons in .env.example', async () => {
254
+ const { environment, output } = createMemoryEnvironment()
255
+
256
+ await createApp(environment, {
257
+ ...simpleOptions,
258
+ chosenAddOns: [
259
+ {
260
+ id: 'addon-a',
261
+ name: 'Addon A',
262
+ type: 'add-on',
263
+ phase: 'add-on',
264
+ packageAdditions: { dependencies: {}, devDependencies: {} },
265
+ routes: [],
266
+ integrations: [],
267
+ envVars: [{ name: 'SHARED_KEY', required: true }],
268
+ getFiles: () => [],
269
+ getFileContents: () => '',
270
+ getDeletedFiles: () => [],
271
+ } as unknown as AddOn,
272
+ {
273
+ id: 'addon-b',
274
+ name: 'Addon B',
275
+ type: 'add-on',
276
+ phase: 'add-on',
277
+ packageAdditions: { dependencies: {}, devDependencies: {} },
278
+ routes: [],
279
+ integrations: [],
280
+ envVars: [{ name: 'SHARED_KEY', required: true }],
281
+ getFiles: () => [],
282
+ getFileContents: () => '',
283
+ getDeletedFiles: () => [],
284
+ } as unknown as AddOn,
285
+ ],
286
+ } as Options)
287
+
288
+ const envExample = output.files['/.env.example'] || ''
289
+ const occurrences = envExample.match(/^SHARED_KEY=/gm) || []
290
+ expect(occurrences.length).toBe(1)
291
+ })
197
292
  })