create-cloudflare 2.68.4 → 2.70.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.
- package/dist/cli.js +1784 -272
- package/package.json +15 -15
- package/templates/react-router/c3.ts +42 -8
- package/templates/react-router/ts/README.md +79 -0
- package/templates/react-router/ts/__dot__gitignore +14 -0
- package/templates/react-router/ts/app/app.css +15 -0
- package/templates/react-router/ts/app/entry.server.tsx +42 -0
- package/templates/react-router/ts/app/routes/home.tsx +19 -0
- package/templates/react-router/ts/app/welcome/welcome.tsx +90 -0
- package/templates/react-router/ts/tsconfig.cloudflare.json +27 -0
- package/templates/react-router/ts/tsconfig.json +14 -0
- package/templates/react-router/ts/tsconfig.node.json +13 -0
- package/templates/react-router/ts/vite.config.ts +15 -0
- package/templates/react-router/ts/workers/app.ts +12 -0
- package/templates/react-router/ts/wrangler.jsonc +9 -0
- package/templates/tanstack-start/c3.ts +3 -1
- package/templates/react-router/ts/react-router.config.ts +0 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-cloudflare",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.70.0",
|
|
4
4
|
"description": "A CLI for creating and deploying new applications to Cloudflare.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -31,14 +31,14 @@
|
|
|
31
31
|
"@babel/parser": "^7.21.3",
|
|
32
32
|
"@babel/types": "^7.21.4",
|
|
33
33
|
"@clack/prompts": "^1.2.0",
|
|
34
|
-
"@cloudflare/workers-types": "^4.
|
|
34
|
+
"@cloudflare/workers-types": "^4.20260601.1",
|
|
35
35
|
"@types/command-exists": "^1.2.0",
|
|
36
36
|
"@types/cross-spawn": "^6.0.2",
|
|
37
37
|
"@types/deepmerge": "^2.2.0",
|
|
38
38
|
"@types/degit": "^2.8.6",
|
|
39
39
|
"@types/dns2": "^2.0.3",
|
|
40
40
|
"@types/esprima": "^4.0.3",
|
|
41
|
-
"@types/node": "
|
|
41
|
+
"@types/node": "22.15.17",
|
|
42
42
|
"@types/semver": "^7.5.1",
|
|
43
43
|
"@types/which-pm-runs": "^1.0.0",
|
|
44
44
|
"@types/yargs": "^17.0.22",
|
|
@@ -55,30 +55,30 @@
|
|
|
55
55
|
"get-port": "^7.1.0",
|
|
56
56
|
"haikunator": "^2.1.2",
|
|
57
57
|
"indent-string": "^5.0.0",
|
|
58
|
-
"jsonc-parser": "
|
|
58
|
+
"jsonc-parser": "3.2.0",
|
|
59
59
|
"magic-string": "^0.30.5",
|
|
60
|
-
"open": "
|
|
60
|
+
"open": "11.0.0",
|
|
61
61
|
"recast": "^0.23.11",
|
|
62
62
|
"semver": "^7.7.1",
|
|
63
|
-
"smol-toml": "
|
|
64
|
-
"tinyglobby": "
|
|
65
|
-
"tree-kill": "
|
|
66
|
-
"typescript": "
|
|
63
|
+
"smol-toml": "1.5.2",
|
|
64
|
+
"tinyglobby": "0.2.16",
|
|
65
|
+
"tree-kill": "1.2.2",
|
|
66
|
+
"typescript": "5.8.3",
|
|
67
67
|
"undici": "7.24.8",
|
|
68
|
-
"vite": "
|
|
68
|
+
"vite": "8.0.13",
|
|
69
69
|
"vite-tsconfig-paths": "^4.0.8",
|
|
70
70
|
"vitest": "4.1.0",
|
|
71
71
|
"which-pm-runs": "^1.1.0",
|
|
72
72
|
"wrap-ansi": "^9.0.0",
|
|
73
73
|
"xdg-app-paths": "^8.3.0",
|
|
74
74
|
"yargs": "^17.7.2",
|
|
75
|
-
"@cloudflare/cli-shared-helpers": "0.1.
|
|
76
|
-
"@cloudflare/codemod": "1.1.0",
|
|
75
|
+
"@cloudflare/cli-shared-helpers": "0.1.6",
|
|
77
76
|
"@cloudflare/mock-npm-registry": "0.0.0",
|
|
78
|
-
"@cloudflare/vite-plugin": "1.39.
|
|
77
|
+
"@cloudflare/vite-plugin": "1.39.2",
|
|
78
|
+
"@cloudflare/codemod": "1.1.0",
|
|
79
79
|
"@cloudflare/workers-tsconfig": "0.0.0",
|
|
80
|
-
"@cloudflare/workers-utils": "0.
|
|
81
|
-
"wrangler": "4.
|
|
80
|
+
"@cloudflare/workers-utils": "0.22.1",
|
|
81
|
+
"wrangler": "4.97.0"
|
|
82
82
|
},
|
|
83
83
|
"engines": {
|
|
84
84
|
"node": ">=22.0.0"
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
1
2
|
import { logRaw } from "@cloudflare/cli-shared-helpers";
|
|
3
|
+
import { brandColor, dim } from "@cloudflare/cli-shared-helpers/colors";
|
|
4
|
+
import { spinner } from "@cloudflare/cli-shared-helpers/interactive";
|
|
2
5
|
import { runFrameworkGenerator } from "frameworks/index";
|
|
6
|
+
import { readJSON, removeFile, writeJSON } from "helpers/files";
|
|
3
7
|
import { detectPackageManager } from "helpers/packageManagers";
|
|
8
|
+
import { installPackages } from "helpers/packages";
|
|
4
9
|
import type { TemplateConfig } from "../../src/templates";
|
|
5
|
-
import type { C3Context } from "types";
|
|
10
|
+
import type { C3Context, PackageJson } from "types";
|
|
6
11
|
|
|
7
12
|
const { npm } = detectPackageManager();
|
|
8
13
|
|
|
9
14
|
const generate = async (ctx: C3Context) => {
|
|
15
|
+
// We use the upstream `create-react-router` default template and overlay
|
|
16
|
+
// our Cloudflare-specific files via `copyFiles`. This avoids depending on
|
|
17
|
+
// a third-party Cloudflare template that has been deleted upstream in the past.
|
|
10
18
|
await runFrameworkGenerator(ctx, [
|
|
11
19
|
ctx.project.name,
|
|
12
|
-
...(ctx.args.experimental
|
|
13
|
-
? []
|
|
14
|
-
: [
|
|
15
|
-
"--template",
|
|
16
|
-
// React-router deleted the template here
|
|
17
|
-
"https://github.com/remix-run/react-router-templates/tree/29ac272b9532fe26463a2d2693fc73ff3c1e884b/cloudflare",
|
|
18
|
-
]),
|
|
19
20
|
// to prevent asking about git twice, just let c3 do it
|
|
20
21
|
"--no-git-init",
|
|
21
22
|
"--no-install",
|
|
@@ -24,6 +25,36 @@ const generate = async (ctx: C3Context) => {
|
|
|
24
25
|
logRaw(""); // newline
|
|
25
26
|
};
|
|
26
27
|
|
|
28
|
+
const configure = async (ctx: C3Context) => {
|
|
29
|
+
// `npmInstall` has already run by this point with the upstream default
|
|
30
|
+
// template's `package.json`, which doesn't include `@cloudflare/vite-plugin`.
|
|
31
|
+
// Our overlaid `vite.config.ts` imports it, so install it now (this also
|
|
32
|
+
// adds it to `package.json`). `wrangler` is installed separately by
|
|
33
|
+
// `installWrangler()` in the main configure flow before this runs.
|
|
34
|
+
await installPackages(["@cloudflare/vite-plugin"], {
|
|
35
|
+
dev: true,
|
|
36
|
+
startText: "Installing the Cloudflare Vite plugin",
|
|
37
|
+
doneText: `${brandColor("installed")} ${dim("@cloudflare/vite-plugin")}`,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// The upstream default template targets a generic Node.js/Docker deployment.
|
|
41
|
+
// Remove artifacts that don't apply to a Cloudflare Workers project.
|
|
42
|
+
const s = spinner();
|
|
43
|
+
s.start("Removing non-Cloudflare artifacts from template");
|
|
44
|
+
removeFile(resolve(ctx.project.path, "Dockerfile"));
|
|
45
|
+
removeFile(resolve(ctx.project.path, ".dockerignore"));
|
|
46
|
+
|
|
47
|
+
// `transformPackageJson` is deep-merge only and cannot remove keys, so strip
|
|
48
|
+
// the Node-server deps and `start` script that the default template ships.
|
|
49
|
+
const pkgJsonPath = resolve(ctx.project.path, "package.json");
|
|
50
|
+
const pkgJson = readJSON(pkgJsonPath) as PackageJson;
|
|
51
|
+
delete pkgJson.dependencies?.["@react-router/node"];
|
|
52
|
+
delete pkgJson.dependencies?.["@react-router/serve"];
|
|
53
|
+
delete pkgJson.scripts?.start;
|
|
54
|
+
writeJSON(pkgJsonPath, pkgJson);
|
|
55
|
+
s.stop(`${brandColor("removed")} ${dim("Node-server template artifacts")}`);
|
|
56
|
+
};
|
|
57
|
+
|
|
27
58
|
const config: TemplateConfig = {
|
|
28
59
|
configVersion: 1,
|
|
29
60
|
id: "react-router",
|
|
@@ -34,6 +65,7 @@ const config: TemplateConfig = {
|
|
|
34
65
|
path: "./ts",
|
|
35
66
|
},
|
|
36
67
|
generate,
|
|
68
|
+
configure,
|
|
37
69
|
transformPackageJson: async () => ({
|
|
38
70
|
dependencies: {
|
|
39
71
|
"react-router": "^7.10.0",
|
|
@@ -45,6 +77,8 @@ const config: TemplateConfig = {
|
|
|
45
77
|
deploy: `${npm} run build && wrangler deploy`,
|
|
46
78
|
preview: `${npm} run build && vite preview`,
|
|
47
79
|
"cf-typegen": `wrangler types`,
|
|
80
|
+
typecheck: `wrangler types && react-router typegen && tsc -b`,
|
|
81
|
+
postinstall: `wrangler types`,
|
|
48
82
|
},
|
|
49
83
|
}),
|
|
50
84
|
devScript: "dev",
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Welcome to React Router!
|
|
2
|
+
|
|
3
|
+
A modern, production-ready template for building full-stack React applications using React Router.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 Server-side rendering
|
|
8
|
+
- ⚡️ Hot Module Replacement (HMR)
|
|
9
|
+
- 📦 Asset bundling and optimization
|
|
10
|
+
- 🔄 Data loading and mutations
|
|
11
|
+
- 🔒 TypeScript by default
|
|
12
|
+
- 🎉 TailwindCSS for styling
|
|
13
|
+
- 📖 [React Router docs](https://reactrouter.com/)
|
|
14
|
+
|
|
15
|
+
## Getting Started
|
|
16
|
+
|
|
17
|
+
### Installation
|
|
18
|
+
|
|
19
|
+
Install the dependencies:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Development
|
|
26
|
+
|
|
27
|
+
Start the development server with HMR:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm run dev
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Your application will be available at `http://localhost:5173`.
|
|
34
|
+
|
|
35
|
+
## Previewing the Production Build
|
|
36
|
+
|
|
37
|
+
Preview the production build locally:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm run preview
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Building for Production
|
|
44
|
+
|
|
45
|
+
Create a production build:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm run build
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Deployment
|
|
52
|
+
|
|
53
|
+
Deployment is done using the Wrangler CLI.
|
|
54
|
+
|
|
55
|
+
To build and deploy directly to production:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
npm run deploy
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
To deploy a preview URL:
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
npx wrangler versions upload
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
You can then promote a version to production after verification or roll it out progressively.
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
npx wrangler versions deploy
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Styling
|
|
74
|
+
|
|
75
|
+
This template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever CSS framework you prefer.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
Built with ❤️ using React Router.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
@import "tailwindcss" source(".");
|
|
2
|
+
|
|
3
|
+
@theme {
|
|
4
|
+
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif,
|
|
5
|
+
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
html,
|
|
9
|
+
body {
|
|
10
|
+
@apply bg-white dark:bg-gray-950;
|
|
11
|
+
|
|
12
|
+
@media (prefers-color-scheme: dark) {
|
|
13
|
+
color-scheme: dark;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { EntryContext } from "react-router";
|
|
2
|
+
import { ServerRouter } from "react-router";
|
|
3
|
+
import { isbot } from "isbot";
|
|
4
|
+
import { renderToReadableStream } from "react-dom/server";
|
|
5
|
+
|
|
6
|
+
export default async function handleRequest(
|
|
7
|
+
request: Request,
|
|
8
|
+
responseStatusCode: number,
|
|
9
|
+
responseHeaders: Headers,
|
|
10
|
+
routerContext: EntryContext,
|
|
11
|
+
) {
|
|
12
|
+
let shellRendered = false;
|
|
13
|
+
const userAgent = request.headers.get("user-agent");
|
|
14
|
+
|
|
15
|
+
const body = await renderToReadableStream(
|
|
16
|
+
<ServerRouter context={routerContext} url={request.url} />,
|
|
17
|
+
{
|
|
18
|
+
onError(error: unknown) {
|
|
19
|
+
responseStatusCode = 500;
|
|
20
|
+
// Log streaming rendering errors from inside the shell. Don't log
|
|
21
|
+
// errors encountered during initial shell rendering since they'll
|
|
22
|
+
// reject and get logged in handleDocumentRequest.
|
|
23
|
+
if (shellRendered) {
|
|
24
|
+
console.error(error);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
);
|
|
29
|
+
shellRendered = true;
|
|
30
|
+
|
|
31
|
+
// Ensure requests from bots and SPA Mode renders wait for all content to load before responding
|
|
32
|
+
// https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation
|
|
33
|
+
if ((userAgent && isbot(userAgent)) || routerContext.isSpaMode) {
|
|
34
|
+
await body.allReady;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
responseHeaders.set("Content-Type", "text/html");
|
|
38
|
+
return new Response(body, {
|
|
39
|
+
headers: responseHeaders,
|
|
40
|
+
status: responseStatusCode,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { env } from "cloudflare:workers";
|
|
2
|
+
|
|
3
|
+
import type { Route } from "./+types/home";
|
|
4
|
+
import { Welcome } from "../welcome/welcome";
|
|
5
|
+
|
|
6
|
+
export function meta({}: Route.MetaArgs) {
|
|
7
|
+
return [
|
|
8
|
+
{ title: "New React Router App" },
|
|
9
|
+
{ name: "description", content: "Welcome to React Router!" },
|
|
10
|
+
];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function loader() {
|
|
14
|
+
return { message: env.VALUE_FROM_CLOUDFLARE };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default function Home({ loaderData }: Route.ComponentProps) {
|
|
18
|
+
return <Welcome message={loaderData.message} />;
|
|
19
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import logoDark from "./logo-dark.svg";
|
|
2
|
+
import logoLight from "./logo-light.svg";
|
|
3
|
+
|
|
4
|
+
export function Welcome({ message }: { message: string }) {
|
|
5
|
+
return (
|
|
6
|
+
<main className="flex items-center justify-center pt-16 pb-4">
|
|
7
|
+
<div className="flex-1 flex flex-col items-center gap-16 min-h-0">
|
|
8
|
+
<header className="flex flex-col items-center gap-9">
|
|
9
|
+
<div className="w-[500px] max-w-[100vw] p-4">
|
|
10
|
+
<img
|
|
11
|
+
src={logoLight}
|
|
12
|
+
alt="React Router"
|
|
13
|
+
className="block w-full dark:hidden"
|
|
14
|
+
/>
|
|
15
|
+
<img
|
|
16
|
+
src={logoDark}
|
|
17
|
+
alt="React Router"
|
|
18
|
+
className="hidden w-full dark:block"
|
|
19
|
+
/>
|
|
20
|
+
</div>
|
|
21
|
+
</header>
|
|
22
|
+
<div className="max-w-[300px] w-full space-y-6 px-4">
|
|
23
|
+
<nav className="rounded-3xl border border-gray-200 p-6 dark:border-gray-700 space-y-4">
|
|
24
|
+
<p className="leading-6 text-gray-700 dark:text-gray-200 text-center">
|
|
25
|
+
What's next?
|
|
26
|
+
</p>
|
|
27
|
+
<ul>
|
|
28
|
+
{resources.map(({ href, text, icon }) => (
|
|
29
|
+
<li key={href}>
|
|
30
|
+
<a
|
|
31
|
+
className="group flex items-center gap-3 self-stretch p-3 leading-normal text-blue-700 hover:underline dark:text-blue-500"
|
|
32
|
+
href={href}
|
|
33
|
+
target="_blank"
|
|
34
|
+
rel="noreferrer"
|
|
35
|
+
>
|
|
36
|
+
{icon}
|
|
37
|
+
{text}
|
|
38
|
+
</a>
|
|
39
|
+
</li>
|
|
40
|
+
))}
|
|
41
|
+
<li className="self-stretch p-3 leading-normal">{message}</li>
|
|
42
|
+
</ul>
|
|
43
|
+
</nav>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</main>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const resources = [
|
|
51
|
+
{
|
|
52
|
+
href: "https://reactrouter.com/docs",
|
|
53
|
+
text: "React Router Docs",
|
|
54
|
+
icon: (
|
|
55
|
+
<svg
|
|
56
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
57
|
+
width="24"
|
|
58
|
+
height="20"
|
|
59
|
+
viewBox="0 0 20 20"
|
|
60
|
+
fill="none"
|
|
61
|
+
className="stroke-gray-600 group-hover:stroke-current dark:stroke-gray-300"
|
|
62
|
+
>
|
|
63
|
+
<path
|
|
64
|
+
d="M9.99981 10.0751V9.99992M17.4688 17.4688C15.889 19.0485 11.2645 16.9853 7.13958 12.8604C3.01467 8.73546 0.951405 4.11091 2.53116 2.53116C4.11091 0.951405 8.73546 3.01467 12.8604 7.13958C16.9853 11.2645 19.0485 15.889 17.4688 17.4688ZM2.53132 17.4688C0.951566 15.8891 3.01483 11.2645 7.13974 7.13963C11.2647 3.01471 15.8892 0.951453 17.469 2.53121C19.0487 4.11096 16.9854 8.73551 12.8605 12.8604C8.73562 16.9853 4.11107 19.0486 2.53132 17.4688Z"
|
|
65
|
+
strokeWidth="1.5"
|
|
66
|
+
strokeLinecap="round"
|
|
67
|
+
/>
|
|
68
|
+
</svg>
|
|
69
|
+
),
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
href: "https://rmx.as/discord",
|
|
73
|
+
text: "Join Discord",
|
|
74
|
+
icon: (
|
|
75
|
+
<svg
|
|
76
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
77
|
+
width="24"
|
|
78
|
+
height="20"
|
|
79
|
+
viewBox="0 0 24 20"
|
|
80
|
+
fill="none"
|
|
81
|
+
className="stroke-gray-600 group-hover:stroke-current dark:stroke-gray-300"
|
|
82
|
+
>
|
|
83
|
+
<path
|
|
84
|
+
d="M15.0686 1.25995L14.5477 1.17423L14.2913 1.63578C14.1754 1.84439 14.0545 2.08275 13.9422 2.31963C12.6461 2.16488 11.3406 2.16505 10.0445 2.32014C9.92822 2.08178 9.80478 1.84975 9.67412 1.62413L9.41449 1.17584L8.90333 1.25995C7.33547 1.51794 5.80717 1.99419 4.37748 2.66939L4.19 2.75793L4.07461 2.93019C1.23864 7.16437 0.46302 11.3053 0.838165 15.3924L0.868838 15.7266L1.13844 15.9264C2.81818 17.1714 4.68053 18.1233 6.68582 18.719L7.18892 18.8684L7.50166 18.4469C7.96179 17.8268 8.36504 17.1824 8.709 16.4944L8.71099 16.4904C10.8645 17.0471 13.128 17.0485 15.2821 16.4947C15.6261 17.1826 16.0293 17.8269 16.4892 18.4469L16.805 18.8725L17.3116 18.717C19.3056 18.105 21.1876 17.1751 22.8559 15.9238L23.1224 15.724L23.1528 15.3923C23.5873 10.6524 22.3579 6.53306 19.8947 2.90714L19.7759 2.73227L19.5833 2.64518C18.1437 1.99439 16.6386 1.51826 15.0686 1.25995ZM16.6074 10.7755L16.6074 10.7756C16.5934 11.6409 16.0212 12.1444 15.4783 12.1444C14.9297 12.1444 14.3493 11.6173 14.3493 10.7877C14.3493 9.94885 14.9378 9.41192 15.4783 9.41192C16.0471 9.41192 16.6209 9.93851 16.6074 10.7755ZM8.49373 12.1444C7.94513 12.1444 7.36471 11.6173 7.36471 10.7877C7.36471 9.94885 7.95323 9.41192 8.49373 9.41192C9.06038 9.41192 9.63892 9.93712 9.6417 10.7815C9.62517 11.6239 9.05462 12.1444 8.49373 12.1444Z"
|
|
85
|
+
strokeWidth="1.5"
|
|
86
|
+
/>
|
|
87
|
+
</svg>
|
|
88
|
+
),
|
|
89
|
+
},
|
|
90
|
+
];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"include": [
|
|
4
|
+
".react-router/types/**/*",
|
|
5
|
+
"app/**/*",
|
|
6
|
+
"app/**/.server/**/*",
|
|
7
|
+
"app/**/.client/**/*",
|
|
8
|
+
"workers/**/*",
|
|
9
|
+
"worker-configuration.d.ts"
|
|
10
|
+
],
|
|
11
|
+
"compilerOptions": {
|
|
12
|
+
"composite": true,
|
|
13
|
+
"strict": true,
|
|
14
|
+
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
|
15
|
+
"types": ["vite/client"],
|
|
16
|
+
"target": "ES2022",
|
|
17
|
+
"module": "ES2022",
|
|
18
|
+
"moduleResolution": "bundler",
|
|
19
|
+
"jsx": "react-jsx",
|
|
20
|
+
"rootDirs": [".", "./.react-router/types"],
|
|
21
|
+
"paths": {
|
|
22
|
+
"~/*": ["./app/*"]
|
|
23
|
+
},
|
|
24
|
+
"esModuleInterop": true,
|
|
25
|
+
"resolveJsonModule": true
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"files": [],
|
|
3
|
+
"references": [
|
|
4
|
+
{ "path": "./tsconfig.node.json" },
|
|
5
|
+
{ "path": "./tsconfig.cloudflare.json" }
|
|
6
|
+
],
|
|
7
|
+
"compilerOptions": {
|
|
8
|
+
"checkJs": true,
|
|
9
|
+
"verbatimModuleSyntax": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"strict": true,
|
|
12
|
+
"noEmit": true
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"include": ["vite.config.ts"],
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"composite": true,
|
|
6
|
+
"strict": true,
|
|
7
|
+
"types": ["node"],
|
|
8
|
+
"lib": ["ES2022"],
|
|
9
|
+
"target": "ES2022",
|
|
10
|
+
"module": "ES2022",
|
|
11
|
+
"moduleResolution": "bundler"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { reactRouter } from "@react-router/dev/vite";
|
|
2
|
+
import { cloudflare } from "@cloudflare/vite-plugin";
|
|
3
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
4
|
+
import { defineConfig } from "vite";
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
plugins: [
|
|
8
|
+
cloudflare({ viteEnvironment: { name: "ssr" } }),
|
|
9
|
+
tailwindcss(),
|
|
10
|
+
reactRouter(),
|
|
11
|
+
],
|
|
12
|
+
resolve: {
|
|
13
|
+
tsconfigPaths: true,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createRequestHandler } from "react-router";
|
|
2
|
+
|
|
3
|
+
const requestHandler = createRequestHandler(
|
|
4
|
+
() => import("virtual:react-router/server-build"),
|
|
5
|
+
import.meta.env.MODE,
|
|
6
|
+
);
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
async fetch(request) {
|
|
10
|
+
return requestHandler(request);
|
|
11
|
+
},
|
|
12
|
+
} satisfies ExportedHandler<Env>;
|
|
@@ -8,6 +8,8 @@ const { npm } = detectPackageManager();
|
|
|
8
8
|
|
|
9
9
|
const generate = async (ctx: C3Context) => {
|
|
10
10
|
await runFrameworkGenerator(ctx, [
|
|
11
|
+
// @tanstack/cli uses `create` as a subcommand
|
|
12
|
+
"create",
|
|
11
13
|
ctx.project.name,
|
|
12
14
|
"--deployment",
|
|
13
15
|
"cloudflare",
|
|
@@ -24,7 +26,7 @@ const config: TemplateConfig = {
|
|
|
24
26
|
configVersion: 1,
|
|
25
27
|
id: "tanstack-start",
|
|
26
28
|
platform: "workers",
|
|
27
|
-
frameworkCli: "@tanstack/
|
|
29
|
+
frameworkCli: "@tanstack/cli",
|
|
28
30
|
displayName: "TanStack Start",
|
|
29
31
|
generate,
|
|
30
32
|
transformPackageJson: async () => ({
|