@tanstack/create 0.61.3 → 0.61.5

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 (46) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/create-app.js +64 -3
  3. package/dist/custom-add-ons/add-on.js +59 -1
  4. package/dist/custom-add-ons/starter.js +5 -1
  5. package/dist/frameworks/react/add-ons/clerk/info.json +9 -0
  6. package/dist/frameworks/react/add-ons/convex/info.json +16 -0
  7. package/dist/frameworks/react/project/base/_dot_gitignore +0 -1
  8. package/dist/frameworks/react/project/base/index.html.ejs +13 -0
  9. package/dist/frameworks/react/project/base/src/main.tsx.ejs +24 -0
  10. package/dist/frameworks/react/project/base/src/routes/__root.tsx.ejs +31 -0
  11. package/dist/frameworks/react/project/base/vite.config.ts.ejs +6 -2
  12. package/dist/frameworks/solid/project/base/_dot_gitignore +0 -1
  13. package/dist/frameworks/solid/project/base/index.html.ejs +13 -0
  14. package/dist/frameworks/solid/project/base/src/main.tsx.ejs +23 -0
  15. package/dist/frameworks/solid/project/base/src/routes/__root.tsx.ejs +20 -0
  16. package/dist/frameworks/solid/project/base/vite.config.ts.ejs +6 -2
  17. package/dist/frameworks.js +1 -0
  18. package/dist/index.js +1 -1
  19. package/dist/package-json.js +20 -0
  20. package/dist/template-file.js +1 -0
  21. package/dist/types/custom-add-ons/add-on.d.ts +9 -0
  22. package/dist/types/index.d.ts +1 -1
  23. package/dist/types/types.d.ts +193 -0
  24. package/dist/types.js +10 -0
  25. package/package.json +1 -1
  26. package/src/create-app.ts +77 -3
  27. package/src/custom-add-ons/add-on.ts +72 -1
  28. package/src/custom-add-ons/starter.ts +7 -1
  29. package/src/frameworks/react/add-ons/clerk/info.json +9 -0
  30. package/src/frameworks/react/add-ons/convex/info.json +16 -0
  31. package/src/frameworks/react/project/base/_dot_gitignore +0 -1
  32. package/src/frameworks/react/project/base/index.html.ejs +13 -0
  33. package/src/frameworks/react/project/base/src/main.tsx.ejs +24 -0
  34. package/src/frameworks/react/project/base/src/routes/__root.tsx.ejs +31 -0
  35. package/src/frameworks/react/project/base/vite.config.ts.ejs +6 -2
  36. package/src/frameworks/solid/project/base/_dot_gitignore +0 -1
  37. package/src/frameworks/solid/project/base/index.html.ejs +13 -0
  38. package/src/frameworks/solid/project/base/src/main.tsx.ejs +23 -0
  39. package/src/frameworks/solid/project/base/src/routes/__root.tsx.ejs +20 -0
  40. package/src/frameworks/solid/project/base/vite.config.ts.ejs +6 -2
  41. package/src/frameworks.ts +1 -0
  42. package/src/index.ts +1 -1
  43. package/src/package-json.ts +24 -0
  44. package/src/template-file.ts +1 -0
  45. package/src/types.ts +15 -0
  46. package/tests/custom-add-ons/starter.test.ts +29 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @tanstack/create
2
2
 
