@tanstack/create 0.63.4 → 0.63.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.
- package/CHANGELOG.md +13 -0
- package/dist/create-app.js +15 -8
- package/dist/frameworks/react/add-ons/better-auth/assets/src/integrations/better-auth/{header-user.tsx → header-user.tsx.ejs} +6 -0
- package/dist/frameworks/react/project/base/src/components/Footer.tsx.ejs +1 -0
- package/dist/frameworks/react/project/base/src/components/Header.tsx.ejs +1 -0
- package/dist/frameworks/react/project/base/src/components/ThemeToggle.tsx.ejs +1 -0
- package/dist/frameworks/react/project/base/src/routes/__root.tsx.ejs +93 -0
- package/dist/frameworks/react/project/base/src/routes/about.tsx.ejs +1 -0
- package/dist/frameworks/react/project/base/src/routes/index.tsx.ejs +17 -0
- package/dist/frameworks/react/project/base/src/styles.css.ejs +18 -0
- package/dist/frameworks/solid/add-ons/better-auth/assets/src/integrations/better-auth/{header-user.tsx → header-user.tsx.ejs} +4 -0
- package/dist/frameworks/solid/project/base/src/components/Header.tsx.ejs +1 -0
- package/dist/frameworks/solid/project/base/src/routes/__root.tsx.ejs +46 -1
- package/dist/frameworks/solid/project/base/src/routes/about.tsx.ejs +1 -0
- package/dist/frameworks/solid/project/base/src/routes/index.tsx.ejs +17 -0
- package/dist/frameworks/solid/project/base/src/styles.css.ejs +18 -0
- package/dist/template-file.js +1 -0
- package/package.json +1 -1
- package/src/create-app.ts +22 -8
- package/src/frameworks/react/add-ons/better-auth/assets/src/integrations/better-auth/{header-user.tsx → header-user.tsx.ejs} +6 -0
- package/src/frameworks/react/project/base/src/components/Footer.tsx.ejs +1 -0
- package/src/frameworks/react/project/base/src/components/Header.tsx.ejs +1 -0
- package/src/frameworks/react/project/base/src/components/ThemeToggle.tsx.ejs +1 -0
- package/src/frameworks/react/project/base/src/routes/__root.tsx.ejs +93 -0
- package/src/frameworks/react/project/base/src/routes/about.tsx.ejs +1 -0
- package/src/frameworks/react/project/base/src/routes/index.tsx.ejs +17 -0
- package/src/frameworks/react/project/base/src/styles.css.ejs +18 -0
- package/src/frameworks/solid/add-ons/better-auth/assets/src/integrations/better-auth/{header-user.tsx → header-user.tsx.ejs} +4 -0
- package/src/frameworks/solid/project/base/src/components/Header.tsx.ejs +1 -0
- package/src/frameworks/solid/project/base/src/routes/__root.tsx.ejs +46 -1
- package/src/frameworks/solid/project/base/src/routes/about.tsx.ejs +1 -0
- package/src/frameworks/solid/project/base/src/routes/index.tsx.ejs +17 -0
- package/src/frameworks/solid/project/base/src/styles.css.ejs +18 -0
- package/src/template-file.ts +1 -0
- package/tests/create-app.test.ts +77 -0
- package/tests/template-context.test.ts +63 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @tanstack/create
|
|
2
2
|
|
|
3
|
+
## 0.63.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fix demo/example files leaking into projects when users opt out of demo pages. ([#434](https://github.com/TanStack/cli/pull/434))
|
|
8
|
+
|
|
9
|
+
- Strip add-on demo support files in `src/lib/`, `src/hooks/`, `src/data/`, `src/components/`, `src/store/`, and any `demo.*` / `demo-*` / `example.*` / `example-*` files.
|
|
10
|
+
- Strip example image assets under `public/`.
|
|
11
|
+
- Generate a minimal base starter (no Header, Footer, ThemeToggle, about page, or styled index page) when declining demo/example pages.
|
|
12
|
+
- Render Better Auth header-user component as `null` when its demo route is excluded, instead of linking to a non-existent route.
|
|
13
|
+
|
|
14
|
+
Closes #422, #409.
|
|
15
|
+
|
|
3
16
|
## 0.63.4
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/dist/create-app.js
CHANGED
|
@@ -9,14 +9,19 @@ import { createTemplateFile } from './template-file.js';
|
|
|
9
9
|
import { installShadcnComponents } from './integrations/shadcn.js';
|
|
10
10
|
import { setupGit } from './integrations/git.js';
|
|
11
11
|
import { runSpecialSteps } from './special-steps/index.js';
|
|
12
|
-
function
|
|
12
|
+
function isDemoFilePath(path) {
|
|
13
13
|
if (!path)
|
|
14
14
|
return false;
|
|
15
15
|
const normalized = path.replace(/\\/g, '/');
|
|
16
|
-
|
|
17
|
-
normalized.includes('/routes/
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
if (normalized.includes('/routes/demo/') ||
|
|
17
|
+
normalized.includes('/routes/example/')) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
const filename = normalized.split('/').pop() || '';
|
|
21
|
+
return (filename.startsWith('demo.') ||
|
|
22
|
+
filename.startsWith('demo-') ||
|
|
23
|
+
filename.startsWith('example.') ||
|
|
24
|
+
filename.startsWith('example-'));
|
|
20
25
|
}
|
|
21
26
|
function stripExamplesFromOptions(options) {
|
|
22
27
|
if (options.includeExamples !== false) {
|
|
@@ -25,18 +30,20 @@ function stripExamplesFromOptions(options) {
|
|
|
25
30
|
const chosenAddOns = options.chosenAddOns
|
|
26
31
|
.filter((addOn) => addOn.type !== 'example')
|
|
27
32
|
.map((addOn) => {
|
|
28
|
-
const filteredRoutes = (addOn.routes || []).filter((route) => !
|
|
33
|
+
const filteredRoutes = (addOn.routes || []).filter((route) => !isDemoFilePath(route.path) &&
|
|
29
34
|
!(route.url && route.url.startsWith('/demo')));
|
|
35
|
+
const filteredIntegrations = (addOn.integrations || []).filter((integration) => !isDemoFilePath(integration.path));
|
|
30
36
|
return {
|
|
31
37
|
...addOn,
|
|
32
38
|
routes: filteredRoutes,
|
|
39
|
+
integrations: filteredIntegrations,
|
|
33
40
|
getFiles: async () => {
|
|
34
41
|
const files = await addOn.getFiles();
|
|
35
|
-
return files.filter((file) => !
|
|
42
|
+
return files.filter((file) => !isDemoFilePath(file));
|
|
36
43
|
},
|
|
37
44
|
getDeletedFiles: async () => {
|
|
38
45
|
const deletedFiles = await addOn.getDeletedFiles();
|
|
39
|
-
return deletedFiles.filter((file) => !
|
|
46
|
+
return deletedFiles.filter((file) => !isDemoFilePath(file));
|
|
40
47
|
},
|
|
41
48
|
};
|
|
42
49
|
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { authClient } from "#/lib/auth-client";
|
|
2
|
+
<%_ if (routes.some(r => r.url === '/demo/better-auth')) { _%>
|
|
2
3
|
import { Link } from "@tanstack/react-router";
|
|
4
|
+
<%_ } _%>
|
|
3
5
|
|
|
4
6
|
export default function BetterAuthHeader() {
|
|
5
7
|
const { data: session, isPending } = authClient.useSession();
|
|
@@ -34,6 +36,7 @@ export default function BetterAuthHeader() {
|
|
|
34
36
|
);
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
<%_ if (routes.some(r => r.url === '/demo/better-auth')) { _%>
|
|
37
40
|
return (
|
|
38
41
|
<Link
|
|
39
42
|
to="/demo/better-auth"
|
|
@@ -42,4 +45,7 @@ export default function BetterAuthHeader() {
|
|
|
42
45
|
Sign in
|
|
43
46
|
</Link>
|
|
44
47
|
);
|
|
48
|
+
<%_ } else { _%>
|
|
49
|
+
return null;
|
|
50
|
+
<%_ } _%>
|
|
45
51
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<% if (!includeExamples) { ignoreFile(); return; } %>
|
|
1
2
|
import { Link } from '@tanstack/react-router'
|
|
2
3
|
<% for (const integration of integrations.filter((i) => i.type === 'header-user')) { %>import <%= integration.jsName %> from '<%= relativePath(integration.path) %>'
|
|
3
4
|
<% } %>import ThemeToggle from './ThemeToggle'
|
|
@@ -27,6 +27,99 @@ function RootComponent() {
|
|
|
27
27
|
</>
|
|
28
28
|
)
|
|
29
29
|
}
|
|
30
|
+
<% } else if (!includeExamples) { %>
|
|
31
|
+
<% let hasContext = addOnEnabled["apollo-client"] || addOnEnabled["tanstack-query"]; %>
|
|
32
|
+
import {
|
|
33
|
+
HeadContent, Scripts, <% if (hasContext) { %>createRootRouteWithContext<% } else { %>createRootRoute<% } %> } from '@tanstack/react-router'
|
|
34
|
+
import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools';
|
|
35
|
+
import { TanStackDevtools } from '@tanstack/react-devtools'
|
|
36
|
+
<% for(const integration of integrations.filter(i => i.type === 'layout' || i.type === 'provider' || i.type === 'devtools')) { %>
|
|
37
|
+
import <%= integration.jsName %> from '<%= relativePath(integration.path, true) %>'
|
|
38
|
+
<% } %><% if (addOnEnabled.paraglide) { %>
|
|
39
|
+
import { getLocale } from '#/paraglide/runtime'
|
|
40
|
+
<% } %>
|
|
41
|
+
import appCss from '../styles.css?url'
|
|
42
|
+
<% if (addOnEnabled["apollo-client"]) { %>
|
|
43
|
+
import type { ApolloClientIntegration } from "@apollo/client-integration-tanstack-start";
|
|
44
|
+
<% } %>
|
|
45
|
+
<% if (addOnEnabled["tanstack-query"]) { %>
|
|
46
|
+
import type { QueryClient } from '@tanstack/react-query'
|
|
47
|
+
<% if (addOnEnabled.tRPC) { %>
|
|
48
|
+
import type { TRPCRouter } from '#/integrations/trpc/router'
|
|
49
|
+
import type { TRPCOptionsProxy } from '@trpc/tanstack-react-query'
|
|
50
|
+
<% } %>
|
|
51
|
+
<% } %>
|
|
52
|
+
<% if (hasContext) { %>
|
|
53
|
+
interface MyRouterContext <% if (addOnEnabled["apollo-client"]) {%> extends ApolloClientIntegration.RouterContext <%} %>{
|
|
54
|
+
<% if (addOnEnabled["tanstack-query"]) { %>
|
|
55
|
+
queryClient: QueryClient
|
|
56
|
+
<% if (addOnEnabled.tRPC) { %>
|
|
57
|
+
trpc: TRPCOptionsProxy<TRPCRouter>
|
|
58
|
+
<% } %>
|
|
59
|
+
<% } %>
|
|
60
|
+
}<% } %>
|
|
61
|
+
|
|
62
|
+
export const Route = <% if (hasContext) { %>createRootRouteWithContext<MyRouterContext>()<% } else { %>createRootRoute<% } %>({
|
|
63
|
+
<% if (addOnEnabled.paraglide) { %>
|
|
64
|
+
beforeLoad: async () => {
|
|
65
|
+
// Other redirect strategies are possible; see
|
|
66
|
+
// https://github.com/TanStack/router/tree/main/examples/react/i18n-paraglide#offline-redirect
|
|
67
|
+
if (typeof document !== 'undefined') {
|
|
68
|
+
document.documentElement.setAttribute('lang', getLocale())
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
<% } %>
|
|
72
|
+
head: () => ({
|
|
73
|
+
meta: [
|
|
74
|
+
{
|
|
75
|
+
charSet: 'utf-8',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'viewport',
|
|
79
|
+
content: 'width=device-width, initial-scale=1',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
title: 'TanStack Start Starter',
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
links: [
|
|
86
|
+
{
|
|
87
|
+
rel: 'stylesheet',
|
|
88
|
+
href: appCss,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
}),
|
|
92
|
+
shellComponent: RootDocument
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
function RootDocument({ children }: { children: React.ReactNode }) {
|
|
96
|
+
return (
|
|
97
|
+
<% if (addOnEnabled.paraglide) { %><html lang={getLocale()}><% } else { %><html lang="en"><% } %>
|
|
98
|
+
<head>
|
|
99
|
+
<HeadContent />
|
|
100
|
+
</head>
|
|
101
|
+
<body>
|
|
102
|
+
<% for(const integration of integrations.filter(i => i.type === 'provider')) { %><<%= integration.jsName %>>
|
|
103
|
+
<% } %>{children}
|
|
104
|
+
<TanStackDevtools
|
|
105
|
+
config={{
|
|
106
|
+
position: 'bottom-right',
|
|
107
|
+
}}
|
|
108
|
+
plugins={[
|
|
109
|
+
{
|
|
110
|
+
name: 'Tanstack Router',
|
|
111
|
+
render: <TanStackRouterDevtoolsPanel />,
|
|
112
|
+
},
|
|
113
|
+
<% for(const integration of integrations.filter(i => i.type === 'devtools')) { %><%= integration.jsName %>,<% } %>
|
|
114
|
+
]}
|
|
115
|
+
/>
|
|
116
|
+
<% for(const integration of integrations.filter(i => i.type === 'layout')) { %><<%= integration.jsName %> />
|
|
117
|
+
<% } %><% for(const integration of integrations.filter(i => i.type === 'provider').reverse()) { %></<%= integration.jsName %>>
|
|
118
|
+
<% } %><Scripts />
|
|
119
|
+
</body>
|
|
120
|
+
</html>
|
|
121
|
+
)
|
|
122
|
+
}
|
|
30
123
|
<% } else { %>
|
|
31
124
|
<% let hasContext = addOnEnabled["apollo-client"] || addOnEnabled["tanstack-query"]; %>
|
|
32
125
|
import {
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
<% if (!includeExamples) { %>
|
|
2
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
3
|
+
|
|
4
|
+
export const Route = createFileRoute("/")({ component: Home });
|
|
5
|
+
|
|
6
|
+
function Home() {
|
|
7
|
+
return (
|
|
8
|
+
<div className="p-8">
|
|
9
|
+
<h1 className="text-4xl font-bold">Welcome to TanStack Start</h1>
|
|
10
|
+
<p className="mt-4 text-lg">
|
|
11
|
+
Edit <code>src/routes/index.tsx</code> to get started.
|
|
12
|
+
</p>
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
<% } else { %>
|
|
1
17
|
import { createFileRoute } from "@tanstack/react-router";
|
|
2
18
|
|
|
3
19
|
export const Route = createFileRoute("/")({ component: App });
|
|
@@ -70,3 +86,4 @@ function App() {
|
|
|
70
86
|
</main>
|
|
71
87
|
);
|
|
72
88
|
}
|
|
89
|
+
<% } %>
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
<% if (!includeExamples) { %>
|
|
2
|
+
@import "tailwindcss";
|
|
3
|
+
|
|
4
|
+
* {
|
|
5
|
+
box-sizing: border-box;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
html,
|
|
9
|
+
body,
|
|
10
|
+
#app {
|
|
11
|
+
min-height: 100%;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
body {
|
|
15
|
+
margin: 0;
|
|
16
|
+
}
|
|
17
|
+
<% } else { %>
|
|
1
18
|
@import url("https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&family=Manrope:wght@400;500;600;700;800&display=swap");
|
|
2
19
|
@import "tailwindcss";
|
|
3
20
|
@plugin "@tailwindcss/typography";
|
|
@@ -257,3 +274,4 @@ a {
|
|
|
257
274
|
transform: translateY(0);
|
|
258
275
|
}
|
|
259
276
|
}
|
|
277
|
+
<% } %>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Show } from "solid-js";
|
|
2
|
+
<%_ if (routes.some(r => r.url === '/demo/better-auth')) { _%>
|
|
2
3
|
import { Link } from "@tanstack/solid-router";
|
|
4
|
+
<%_ } _%>
|
|
3
5
|
import { authClient } from "../../lib/auth-client";
|
|
4
6
|
|
|
5
7
|
export default function BetterAuthHeader() {
|
|
@@ -14,6 +16,7 @@ export default function BetterAuthHeader() {
|
|
|
14
16
|
>
|
|
15
17
|
<Show
|
|
16
18
|
when={session().data?.user}
|
|
19
|
+
<%_ if (routes.some(r => r.url === '/demo/better-auth')) { _%>
|
|
17
20
|
fallback={
|
|
18
21
|
<Link
|
|
19
22
|
to="/demo/better-auth"
|
|
@@ -22,6 +25,7 @@ export default function BetterAuthHeader() {
|
|
|
22
25
|
Sign in
|
|
23
26
|
</Link>
|
|
24
27
|
}
|
|
28
|
+
<%_ } _%>
|
|
25
29
|
>
|
|
26
30
|
{(user) => (
|
|
27
31
|
<div class="flex items-center gap-2">
|
|
@@ -16,6 +16,51 @@ function RootComponent() {
|
|
|
16
16
|
</>
|
|
17
17
|
)
|
|
18
18
|
}
|
|
19
|
+
<% } else if (!includeExamples) { %>
|
|
20
|
+
import { HeadContent, Outlet, Scripts, createRootRouteWithContext } from '@tanstack/solid-router'
|
|
21
|
+
import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
|
|
22
|
+
|
|
23
|
+
<% if (addOnEnabled['solid-ui']) { %>
|
|
24
|
+
import "@fontsource/inter/400.css"
|
|
25
|
+
<% } %>
|
|
26
|
+
|
|
27
|
+
import { HydrationScript } from 'solid-js/web'
|
|
28
|
+
import { Suspense } from 'solid-js'
|
|
29
|
+
|
|
30
|
+
<% for(const addOn of addOns) {
|
|
31
|
+
for(const init of addOn.main?.initialize || []) { %>
|
|
32
|
+
<%- init %>
|
|
33
|
+
<% } } %>
|
|
34
|
+
|
|
35
|
+
import styleCss from "../styles.css?url";
|
|
36
|
+
|
|
37
|
+
export const Route = createRootRouteWithContext()({
|
|
38
|
+
head: () => ({
|
|
39
|
+
links: [{ rel: "stylesheet", href: styleCss }],
|
|
40
|
+
}),
|
|
41
|
+
shellComponent: RootComponent,
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
function RootComponent() {
|
|
45
|
+
return (
|
|
46
|
+
<html>
|
|
47
|
+
<head>
|
|
48
|
+
<HydrationScript />
|
|
49
|
+
<HeadContent />
|
|
50
|
+
</head>
|
|
51
|
+
<body>
|
|
52
|
+
<Suspense>
|
|
53
|
+
<Outlet />
|
|
54
|
+
<TanStackRouterDevtools />
|
|
55
|
+
<% for(const integration of integrations.filter(i => i.type === 'layout')) { %>
|
|
56
|
+
<<%= integration.jsName %> />
|
|
57
|
+
<% } %>
|
|
58
|
+
</Suspense>
|
|
59
|
+
<Scripts />
|
|
60
|
+
</body>
|
|
61
|
+
</html>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
19
64
|
<% } else { %>
|
|
20
65
|
import { HeadContent, Outlet, Scripts, createRootRouteWithContext } from '@tanstack/solid-router'
|
|
21
66
|
import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
|
|
@@ -47,9 +92,9 @@ function RootComponent() {
|
|
|
47
92
|
<html>
|
|
48
93
|
<head>
|
|
49
94
|
<HydrationScript />
|
|
95
|
+
<HeadContent />
|
|
50
96
|
</head>
|
|
51
97
|
<body>
|
|
52
|
-
<HeadContent />
|
|
53
98
|
<Suspense>
|
|
54
99
|
<Header />
|
|
55
100
|
<Outlet />
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
<% if (!includeExamples) { %>
|
|
2
|
+
import { createFileRoute } from '@tanstack/solid-router'
|
|
3
|
+
|
|
4
|
+
export const Route = createFileRoute('/')({ component: Home })
|
|
5
|
+
|
|
6
|
+
function Home() {
|
|
7
|
+
return (
|
|
8
|
+
<div class="p-8">
|
|
9
|
+
<h1 class="text-4xl font-bold">Welcome to TanStack Start</h1>
|
|
10
|
+
<p class="mt-4 text-lg">
|
|
11
|
+
Edit <code>src/routes/index.tsx</code> to get started.
|
|
12
|
+
</p>
|
|
13
|
+
</div>
|
|
14
|
+
)
|
|
15
|
+
}
|
|
16
|
+
<% } else { %>
|
|
1
17
|
import { createFileRoute } from '@tanstack/solid-router'
|
|
2
18
|
|
|
3
19
|
export const Route = createFileRoute('/')({ component: App })
|
|
@@ -66,3 +82,4 @@ function App() {
|
|
|
66
82
|
</main>
|
|
67
83
|
)
|
|
68
84
|
}
|
|
85
|
+
<% } %>
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
<% if (!includeExamples) { %>
|
|
2
|
+
@import 'tailwindcss';
|
|
3
|
+
|
|
4
|
+
* {
|
|
5
|
+
box-sizing: border-box;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
html,
|
|
9
|
+
body,
|
|
10
|
+
#app {
|
|
11
|
+
min-height: 100%;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
body {
|
|
15
|
+
margin: 0;
|
|
16
|
+
}
|
|
17
|
+
<% } else { %>
|
|
1
18
|
@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&family=Manrope:wght@400;500;600;700;800&display=swap');
|
|
2
19
|
@import 'tailwindcss';
|
|
3
20
|
|
|
@@ -193,3 +210,4 @@ code {
|
|
|
193
210
|
transform: translateY(0);
|
|
194
211
|
}
|
|
195
212
|
}
|
|
213
|
+
<% } %>
|
package/dist/template-file.js
CHANGED
|
@@ -83,6 +83,7 @@ export function createTemplateFile(environment, options) {
|
|
|
83
83
|
fileRouter: options.mode === 'file-router',
|
|
84
84
|
codeRouter: options.mode === 'code-router',
|
|
85
85
|
routerOnly: options.routerOnly === true,
|
|
86
|
+
includeExamples: options.includeExamples !== false,
|
|
86
87
|
addOnEnabled,
|
|
87
88
|
addOnOption: options.addOnOptions,
|
|
88
89
|
addOns: options.chosenAddOns,
|
package/package.json
CHANGED
package/src/create-app.ts
CHANGED
|
@@ -17,14 +17,23 @@ import { runSpecialSteps } from './special-steps/index.js'
|
|
|
17
17
|
|
|
18
18
|
import type { Environment, FileBundleHandler, Options } from './types.js'
|
|
19
19
|
|
|
20
|
-
function
|
|
20
|
+
function isDemoFilePath(path?: string) {
|
|
21
21
|
if (!path) return false
|
|
22
22
|
const normalized = path.replace(/\\/g, '/')
|
|
23
|
-
|
|
23
|
+
|
|
24
|
+
if (
|
|
24
25
|
normalized.includes('/routes/demo/') ||
|
|
25
|
-
normalized.includes('/routes/
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
normalized.includes('/routes/example/')
|
|
27
|
+
) {
|
|
28
|
+
return true
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const filename = normalized.split('/').pop() || ''
|
|
32
|
+
return (
|
|
33
|
+
filename.startsWith('demo.') ||
|
|
34
|
+
filename.startsWith('demo-') ||
|
|
35
|
+
filename.startsWith('example.') ||
|
|
36
|
+
filename.startsWith('example-')
|
|
28
37
|
)
|
|
29
38
|
}
|
|
30
39
|
|
|
@@ -38,20 +47,25 @@ function stripExamplesFromOptions(options: Options): Options {
|
|
|
38
47
|
.map((addOn) => {
|
|
39
48
|
const filteredRoutes = (addOn.routes || []).filter(
|
|
40
49
|
(route) =>
|
|
41
|
-
!
|
|
50
|
+
!isDemoFilePath(route.path) &&
|
|
42
51
|
!(route.url && route.url.startsWith('/demo')),
|
|
43
52
|
)
|
|
53
|
+
|
|
54
|
+
const filteredIntegrations = (addOn.integrations || []).filter(
|
|
55
|
+
(integration) => !isDemoFilePath(integration.path)
|
|
56
|
+
)
|
|
44
57
|
|
|
45
58
|
return {
|
|
46
59
|
...addOn,
|
|
47
60
|
routes: filteredRoutes,
|
|
61
|
+
integrations: filteredIntegrations,
|
|
48
62
|
getFiles: async () => {
|
|
49
63
|
const files = await addOn.getFiles()
|
|
50
|
-
return files.filter((file) => !
|
|
64
|
+
return files.filter((file) => !isDemoFilePath(file))
|
|
51
65
|
},
|
|
52
66
|
getDeletedFiles: async () => {
|
|
53
67
|
const deletedFiles = await addOn.getDeletedFiles()
|
|
54
|
-
return deletedFiles.filter((file) => !
|
|
68
|
+
return deletedFiles.filter((file) => !isDemoFilePath(file))
|
|
55
69
|
},
|
|
56
70
|
}
|
|
57
71
|
})
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { authClient } from "#/lib/auth-client";
|
|
2
|
+
<%_ if (routes.some(r => r.url === '/demo/better-auth')) { _%>
|
|
2
3
|
import { Link } from "@tanstack/react-router";
|
|
4
|
+
<%_ } _%>
|
|
3
5
|
|
|
4
6
|
export default function BetterAuthHeader() {
|
|
5
7
|
const { data: session, isPending } = authClient.useSession();
|
|
@@ -34,6 +36,7 @@ export default function BetterAuthHeader() {
|
|
|
34
36
|
);
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
<%_ if (routes.some(r => r.url === '/demo/better-auth')) { _%>
|
|
37
40
|
return (
|
|
38
41
|
<Link
|
|
39
42
|
to="/demo/better-auth"
|
|
@@ -42,4 +45,7 @@ export default function BetterAuthHeader() {
|
|
|
42
45
|
Sign in
|
|
43
46
|
</Link>
|
|
44
47
|
);
|
|
48
|
+
<%_ } else { _%>
|
|
49
|
+
return null;
|
|
50
|
+
<%_ } _%>
|
|
45
51
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<% if (!includeExamples) { ignoreFile(); return; } %>
|
|
1
2
|
import { Link } from '@tanstack/react-router'
|
|
2
3
|
<% for (const integration of integrations.filter((i) => i.type === 'header-user')) { %>import <%= integration.jsName %> from '<%= relativePath(integration.path) %>'
|
|
3
4
|
<% } %>import ThemeToggle from './ThemeToggle'
|
|
@@ -27,6 +27,99 @@ function RootComponent() {
|
|
|
27
27
|
</>
|
|
28
28
|
)
|
|
29
29
|
}
|
|
30
|
+
<% } else if (!includeExamples) { %>
|
|
31
|
+
<% let hasContext = addOnEnabled["apollo-client"] || addOnEnabled["tanstack-query"]; %>
|
|
32
|
+
import {
|
|
33
|
+
HeadContent, Scripts, <% if (hasContext) { %>createRootRouteWithContext<% } else { %>createRootRoute<% } %> } from '@tanstack/react-router'
|
|
34
|
+
import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools';
|
|
35
|
+
import { TanStackDevtools } from '@tanstack/react-devtools'
|
|
36
|
+
<% for(const integration of integrations.filter(i => i.type === 'layout' || i.type === 'provider' || i.type === 'devtools')) { %>
|
|
37
|
+
import <%= integration.jsName %> from '<%= relativePath(integration.path, true) %>'
|
|
38
|
+
<% } %><% if (addOnEnabled.paraglide) { %>
|
|
39
|
+
import { getLocale } from '#/paraglide/runtime'
|
|
40
|
+
<% } %>
|
|
41
|
+
import appCss from '../styles.css?url'
|
|
42
|
+
<% if (addOnEnabled["apollo-client"]) { %>
|
|
43
|
+
import type { ApolloClientIntegration } from "@apollo/client-integration-tanstack-start";
|
|
44
|
+
<% } %>
|
|
45
|
+
<% if (addOnEnabled["tanstack-query"]) { %>
|
|
46
|
+
import type { QueryClient } from '@tanstack/react-query'
|
|
47
|
+
<% if (addOnEnabled.tRPC) { %>
|
|
48
|
+
import type { TRPCRouter } from '#/integrations/trpc/router'
|
|
49
|
+
import type { TRPCOptionsProxy } from '@trpc/tanstack-react-query'
|
|
50
|
+
<% } %>
|
|
51
|
+
<% } %>
|
|
52
|
+
<% if (hasContext) { %>
|
|
53
|
+
interface MyRouterContext <% if (addOnEnabled["apollo-client"]) {%> extends ApolloClientIntegration.RouterContext <%} %>{
|
|
54
|
+
<% if (addOnEnabled["tanstack-query"]) { %>
|
|
55
|
+
queryClient: QueryClient
|
|
56
|
+
<% if (addOnEnabled.tRPC) { %>
|
|
57
|
+
trpc: TRPCOptionsProxy<TRPCRouter>
|
|
58
|
+
<% } %>
|
|
59
|
+
<% } %>
|
|
60
|
+
}<% } %>
|
|
61
|
+
|
|
62
|
+
export const Route = <% if (hasContext) { %>createRootRouteWithContext<MyRouterContext>()<% } else { %>createRootRoute<% } %>({
|
|
63
|
+
<% if (addOnEnabled.paraglide) { %>
|
|
64
|
+
beforeLoad: async () => {
|
|
65
|
+
// Other redirect strategies are possible; see
|
|
66
|
+
// https://github.com/TanStack/router/tree/main/examples/react/i18n-paraglide#offline-redirect
|
|
67
|
+
if (typeof document !== 'undefined') {
|
|
68
|
+
document.documentElement.setAttribute('lang', getLocale())
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
<% } %>
|
|
72
|
+
head: () => ({
|
|
73
|
+
meta: [
|
|
74
|
+
{
|
|
75
|
+
charSet: 'utf-8',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'viewport',
|
|
79
|
+
content: 'width=device-width, initial-scale=1',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
title: 'TanStack Start Starter',
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
links: [
|
|
86
|
+
{
|
|
87
|
+
rel: 'stylesheet',
|
|
88
|
+
href: appCss,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
}),
|
|
92
|
+
shellComponent: RootDocument
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
function RootDocument({ children }: { children: React.ReactNode }) {
|
|
96
|
+
return (
|
|
97
|
+
<% if (addOnEnabled.paraglide) { %><html lang={getLocale()}><% } else { %><html lang="en"><% } %>
|
|
98
|
+
<head>
|
|
99
|
+
<HeadContent />
|
|
100
|
+
</head>
|
|
101
|
+
<body>
|
|
102
|
+
<% for(const integration of integrations.filter(i => i.type === 'provider')) { %><<%= integration.jsName %>>
|
|
103
|
+
<% } %>{children}
|
|
104
|
+
<TanStackDevtools
|
|
105
|
+
config={{
|
|
106
|
+
position: 'bottom-right',
|
|
107
|
+
}}
|
|
108
|
+
plugins={[
|
|
109
|
+
{
|
|
110
|
+
name: 'Tanstack Router',
|
|
111
|
+
render: <TanStackRouterDevtoolsPanel />,
|
|
112
|
+
},
|
|
113
|
+
<% for(const integration of integrations.filter(i => i.type === 'devtools')) { %><%= integration.jsName %>,<% } %>
|
|
114
|
+
]}
|
|
115
|
+
/>
|
|
116
|
+
<% for(const integration of integrations.filter(i => i.type === 'layout')) { %><<%= integration.jsName %> />
|
|
117
|
+
<% } %><% for(const integration of integrations.filter(i => i.type === 'provider').reverse()) { %></<%= integration.jsName %>>
|
|
118
|
+
<% } %><Scripts />
|
|
119
|
+
</body>
|
|
120
|
+
</html>
|
|
121
|
+
)
|
|
122
|
+
}
|
|
30
123
|
<% } else { %>
|
|
31
124
|
<% let hasContext = addOnEnabled["apollo-client"] || addOnEnabled["tanstack-query"]; %>
|
|
32
125
|
import {
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
<% if (!includeExamples) { %>
|
|
2
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
3
|
+
|
|
4
|
+
export const Route = createFileRoute("/")({ component: Home });
|
|
5
|
+
|
|
6
|
+
function Home() {
|
|
7
|
+
return (
|
|
8
|
+
<div className="p-8">
|
|
9
|
+
<h1 className="text-4xl font-bold">Welcome to TanStack Start</h1>
|
|
10
|
+
<p className="mt-4 text-lg">
|
|
11
|
+
Edit <code>src/routes/index.tsx</code> to get started.
|
|
12
|
+
</p>
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
<% } else { %>
|
|
1
17
|
import { createFileRoute } from "@tanstack/react-router";
|
|
2
18
|
|
|
3
19
|
export const Route = createFileRoute("/")({ component: App });
|
|
@@ -70,3 +86,4 @@ function App() {
|
|
|
70
86
|
</main>
|
|
71
87
|
);
|
|
72
88
|
}
|
|
89
|
+
<% } %>
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
<% if (!includeExamples) { %>
|
|
2
|
+
@import "tailwindcss";
|
|
3
|
+
|
|
4
|
+
* {
|
|
5
|
+
box-sizing: border-box;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
html,
|
|
9
|
+
body,
|
|
10
|
+
#app {
|
|
11
|
+
min-height: 100%;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
body {
|
|
15
|
+
margin: 0;
|
|
16
|
+
}
|
|
17
|
+
<% } else { %>
|
|
1
18
|
@import url("https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&family=Manrope:wght@400;500;600;700;800&display=swap");
|
|
2
19
|
@import "tailwindcss";
|
|
3
20
|
@plugin "@tailwindcss/typography";
|
|
@@ -257,3 +274,4 @@ a {
|
|
|
257
274
|
transform: translateY(0);
|
|
258
275
|
}
|
|
259
276
|
}
|
|
277
|
+
<% } %>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Show } from "solid-js";
|
|
2
|
+
<%_ if (routes.some(r => r.url === '/demo/better-auth')) { _%>
|
|
2
3
|
import { Link } from "@tanstack/solid-router";
|
|
4
|
+
<%_ } _%>
|
|
3
5
|
import { authClient } from "../../lib/auth-client";
|
|
4
6
|
|
|
5
7
|
export default function BetterAuthHeader() {
|
|
@@ -14,6 +16,7 @@ export default function BetterAuthHeader() {
|
|
|
14
16
|
>
|
|
15
17
|
<Show
|
|
16
18
|
when={session().data?.user}
|
|
19
|
+
<%_ if (routes.some(r => r.url === '/demo/better-auth')) { _%>
|
|
17
20
|
fallback={
|
|
18
21
|
<Link
|
|
19
22
|
to="/demo/better-auth"
|
|
@@ -22,6 +25,7 @@ export default function BetterAuthHeader() {
|
|
|
22
25
|
Sign in
|
|
23
26
|
</Link>
|
|
24
27
|
}
|
|
28
|
+
<%_ } _%>
|
|
25
29
|
>
|
|
26
30
|
{(user) => (
|
|
27
31
|
<div class="flex items-center gap-2">
|
|
@@ -16,6 +16,51 @@ function RootComponent() {
|
|
|
16
16
|
</>
|
|
17
17
|
)
|
|
18
18
|
}
|
|
19
|
+
<% } else if (!includeExamples) { %>
|
|
20
|
+
import { HeadContent, Outlet, Scripts, createRootRouteWithContext } from '@tanstack/solid-router'
|
|
21
|
+
import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
|
|
22
|
+
|
|
23
|
+
<% if (addOnEnabled['solid-ui']) { %>
|
|
24
|
+
import "@fontsource/inter/400.css"
|
|
25
|
+
<% } %>
|
|
26
|
+
|
|
27
|
+
import { HydrationScript } from 'solid-js/web'
|
|
28
|
+
import { Suspense } from 'solid-js'
|
|
29
|
+
|
|
30
|
+
<% for(const addOn of addOns) {
|
|
31
|
+
for(const init of addOn.main?.initialize || []) { %>
|
|
32
|
+
<%- init %>
|
|
33
|
+
<% } } %>
|
|
34
|
+
|
|
35
|
+
import styleCss from "../styles.css?url";
|
|
36
|
+
|
|
37
|
+
export const Route = createRootRouteWithContext()({
|
|
38
|
+
head: () => ({
|
|
39
|
+
links: [{ rel: "stylesheet", href: styleCss }],
|
|
40
|
+
}),
|
|
41
|
+
shellComponent: RootComponent,
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
function RootComponent() {
|
|
45
|
+
return (
|
|
46
|
+
<html>
|
|
47
|
+
<head>
|
|
48
|
+
<HydrationScript />
|
|
49
|
+
<HeadContent />
|
|
50
|
+
</head>
|
|
51
|
+
<body>
|
|
52
|
+
<Suspense>
|
|
53
|
+
<Outlet />
|
|
54
|
+
<TanStackRouterDevtools />
|
|
55
|
+
<% for(const integration of integrations.filter(i => i.type === 'layout')) { %>
|
|
56
|
+
<<%= integration.jsName %> />
|
|
57
|
+
<% } %>
|
|
58
|
+
</Suspense>
|
|
59
|
+
<Scripts />
|
|
60
|
+
</body>
|
|
61
|
+
</html>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
19
64
|
<% } else { %>
|
|
20
65
|
import { HeadContent, Outlet, Scripts, createRootRouteWithContext } from '@tanstack/solid-router'
|
|
21
66
|
import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
|
|
@@ -47,9 +92,9 @@ function RootComponent() {
|
|
|
47
92
|
<html>
|
|
48
93
|
<head>
|
|
49
94
|
<HydrationScript />
|
|
95
|
+
<HeadContent />
|
|
50
96
|
</head>
|
|
51
97
|
<body>
|
|
52
|
-
<HeadContent />
|
|
53
98
|
<Suspense>
|
|
54
99
|
<Header />
|
|
55
100
|
<Outlet />
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
<% if (!includeExamples) { %>
|
|
2
|
+
import { createFileRoute } from '@tanstack/solid-router'
|
|
3
|
+
|
|
4
|
+
export const Route = createFileRoute('/')({ component: Home })
|
|
5
|
+
|
|
6
|
+
function Home() {
|
|
7
|
+
return (
|
|
8
|
+
<div class="p-8">
|
|
9
|
+
<h1 class="text-4xl font-bold">Welcome to TanStack Start</h1>
|
|
10
|
+
<p class="mt-4 text-lg">
|
|
11
|
+
Edit <code>src/routes/index.tsx</code> to get started.
|
|
12
|
+
</p>
|
|
13
|
+
</div>
|
|
14
|
+
)
|
|
15
|
+
}
|
|
16
|
+
<% } else { %>
|
|
1
17
|
import { createFileRoute } from '@tanstack/solid-router'
|
|
2
18
|
|
|
3
19
|
export const Route = createFileRoute('/')({ component: App })
|
|
@@ -66,3 +82,4 @@ function App() {
|
|
|
66
82
|
</main>
|
|
67
83
|
)
|
|
68
84
|
}
|
|
85
|
+
<% } %>
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
<% if (!includeExamples) { %>
|
|
2
|
+
@import 'tailwindcss';
|
|
3
|
+
|
|
4
|
+
* {
|
|
5
|
+
box-sizing: border-box;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
html,
|
|
9
|
+
body,
|
|
10
|
+
#app {
|
|
11
|
+
min-height: 100%;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
body {
|
|
15
|
+
margin: 0;
|
|
16
|
+
}
|
|
17
|
+
<% } else { %>
|
|
1
18
|
@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&family=Manrope:wght@400;500;600;700;800&display=swap');
|
|
2
19
|
@import 'tailwindcss';
|
|
3
20
|
|
|
@@ -193,3 +210,4 @@ code {
|
|
|
193
210
|
transform: translateY(0);
|
|
194
211
|
}
|
|
195
212
|
}
|
|
213
|
+
<% } %>
|
package/src/template-file.ts
CHANGED
|
@@ -137,6 +137,7 @@ export function createTemplateFile(environment: Environment, options: Options) {
|
|
|
137
137
|
fileRouter: options.mode === 'file-router',
|
|
138
138
|
codeRouter: options.mode === 'code-router',
|
|
139
139
|
routerOnly: options.routerOnly === true,
|
|
140
|
+
includeExamples: options.includeExamples !== false,
|
|
140
141
|
addOnEnabled,
|
|
141
142
|
addOnOption: options.addOnOptions,
|
|
142
143
|
addOns: options.chosenAddOns,
|
package/tests/create-app.test.ts
CHANGED
|
@@ -117,4 +117,81 @@ describe('createApp', () => {
|
|
|
117
117
|
expect(output.files['/src/test2.txt']).toEqual('base64::aGVsbG8=')
|
|
118
118
|
expect(output.commands.some(({ command }) => command === 'echo')).toBe(true)
|
|
119
119
|
})
|
|
120
|
+
|
|
121
|
+
it('should strip demo files from add-ons when includeExamples is false', async () => {
|
|
122
|
+
const { environment, output } = createMemoryEnvironment()
|
|
123
|
+
|
|
124
|
+
const demoFiles = [
|
|
125
|
+
'src/routes/demo/form.simple.tsx',
|
|
126
|
+
'src/routes/demo.form.tsx',
|
|
127
|
+
'src/routes/example.chat.tsx',
|
|
128
|
+
'src/components/demo-AIAssistant.tsx',
|
|
129
|
+
'src/components/demo.FormComponents.tsx',
|
|
130
|
+
'src/hooks/demo-useAudioRecorder.ts',
|
|
131
|
+
'src/hooks/demo.form.ts',
|
|
132
|
+
'src/lib/demo-store.ts',
|
|
133
|
+
'src/lib/demo.ai-hook.ts',
|
|
134
|
+
'src/data/demo-guitars.ts',
|
|
135
|
+
'src/store/demo.hooks.ts',
|
|
136
|
+
'src/store/demo.store.ts',
|
|
137
|
+
'src/demo.index.css',
|
|
138
|
+
'public/demo-neon.svg',
|
|
139
|
+
'public/example-guitar-flowers.jpg',
|
|
140
|
+
]
|
|
141
|
+
const keepFiles = [
|
|
142
|
+
'src/routes/index.tsx',
|
|
143
|
+
'src/components/Header.tsx',
|
|
144
|
+
'src/lib/utils.ts',
|
|
145
|
+
]
|
|
146
|
+
const allFiles = [...demoFiles, ...keepFiles]
|
|
147
|
+
|
|
148
|
+
await createApp(environment, {
|
|
149
|
+
...simpleOptions,
|
|
150
|
+
includeExamples: false,
|
|
151
|
+
chosenAddOns: [
|
|
152
|
+
{
|
|
153
|
+
id: 'test-addon',
|
|
154
|
+
type: 'add-on',
|
|
155
|
+
phase: 'add-on',
|
|
156
|
+
packageAdditions: { dependencies: {}, devDependencies: {} },
|
|
157
|
+
routes: [],
|
|
158
|
+
integrations: [],
|
|
159
|
+
getFiles: () => allFiles,
|
|
160
|
+
getFileContents: () => 'content',
|
|
161
|
+
getDeletedFiles: () => [],
|
|
162
|
+
} as unknown as AddOn,
|
|
163
|
+
],
|
|
164
|
+
} as Options)
|
|
165
|
+
|
|
166
|
+
for (const file of demoFiles) {
|
|
167
|
+
expect(output.files[`/${file}`]).toBeUndefined()
|
|
168
|
+
}
|
|
169
|
+
for (const file of keepFiles) {
|
|
170
|
+
expect(output.files[`/${file}`]).toBeDefined()
|
|
171
|
+
}
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
it('should keep demo files from add-ons when includeExamples is true', async () => {
|
|
175
|
+
const { environment, output } = createMemoryEnvironment()
|
|
176
|
+
|
|
177
|
+
await createApp(environment, {
|
|
178
|
+
...simpleOptions,
|
|
179
|
+
includeExamples: true,
|
|
180
|
+
chosenAddOns: [
|
|
181
|
+
{
|
|
182
|
+
id: 'test-addon',
|
|
183
|
+
type: 'add-on',
|
|
184
|
+
phase: 'add-on',
|
|
185
|
+
packageAdditions: { dependencies: {}, devDependencies: {} },
|
|
186
|
+
routes: [],
|
|
187
|
+
integrations: [],
|
|
188
|
+
getFiles: () => ['src/components/demo-AIAssistant.tsx'],
|
|
189
|
+
getFileContents: () => 'content',
|
|
190
|
+
getDeletedFiles: () => [],
|
|
191
|
+
} as unknown as AddOn,
|
|
192
|
+
],
|
|
193
|
+
} as Options)
|
|
194
|
+
|
|
195
|
+
expect(output.files['/src/components/demo-AIAssistant.tsx']).toBeDefined()
|
|
196
|
+
})
|
|
120
197
|
})
|
|
@@ -311,4 +311,67 @@ export const db = testAddon(/* connection */)`
|
|
|
311
311
|
expect(output.files['/test/src/db/__sqlite__index.ts']).toBeUndefined()
|
|
312
312
|
expect(output.files['/test/src/db/__postgres__index.ts']).toBeUndefined()
|
|
313
313
|
})
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
describe('Template Context - includeExamples', () => {
|
|
317
|
+
it('should default includeExamples to true when undefined', async () => {
|
|
318
|
+
const { environment, output } = createMemoryEnvironment()
|
|
319
|
+
const templateFile = createTemplateFile(environment, simpleOptions)
|
|
320
|
+
environment.startRun()
|
|
321
|
+
await templateFile(
|
|
322
|
+
'test.txt.ejs',
|
|
323
|
+
'<%= includeExamples ? "with-examples" : "no-examples" %>',
|
|
324
|
+
)
|
|
325
|
+
environment.finishRun()
|
|
326
|
+
|
|
327
|
+
expect(output.files['/test/test.txt']).toEqual('with-examples')
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
it('should set includeExamples to false when options.includeExamples is false', async () => {
|
|
331
|
+
const { environment, output } = createMemoryEnvironment()
|
|
332
|
+
const templateFile = createTemplateFile(environment, {
|
|
333
|
+
...simpleOptions,
|
|
334
|
+
includeExamples: false,
|
|
335
|
+
})
|
|
336
|
+
environment.startRun()
|
|
337
|
+
await templateFile(
|
|
338
|
+
'test.txt.ejs',
|
|
339
|
+
'<%= includeExamples ? "with-examples" : "no-examples" %>',
|
|
340
|
+
)
|
|
341
|
+
environment.finishRun()
|
|
342
|
+
|
|
343
|
+
expect(output.files['/test/test.txt']).toEqual('no-examples')
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
it('should ignore files when includeExamples is false', async () => {
|
|
347
|
+
const { environment, output } = createMemoryEnvironment()
|
|
348
|
+
const templateFile = createTemplateFile(environment, {
|
|
349
|
+
...simpleOptions,
|
|
350
|
+
includeExamples: false,
|
|
351
|
+
})
|
|
352
|
+
environment.startRun()
|
|
353
|
+
await templateFile(
|
|
354
|
+
'about.ts.ejs',
|
|
355
|
+
'<% if (!includeExamples) { ignoreFile(); return; } %>\nexport const about = true',
|
|
356
|
+
)
|
|
357
|
+
environment.finishRun()
|
|
358
|
+
|
|
359
|
+
expect(output.files['/test/about.ts']).toBeUndefined()
|
|
360
|
+
})
|
|
361
|
+
|
|
362
|
+
it('should include files when includeExamples is true', async () => {
|
|
363
|
+
const { environment, output } = createMemoryEnvironment()
|
|
364
|
+
const templateFile = createTemplateFile(environment, {
|
|
365
|
+
...simpleOptions,
|
|
366
|
+
includeExamples: true,
|
|
367
|
+
})
|
|
368
|
+
environment.startRun()
|
|
369
|
+
await templateFile(
|
|
370
|
+
'about.ts.ejs',
|
|
371
|
+
'<% if (!includeExamples) { ignoreFile(); return; } %>\nexport const about = true',
|
|
372
|
+
)
|
|
373
|
+
environment.finishRun()
|
|
374
|
+
|
|
375
|
+
expect(output.files['/test/about.ts']).toBeDefined()
|
|
376
|
+
})
|
|
314
377
|
})
|