3
+ ## 0.61.5
4
+
5
+ ### Patch Changes
6
+
7
+ - Add a continuous development workflow for custom add-on authors. ([`b3cc585`](https://github.com/TanStack/cli/commit/b3cc5851d2b81613e3b024eb7981c440ee5183af))
8
+
9
+ - Add `tanstack add-on dev` to watch project files and continuously refresh `.add-on` outputs.
10
+ - Rebuild `.add-on` assets and `add-on.json` automatically when source files change.
11
+ - Document the new add-on development loop in the custom add-on guide.
12
+
13
+ - Improve scaffold customization and custom add-on authoring flow. ([`5fbf262`](https://github.com/TanStack/cli/commit/5fbf262fe3a0d070e6a78fa2f2a920b176b84480))
14
+
15
+ - Add `--examples` / `--no-examples` support to include or omit demo/example pages during app creation.
16
+ - Prompt for add-on-declared environment variables during interactive create and seed entered values into generated `.env.local`.
17
+ - Ensure custom add-on/starter metadata consistently includes a `version`, with safe backfill for older metadata files.
18
+ - Align bundled starter/example metadata and docs with current Start/file-router behavior.
19
+
20
+ ## 0.61.4
21
+
22
+ ### Patch Changes
23
+
24
+ - Update the React Paraglide Vite plugin strategy to include `baseLocale` alongside `url`, preventing missing-locale routing/rendering errors in generated apps. ([`164522e`](https://github.com/TanStack/cli/commit/164522e444188e83710fc599304132de8cb379e6))
25
+
26
+ - Improve CLI compatibility and scaffold behavior for legacy router-first workflows. ([`2949819`](https://github.com/TanStack/cli/commit/2949819058b4d4b1760be683ef29bfd459ddb28b))
27
+
28
+ - Add safer target directory handling by warning before creating into non-empty folders.
29
+ - Support explicit git initialization control via `--git` and `--no-git`.
30
+ - Restore router-only compatibility mode with file-based routing templates (without Start-dependent add-ons/deployments/starters), while still allowing toolchains.
31
+ - Default `create-tsrouter-app` to router-only compatibility mode.
32
+ - Remove stale `count.txt` ignore entries from base templates.
33
+
34
+ Also expands starter documentation with clearer creation, maintenance, UI usage, and banner guidance.
35
+
3
36
  ## 0.61.3
4
37
 
5
38
  ### Patch Changes
@@ -8,6 +8,42 @@ import { createTemplateFile } from './template-file.js';
8
8
  import { installShadcnComponents } from './integrations/shadcn.js';
9
9
  import { setupGit } from './integrations/git.js';
10
10
  import { runSpecialSteps } from './special-steps/index.js';
11
+ function isDemoRoutePath(path) {
12
+ if (!path)
13
+ return false;
14
+ const normalized = path.replace(/\\/g, '/');
15
+ return (normalized.includes('/routes/demo/') ||
16
+ normalized.includes('/routes/demo.') ||
17
+ normalized.includes('/routes/example/') ||
18
+ normalized.includes('/routes/example.'));
19
+ }
20
+ function stripExamplesFromOptions(options) {
21
+ if (options.includeExamples !== false) {
22
+ return options;
23
+ }
24
+ const chosenAddOns = options.chosenAddOns
25
+ .filter((addOn) => addOn.type !== 'example')
26
+ .map((addOn) => {
27
+ const filteredRoutes = (addOn.routes || []).filter((route) => !isDemoRoutePath(route.path) &&
28
+ !(route.url && route.url.startsWith('/demo')));
29
+ return {
30
+ ...addOn,
31
+ routes: filteredRoutes,
32
+ getFiles: async () => {
33
+ const files = await addOn.getFiles();
34
+ return files.filter((file) => !isDemoRoutePath(file));
35
+ },
36
+ getDeletedFiles: async () => {
37
+ const deletedFiles = await addOn.getDeletedFiles();
38
+ return deletedFiles.filter((file) => !isDemoRoutePath(file));
39
+ },
40
+ };
41
+ });
42
+ return {
43
+ ...options,
44
+ chosenAddOns,
45
+ };
46
+ }
11
47
  async function writeFiles(environment, options) {
12
48
  const templateFileFromContent = createTemplateFile(environment, options);
13
49
  async function writeFileBundle(bundle) {
@@ -170,6 +206,29 @@ async function runCommandsAndInstallDependencies(environment, options) {
170
206
  }
171
207
  await installShadcnComponents(environment, options.targetDir, options);
172
208
  }
209
+ async function seedEnvValues(environment, options) {
210
+ const envVarValues = options.envVarValues || {};
211
+ const entries = Object.entries(envVarValues);
212
+ if (entries.length === 0)
213
+ return;
214
+ const envLocalPath = resolve(options.targetDir, '.env.local');
215
+ if (!environment.exists(envLocalPath)) {
216
+ return;
217
+ }
218
+ let envContents = await environment.readFile(envLocalPath);
219
+ for (const [key, value] of entries) {
220
+ const escapedValue = value.replace(/\n/g, '\\n');
221
+ const nextLine = `${key}=${escapedValue}`;
222
+ const pattern = new RegExp(`^${key}=.*$`, 'm');
223
+ if (pattern.test(envContents)) {
224
+ envContents = envContents.replace(pattern, nextLine);
225
+ }
226
+ else {
227
+ envContents += `${envContents.endsWith('\n') ? '' : '\n'}${nextLine}\n`;
228
+ }
229
+ }
230
+ await environment.writeFile(envLocalPath, envContents);
231
+ }
173
232
  function report(environment, options) {
174
233
  const warnings = [];
175
234
  for (const addOn of options.chosenAddOns) {
@@ -207,9 +266,11 @@ ${cdInstruction}% ${formatCommand(getPackageManagerScriptCommand(options.package
207
266
  Please read the README.md file for information on testing, styling, adding routes, etc.${errorStatement}`);
208
267
  }
209
268
  export async function createApp(environment, options) {
269
+ const effectiveOptions = stripExamplesFromOptions(options);
210
270
  environment.startRun();
211
- await writeFiles(environment, options);
212
- await runCommandsAndInstallDependencies(environment, options);
271
+ await writeFiles(environment, effectiveOptions);
272
+ await seedEnvValues(environment, effectiveOptions);
273
+ await runCommandsAndInstallDependencies(environment, effectiveOptions);
213
274
  environment.finishRun();
214
- report(environment, options);
275
+ report(environment, effectiveOptions);
215
276
  }
@@ -1,4 +1,4 @@
1
- import { readFile } from 'node:fs/promises';
1
+ import { readFile, watch } from 'node:fs/promises';
2
2
  import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
3
3
  import { basename, dirname, resolve } from 'node:path';
4
4
  import { AddOnCompiledSchema } from '../types.js';
@@ -15,6 +15,19 @@ export const ADD_ON_IGNORE_FILES = [
15
15
  const INFO_FILE = '.add-on/info.json';
16
16
  const COMPILED_FILE = 'add-on.json';
17
17
  const ASSETS_DIR = 'assets';
18
+ const ADD_ON_DEV_IGNORE_PREFIXES = [
19
+ '.add-on/',
20
+ '.git/',
21
+ 'node_modules/',
22
+ '.turbo/',
23
+ 'dist/',
24
+ ];
25
+ function shouldIgnoreDevPath(path) {
26
+ const normalized = path.replace(/\\/g, '/');
27
+ if (normalized === COMPILED_FILE)
28
+ return true;
29
+ return ADD_ON_DEV_IGNORE_PREFIXES.some((prefix) => normalized.startsWith(prefix));
30
+ }
18
31
  export function camelCase(str) {
19
32
  return str
20
33
  .split(/(\.|-|\/)/)
@@ -78,6 +91,9 @@ export async function readOrGenerateAddOnInfo(options) {
78
91
  },
79
92
  dependsOn: options.chosenAddOns,
80
93
  };
94
+ if (!info.version) {
95
+ info.version = '0.0.1';
96
+ }
81
97
  return info;
82
98
  }
83
99
  export async function generateProject(persistedOptions) {
@@ -136,6 +152,48 @@ export async function initAddOn(environment) {
136
152
  await updateAddOnInfo(environment);
137
153
  await compileAddOn(environment);
138
154
  }
155
+ export async function devAddOn(environment) {
156
+ await initAddOn(environment);
157
+ environment.info('Add-on dev mode is running.', 'Watching project files and recompiling add-on output on changes. Press Ctrl+C to stop.');
158
+ const abortController = new AbortController();
159
+ let debounceTimeout;
160
+ const rerun = async () => {
161
+ try {
162
+ await updateAddOnInfo(environment);
163
+ await compileAddOn(environment);
164
+ environment.info('Add-on updated.', 'Compiled add-on.json and refreshed .add-on');
165
+ }
166
+ catch (error) {
167
+ const message = error instanceof Error ? error.message : String(error);
168
+ environment.error('Failed to rebuild add-on.', message);
169
+ }
170
+ };
171
+ process.once('SIGINT', () => {
172
+ abortController.abort();
173
+ });
174
+ try {
175
+ for await (const event of watch(process.cwd(), {
176
+ recursive: true,
177
+ signal: abortController.signal,
178
+ })) {
179
+ const file = event.filename?.toString();
180
+ if (!file || shouldIgnoreDevPath(file))
181
+ continue;
182
+ if (debounceTimeout) {
183
+ clearTimeout(debounceTimeout);
184
+ }
185
+ debounceTimeout = setTimeout(() => {
186
+ void rerun();
187
+ }, 200);
188
+ }
189
+ }
190
+ catch (error) {
191
+ const message = error instanceof Error ? error.message : String(error);
192
+ if (!message.includes('aborted')) {
193
+ throw error;
194
+ }
195
+ }
196
+ }
139
197
  export async function loadRemoteAddOn(url) {
140
198
  const response = await fetch(url);
141
199
  const jsonContent = await response.json();
@@ -7,7 +7,7 @@ import { compareFilesRecursively, createAppOptionsFromPersisted, createPackageAd
7
7
  const INFO_FILE = 'starter-info.json';
8
8
  const COMPILED_FILE = 'starter.json';
9
9
  export async function readOrGenerateStarterInfo(options) {
10
- return existsSync(INFO_FILE)
10
+ const info = existsSync(INFO_FILE)
11
11
  ? JSON.parse((await readFile(INFO_FILE)).toString())
12
12
  : {
13
13
  id: `${options.projectName}-starter`,
@@ -31,6 +31,10 @@ export async function readOrGenerateStarterInfo(options) {
31
31
  dependsOn: options.chosenAddOns,
32
32
  typescript: true,
33
33
  };
34
+ if (!info.version) {
35
+ info.version = '0.0.1';
36
+ }
37
+ return info;
34
38
  }
35
39
  async function loadCurrentStarterInfo(environment) {
36
40
  const persistedOptions = await readCurrentProjectOptions(environment);
@@ -28,5 +28,14 @@
28
28
  "jsName": "ClerkProvider",
29
29
  "path": "src/integrations/clerk/provider.tsx"
30
30
  }
31
+ ],
32
+ "envVars": [
33
+ {
34
+ "name": "VITE_CLERK_PUBLISHABLE_KEY",
35
+ "description": "Clerk publishable key",
36
+ "required": true,
37
+ "secret": false,
38
+ "file": ".env.local"
39
+ }
31
40
  ]
32
41
  }
@@ -23,5 +23,21 @@
23
23
  "path": "src/integrations/convex/provider.tsx",
24
24
  "jsName": "ConvexProvider"
25
25
  }
26
+ ],
27
+ "envVars": [
28
+ {
29
+ "name": "CONVEX_DEPLOYMENT",
30
+ "description": "Convex deployment name",
31
+ "required": false,
32
+ "secret": false,
33
+ "file": ".env.local"
34
+ },
35
+ {
36
+ "name": "VITE_CONVEX_URL",
37
+ "description": "Convex deployment URL",
38
+ "required": true,
39
+ "secret": false,
40
+ "file": ".env.local"
41
+ }
26
42
  ]
27
43
  }
@@ -3,7 +3,6 @@ node_modules
3
3
  dist
4
4
  dist-ssr
5
5
  *.local
6
- count.txt
7
6
  .env
8
7
  .nitro
9
8
  .tanstack
@@ -0,0 +1,13 @@
1
+ <% if (!routerOnly) { ignoreFile() } %>
2
+ <!doctype html>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title><%= projectName %></title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.tsx"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,24 @@
1
+ <% if (!routerOnly) { ignoreFile() } %>
2
+ import React from 'react'
3
+ import ReactDOM from 'react-dom/client'
4
+ import { RouterProvider, createRouter } from '@tanstack/react-router'
5
+ import { routeTree } from './routeTree.gen'
6
+
7
+ const router = createRouter({
8
+ routeTree,
9
+ defaultPreload: 'intent',
10
+ scrollRestoration: true,
11
+ })
12
+
13
+ declare module '@tanstack/react-router' {
14
+ interface Register {
15
+ router: typeof router
16
+ }
17
+ }
18
+
19
+ const rootElement = document.getElementById('app')!
20
+
21
+ if (!rootElement.innerHTML) {
22
+ const root = ReactDOM.createRoot(rootElement)
23
+ root.render(<RouterProvider router={router} />)
24
+ }
@@ -1,3 +1,33 @@
1
+ <% if (routerOnly) { %>
2
+ import { Outlet, createRootRoute } from '@tanstack/react-router'
3
+ import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'
4
+ import { TanStackDevtools } from '@tanstack/react-devtools'
5
+
6
+ import '../styles.css'
7
+
8
+ export const Route = createRootRoute({
9
+ component: RootComponent,
10
+ })
11
+
12
+ function RootComponent() {
13
+ return (
14
+ <>
15
+ <Outlet />
16
+ <TanStackDevtools
17
+ config={{
18
+ position: 'bottom-right',
19
+ }}
20
+ plugins={[
21
+ {
22
+ name: 'TanStack Router',
23
+ render: <TanStackRouterDevtoolsPanel />,
24
+ },
25
+ ]}
26
+ />
27
+ </>
28
+ )
29
+ }
30
+ <% } else { %>
1
31
  <% let hasContext = addOnEnabled["apollo-client"] || addOnEnabled["tanstack-query"]; %>
2
32
  import {
3
33
  HeadContent, Scripts, <% if (hasContext) { %>createRootRouteWithContext<% } else { %>createRootRoute<% } %> } from '@tanstack/react-router'
@@ -93,3 +123,4 @@ function RootDocument({ children }: { children: React.ReactNode }) {
93
123
  </html>
94
124
  )
95
125
  }
126
+ <% } %>
@@ -4,7 +4,11 @@ import tsconfigPaths from 'vite-tsconfig-paths'
4
4
  <% if (addOnEnabled.paraglide) { -%>
5
5
  import { paraglideVitePlugin } from "@inlang/paraglide-js"
6
6
  <% } -%>
7
+ <% if (routerOnly) { %>
8
+ import { tanstackRouter } from '@tanstack/router-plugin/vite'
9
+ <% } else { %>
7
10
  import { tanstackStart } from '@tanstack/react-start/plugin/vite';
11
+ <% } %>
8
12
  import viteReact from '@vitejs/plugin-react'
9
13
  import tailwindcss from "@tailwindcss/vite"
10
14
  <% for(const integration of integrations.filter(i => i.type === 'vite-plugin')) { %><%- integrationImportContent(integration) %>
@@ -14,11 +18,11 @@ const config = defineConfig({
14
18
  plugins: [devtools(), <% if (addOnEnabled.paraglide) { %>paraglideVitePlugin({
15
19
  project: './project.inlang',
16
20
  outdir: './src/paraglide',
17
- strategy: ['url'],
21
+ strategy: ['url', "baseLocale"],
18
22
  }), <% } %><% for(const integration of integrations.filter(i => i.type === 'vite-plugin')) { %><%- integrationImportCode(integration) %>,<% } %>
19
23
  tsconfigPaths({ projects: ['./tsconfig.json'] }),
20
24
  tailwindcss(),
21
- tanstackStart(),
25
+ <% if (routerOnly) { %>tanstackRouter({ target: 'react', autoCodeSplitting: true }),<% } else { %>tanstackStart(),<% } %>
22
26
  viteReact(<% if (addOnEnabled.compiler) { %>{
23
27
  babel: {
24
28
  plugins: ["babel-plugin-react-compiler"],
@@ -10,4 +10,3 @@ dist-ssr
10
10
  .output
11
11
  .vinxi
12
12
  __unconfig*
13
- count.txt
@@ -0,0 +1,13 @@
1
+ <% if (!routerOnly) { ignoreFile() } %>
2
+ <!doctype html>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title><%= projectName %></title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.tsx"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,23 @@
1
+ <% if (!routerOnly) { ignoreFile() } %>
2
+ import { render } from 'solid-js/web'
3
+ import { RouterProvider, createRouter } from '@tanstack/solid-router'
4
+ import { routeTree } from './routeTree.gen'
5
+
6
+ const router = createRouter({
7
+ routeTree,
8
+ defaultPreload: 'intent',
9
+ defaultPreloadStaleTime: 0,
10
+ scrollRestoration: true,
11
+ })
12
+
13
+ declare module '@tanstack/solid-router' {
14
+ interface Register {
15
+ router: typeof router
16
+ }
17
+ }
18
+
19
+ const rootElement = document.getElementById('app')!
20
+
21
+ if (!rootElement.innerHTML) {
22
+ render(() => <RouterProvider router={router} />, rootElement)
23
+ }
@@ -1,3 +1,22 @@
1
+ <% if (routerOnly) { %>
2
+ import { Outlet, createRootRoute } from '@tanstack/solid-router'
3
+ import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
4
+
5
+ import '../styles.css'
6
+
7
+ export const Route = createRootRoute({
8
+ component: RootComponent,
9
+ })
10
+
11
+ function RootComponent() {
12
+ return (
13
+ <>
14
+ <Outlet />
15
+ <TanStackRouterDevtools position="bottom-right" />
16
+ </>
17
+ )
18
+ }
19
+ <% } else { %>
1
20
  import { HeadContent, Outlet, Scripts, createRootRouteWithContext } from '@tanstack/solid-router'
2
21
  import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
3
22
 
@@ -47,3 +66,4 @@ function RootComponent() {
47
66
  </html>
48
67
  );
49
68
  }
69
+ <% } %>
@@ -2,7 +2,11 @@ import { defineConfig } from "vite";
2
2
  import { devtools } from '@tanstack/devtools-vite'
3
3
  import viteTsConfigPaths from 'vite-tsconfig-paths'
4
4
  import tailwindcss from "@tailwindcss/vite"
5
+ <% if (routerOnly) { %>
6
+ import { tanstackRouter } from '@tanstack/router-plugin/vite'
7
+ <% } else { %>
5
8
  import { tanstackStart } from "@tanstack/solid-start/plugin/vite";
9
+ <% } %>
6
10
  import solidPlugin from 'vite-plugin-solid';
7
11
  <% for(const integration of integrations.filter(i => i.type === 'vite-plugin')) { %><%- integrationImportContent(integration) %>
8
12
  <% } %>
@@ -15,7 +19,7 @@ export default defineConfig({
15
19
  projects: ['./tsconfig.json'],
16
20
  }),
17
21
  tailwindcss(),
18
- tanstackStart(),
19
- solidPlugin({ ssr: true }),
22
+ <% if (routerOnly) { %>tanstackRouter({ target: 'solid', autoCodeSplitting: true }),<% } else { %>tanstackStart(),<% } %>
23
+ solidPlugin(<% if (!routerOnly) { %>{ ssr: true }<% } %>),
20
24
  ],
21
25
  })
@@ -67,6 +67,7 @@ export function scanAddOnDirectories(addOnsDirectories) {
67
67
  addOns.push({
68
68
  ...info,
69
69
  id: dir,
70
+ version: info.version ?? '0.0.0',
70
71
  packageAdditions,
71
72
  packageTemplate,
72
73
  readme,
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ export { writeConfigFileToEnvironment, readConfigFileFromEnvironment, readConfig
17
17
  export { cleanUpFiles, cleanUpFileArray, readFileHelper, getBinaryFile, recursivelyGatherFiles, relativePath, toCleanPath, } from './file-helpers.js';
18
18
  export { formatCommand, handleSpecialURL } from './utils.js';
19
19
  export { initStarter, compileStarter } from './custom-add-ons/starter.js';
20
- export { initAddOn, compileAddOn } from './custom-add-ons/add-on.js';
20
+ export { initAddOn, compileAddOn, devAddOn } from './custom-add-ons/add-on.js';
21
21
  export { createAppOptionsFromPersisted, createSerializedOptionsFromPersisted, } from './custom-add-ons/shared.js';
22
22
  export { createSerializedOptions } from './options.js';
23
23
  export { getRawRegistry, getRegistry, getRegistryAddOns, getRegistryStarters, } from './registry.js';
@@ -49,6 +49,7 @@ export function createPackageJSON(options) {
49
49
  jsx: 'tsx',
50
50
  fileRouter: options.mode === 'file-router',
51
51
  codeRouter: options.mode === 'code-router',
52
+ routerOnly: options.routerOnly === true,
52
53
  addOnEnabled: options.chosenAddOns.reduce((acc, addon) => {
53
54
  acc[addon.id] = true;
54
55
  return acc;
@@ -71,6 +72,25 @@ export function createPackageJSON(options) {
71
72
  if (options.starter) {
72
73
  packageJSON = mergePackageJSON(packageJSON, options.starter.packageAdditions);
73
74
  }
75
+ if (options.routerOnly) {
76
+ if (options.framework.id === 'react-cra') {
77
+ delete packageJSON.dependencies?.['@tanstack/react-start'];
78
+ delete packageJSON.dependencies?.['@tanstack/react-router-ssr-query'];
79
+ packageJSON.devDependencies = {
80
+ ...(packageJSON.devDependencies ?? {}),
81
+ '@tanstack/router-plugin': packageJSON.devDependencies?.['@tanstack/router-plugin'] ?? '^1.132.0',
82
+ };
83
+ }
84
+ if (options.framework.id === 'solid') {
85
+ delete packageJSON.dependencies?.['@tanstack/solid-start'];
86
+ delete packageJSON.dependencies?.['@tanstack/solid-router-ssr-query'];
87
+ delete packageJSON.scripts?.start;
88
+ packageJSON.devDependencies = {
89
+ ...(packageJSON.devDependencies ?? {}),
90
+ '@tanstack/router-plugin': packageJSON.devDependencies?.['@tanstack/router-plugin'] ?? '^1.133.20',
91
+ };
92
+ }
93
+ }
74
94
  packageJSON.dependencies = sortObject((packageJSON.dependencies ?? {}));
75
95
  packageJSON.devDependencies = sortObject((packageJSON.devDependencies ?? {}));
76
96
  return packageJSON;
@@ -82,6 +82,7 @@ export function createTemplateFile(environment, options) {
82
82
  jsx: 'tsx',
83
83
  fileRouter: options.mode === 'file-router',
84
84
  codeRouter: options.mode === 'code-router',
85
+ routerOnly: options.routerOnly === true,
85
86
  addOnEnabled,
86
87
  addOnOption: options.addOnOptions,
87
88
  addOns: options.chosenAddOns,
@@ -61,6 +61,14 @@ export declare function generateProject(persistedOptions: PersistedOptions): Pro
61
61
  addOnSpecialSteps?: string[] | undefined;
62
62
  createSpecialSteps?: string[] | undefined;
63
63
  postInitSpecialSteps?: string[] | undefined;
64
+ envVars?: {
65
+ name: string;
66
+ file?: ".env" | ".env.local" | undefined;
67
+ description?: string | undefined;
68
+ default?: string | undefined;
69
+ required?: boolean | undefined;
70
+ secret?: boolean | undefined;
71
+ }[] | undefined;
64
72
  integrations?: {
65
73
  type?: string | undefined;
66
74
  code?: string | undefined;
@@ -79,4 +87,5 @@ export declare function buildAssetsDirectory(output: {
79
87
  export declare function updateAddOnInfo(environment: Environment): Promise<void>;
80
88
  export declare function compileAddOn(environment: Environment): Promise<void>;
81
89
  export declare function initAddOn(environment: Environment): Promise<void>;
90
+ export declare function devAddOn(environment: Environment): Promise<void>;
82
91
  export declare function loadRemoteAddOn(url: string): Promise<AddOn>;
@@ -12,7 +12,7 @@ export { writeConfigFileToEnvironment, readConfigFileFromEnvironment, readConfig
12
12
  export { cleanUpFiles, cleanUpFileArray, readFileHelper, getBinaryFile, recursivelyGatherFiles, relativePath, toCleanPath, } from './file-helpers.js';
13
13
  export { formatCommand, handleSpecialURL } from './utils.js';
14
14
  export { initStarter, compileStarter } from './custom-add-ons/starter.js';
15
- export { initAddOn, compileAddOn } from './custom-add-ons/add-on.js';
15
+ export { initAddOn, compileAddOn, devAddOn } from './custom-add-ons/add-on.js';
16
16
  export { createAppOptionsFromPersisted, createSerializedOptionsFromPersisted, } from './custom-add-ons/shared.js';
17
17
  export { createSerializedOptions } from './options.js';
18
18
  export { getRawRegistry, getRegistry, getRegistryAddOns, getRegistryStarters, } from './registry.js';