create-vitnode-app 1.2.0-canary.9 → 2.0.0-canary.2
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/LICENSE.md +1 -1
- package/README.md +58 -18
- package/copy-of-vitnode-app/.vscode/settings.json +10 -0
- package/copy-of-vitnode-app/README.md +62 -0
- package/copy-of-vitnode-app/api/.gitignore_template +32 -0
- package/copy-of-vitnode-app/api/drizzle.config.ts +12 -0
- package/copy-of-vitnode-app/api/src/index.ts +27 -0
- package/copy-of-vitnode-app/api/src/vitnode.api.config.ts +57 -0
- package/copy-of-vitnode-app/api/tsconfig.json +17 -0
- package/copy-of-vitnode-app/api-bun/src/index.ts +16 -0
- package/copy-of-vitnode-app/api-single-app/drizzle.config.ts +12 -0
- package/copy-of-vitnode-app/api-single-app/src/routes/api/$.ts +32 -0
- package/copy-of-vitnode-app/api-single-app/src/server/api-bridge.ts +22 -0
- package/copy-of-vitnode-app/api-single-app/src/server/vitnode-api.server.ts +29 -0
- package/copy-of-vitnode-app/api-single-app/src/vitnode.api.config.ts +36 -0
- package/copy-of-vitnode-app/docker/docker-compose.yml +30 -0
- package/copy-of-vitnode-app/eslint/.prettierrc.mjs +1 -1
- package/copy-of-vitnode-app/eslint/eslint.config.mjs +18 -2
- package/copy-of-vitnode-app/{root → eslint-react}/.prettierrc.mjs +1 -1
- package/copy-of-vitnode-app/eslint-react/eslint.config.mjs +19 -0
- package/copy-of-vitnode-app/monorepo/.gitignore_template +41 -0
- package/copy-of-vitnode-app/monorepo/apps/api/.env.example +12 -0
- package/copy-of-vitnode-app/monorepo/apps/web/.env.example +12 -0
- package/copy-of-vitnode-app/monorepo/turbo.json +53 -0
- package/copy-of-vitnode-app/root/.env.example +16 -5
- package/copy-of-vitnode-app/root/.gitignore_template +41 -0
- package/copy-of-vitnode-app/root/global.d.ts +28 -0
- package/copy-of-vitnode-app/root/src/components/admin-shell.tsx +72 -0
- package/copy-of-vitnode-app/root/src/components/main-header.tsx +33 -0
- package/copy-of-vitnode-app/root/src/lib/admin-auth.ts +11 -0
- package/copy-of-vitnode-app/root/src/lib/admin-nav.ts +43 -0
- package/copy-of-vitnode-app/root/src/lib/admin-search.ts +37 -0
- package/copy-of-vitnode-app/root/src/lib/auth.ts +66 -0
- package/copy-of-vitnode-app/root/src/lib/content-registry.ts +52 -0
- package/copy-of-vitnode-app/root/src/lib/i18n/runtime.ts +75 -0
- package/copy-of-vitnode-app/root/src/lib/i18n/shared.ts +20 -0
- package/copy-of-vitnode-app/root/src/lib/navigation.ts +24 -0
- package/copy-of-vitnode-app/root/src/lib/page-head.ts +19 -0
- package/copy-of-vitnode-app/root/src/locales/app.ts +28 -0
- package/copy-of-vitnode-app/root/src/locales/packages.ts +43 -0
- package/copy-of-vitnode-app/root/src/router.tsx +227 -0
- package/copy-of-vitnode-app/root/src/routes/__root.tsx +212 -0
- package/copy-of-vitnode-app/root/src/routes/_admin/admin.core.index.tsx +69 -0
- package/copy-of-vitnode-app/root/src/routes/_admin.tsx +258 -0
- package/copy-of-vitnode-app/root/src/routes/_main/index.tsx +60 -0
- package/copy-of-vitnode-app/root/src/routes/_main.tsx +64 -0
- package/copy-of-vitnode-app/root/src/server/messages.server.ts +21 -0
- package/copy-of-vitnode-app/root/src/start.ts +24 -0
- package/copy-of-vitnode-app/root/src/styles.css +139 -0
- package/copy-of-vitnode-app/root/src/vitnode.config.ts +73 -0
- package/copy-of-vitnode-app/root/src/vitnode.server.config.ts +23 -0
- package/copy-of-vitnode-app/root/tsconfig.json +24 -16
- package/copy-of-vitnode-app/root/tsr.config.json +3 -0
- package/copy-of-vitnode-app/root/vite.config.ts +106 -0
- package/copy-of-vitnode-plugin/root/.swcrc +26 -0
- package/copy-of-vitnode-plugin/root/global.d.ts +21 -0
- package/copy-of-vitnode-plugin/root/npmignore.template +17 -0
- package/copy-of-vitnode-plugin/root/tsconfig.build.json +5 -0
- package/copy-of-vitnode-plugin/root/tsconfig.json +25 -0
- package/dist/src/create/create-package-json.js +266 -56
- package/dist/src/create/create-vitnode.js +177 -28
- package/dist/src/create/package-versions.js +49 -0
- package/dist/src/helpers/get-available-package-managers.js +6 -6
- package/dist/src/helpers/get-package-json.js +2 -2
- package/dist/src/helpers/get-package-manager-from-root.js +15 -0
- package/dist/src/helpers/get-vitnode-package-version.js +9 -0
- package/dist/src/helpers/init-vitnode.js +34 -0
- package/dist/src/helpers/install-dependencies.js +55 -14
- package/dist/src/helpers/is-folder-empty.js +25 -26
- package/dist/src/helpers/is-online.js +16 -16
- package/dist/src/helpers/is-writeable.js +3 -3
- package/dist/src/helpers/validate-pkg.js +1 -1
- package/dist/src/helpers/with-If.js +1 -0
- package/dist/src/index.js +29 -26
- package/dist/src/plugin/create/add-plugin-to-workspace.js +74 -0
- package/dist/src/plugin/create/create-package-json.js +54 -0
- package/dist/src/plugin/create/create-plugin-vitnode.js +80 -0
- package/dist/src/plugin/create/route-templates.js +144 -0
- package/dist/src/plugin/index.js +17 -6
- package/dist/src/plugin/questions.js +14 -0
- package/dist/src/plugin/validation.js +76 -0
- package/dist/src/prepare/prepare.js +11 -8
- package/dist/src/questions.js +52 -15
- package/dist/src/validation.js +15 -15
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +22 -12
- package/copy-of-vitnode-app/root/README.md +0 -1
- package/copy-of-vitnode-app/root/drizzle.config.ts +0 -12
- package/copy-of-vitnode-app/root/gitignore_template +0 -43
- package/copy-of-vitnode-app/root/next.config.ts +0 -11
- package/copy-of-vitnode-app/root/postcss.config.mjs +0 -8
- package/copy-of-vitnode-app/root/src/app/[locale]/(main)/[...rest]/page.tsx +0 -5
- package/copy-of-vitnode-app/root/src/app/[locale]/(main)/layout.tsx +0 -10
- package/copy-of-vitnode-app/root/src/app/[locale]/(main)/not-found.tsx +0 -5
- package/copy-of-vitnode-app/root/src/app/[locale]/(main)/page.tsx +0 -113
- package/copy-of-vitnode-app/root/src/app/[locale]/admin/(auth)/layout.tsx +0 -10
- package/copy-of-vitnode-app/root/src/app/[locale]/admin/not-found.tsx +0 -5
- package/copy-of-vitnode-app/root/src/app/[locale]/admin/page.tsx +0 -5
- package/copy-of-vitnode-app/root/src/app/[locale]/layout.tsx +0 -36
- package/copy-of-vitnode-app/root/src/app/api/[...route]/route.ts +0 -18
- package/copy-of-vitnode-app/root/src/app/favicon.ico +0 -0
- package/copy-of-vitnode-app/root/src/app/global-error.tsx +0 -27
- package/copy-of-vitnode-app/root/src/app/global.css +0 -128
- package/copy-of-vitnode-app/root/src/app/layout.tsx +0 -9
- package/copy-of-vitnode-app/root/src/app/not-found.tsx +0 -13
- package/copy-of-vitnode-app/root/src/vitnode.api.config.ts +0 -5
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
|
|
2
|
+
"include": ["**/*.ts", "**/*.tsx", "eslint.config.js", "prettier.config.js", "vite.config.js"],
|
|
3
|
+
|
|
4
4
|
"compilerOptions": {
|
|
5
|
-
"target": "
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"noEmit": true,
|
|
9
|
-
"baseUrl": ".",
|
|
10
|
-
"plugins": [
|
|
11
|
-
{
|
|
12
|
-
"name": "next"
|
|
13
|
-
}
|
|
14
|
-
],
|
|
5
|
+
"target": "ES2022",
|
|
6
|
+
"jsx": "react-jsx",
|
|
7
|
+
"module": "ESNext",
|
|
15
8
|
"paths": {
|
|
9
|
+
"#/*": ["./src/*"],
|
|
16
10
|
"@/*": ["./src/*"]
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
},
|
|
12
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
13
|
+
"types": ["vite/client", "node"],
|
|
14
|
+
|
|
15
|
+
/* Bundler mode */
|
|
16
|
+
"moduleResolution": "bundler",
|
|
17
|
+
"allowImportingTsExtensions": true,
|
|
18
|
+
"verbatimModuleSyntax": true,
|
|
19
|
+
"noEmit": true,
|
|
20
|
+
|
|
21
|
+
/* Linting */
|
|
22
|
+
"skipLibCheck": true,
|
|
23
|
+
"strict": true,
|
|
24
|
+
"noUnusedLocals": true,
|
|
25
|
+
"noUnusedParameters": true,
|
|
26
|
+
"noFallthroughCasesInSwitch": true,
|
|
27
|
+
"noUncheckedSideEffectImports": true
|
|
28
|
+
}
|
|
21
29
|
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
2
|
+
import { devtools } from "@tanstack/devtools-vite";
|
|
3
|
+
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
|
|
4
|
+
import viteReact from "@vitejs/plugin-react";
|
|
5
|
+
import { vitnode } from "@vitnode/core/framework/vite";
|
|
6
|
+
import { nitro } from "nitro/vite";
|
|
7
|
+
import { defineConfig } from "vite";
|
|
8
|
+
|
|
9
|
+
const config = defineConfig({
|
|
10
|
+
resolve: { tsconfigPaths: true },
|
|
11
|
+
/**
|
|
12
|
+
* A second dev server has to fail rather than quietly move.
|
|
13
|
+
*
|
|
14
|
+
* `tanstackStart()` runs the route generator and *writes*
|
|
15
|
+
* `src/routeTree.gen.ts`. Two servers means two generators owning one file: if
|
|
16
|
+
* their route lists ever differ - which is precisely what happens when one was
|
|
17
|
+
* started before a route file existed - they overwrite each other forever, and
|
|
18
|
+
* every write is a full page reload. Without `strictPort` the second `pnpm dev`
|
|
19
|
+
* says "Port 3000 is in use, trying another one" and succeeds, so the fight
|
|
20
|
+
* starts silently and looks like an inexplicable refresh loop on the first
|
|
21
|
+
* server.
|
|
22
|
+
*/
|
|
23
|
+
server: { strictPort: true },
|
|
24
|
+
ssr: {
|
|
25
|
+
/**
|
|
26
|
+
* The VitNode API packages mounted at `/api/*`, kept out of the SSR pass.
|
|
27
|
+
*
|
|
28
|
+
* They are Node libraries rather than app source: `@vitnode/core` loads its
|
|
29
|
+
* locale files with a runtime `import("./en.json", { with: { type: "json" } })`
|
|
30
|
+
* relative to its own `dist`. Bundling them in this pass moves that chunk
|
|
31
|
+
* and the JSON stops resolving, which fails the build outright. Left
|
|
32
|
+
* external here, Nitro resolves them from the package itself.
|
|
33
|
+
*
|
|
34
|
+
* Every VitNode package the app installs belongs on this list - add a
|
|
35
|
+
* plugin's package name here when you install one.
|
|
36
|
+
*
|
|
37
|
+
* This is also what decides the shape of `@vitnode/core/tanstack/*`, so it is
|
|
38
|
+
* worth naming the consequence rather than leaving it to be rediscovered.
|
|
39
|
+
* Externalised here, the package skips this pass entirely and Nitro's own
|
|
40
|
+
* Rollup run inlines its `dist` afterwards - and nothing in that path runs
|
|
41
|
+
* the TanStack Start compiler. The *client* build has no such gap: it inlines
|
|
42
|
+
* the package, so the compiler transforms it there. So package code reaches
|
|
43
|
+
* the browser compiled and the server un-compiled, which is exactly why the
|
|
44
|
+
* package may declare `createIsomorphicFn` (its stub falls back to the
|
|
45
|
+
* `.server()` branch, which is what a server wants) and may never declare
|
|
46
|
+
* `createServerFn` (un-compiled, its handler resolves to `undefined` with no
|
|
47
|
+
* error at all). `packages/vitnode/src/tanstack/boundary.test.ts` holds the
|
|
48
|
+
* package to that.
|
|
49
|
+
*
|
|
50
|
+
* Removing `@vitnode/core` from this list to close the gap was measured and
|
|
51
|
+
* does not work: the SSR pass then reaches the locale barrel above and the
|
|
52
|
+
* build fails on `Could not resolve './en.json'`.
|
|
53
|
+
*
|
|
54
|
+
* ## `tslib` is here for an entirely different reason
|
|
55
|
+
*
|
|
56
|
+
* It is not a VitNode package and it is not a Node library. It is here
|
|
57
|
+
* because bundling it is broken, in a way that only appears in a production
|
|
58
|
+
* build and only once a page renders.
|
|
59
|
+
*
|
|
60
|
+
* The Radix scroll-lock stack that every modal in a VitNode page pulls in -
|
|
61
|
+
* `react-remove-scroll`, `use-sidecar`, `aria-hidden` - does
|
|
62
|
+
* `import { __extends } from "tslib"`. Under the `node` condition that
|
|
63
|
+
* resolves to `tslib/modules/index.js`, a two-line ESM shim around the
|
|
64
|
+
* **CommonJS** `tslib.js`:
|
|
65
|
+
*
|
|
66
|
+
* import tslib from "../tslib.js";
|
|
67
|
+
* const { __extends, … } = tslib;
|
|
68
|
+
*
|
|
69
|
+
* `tslib.js` defines `__esModule` on its exports, so Rolldown's CJS interop
|
|
70
|
+
* helper does not synthesise a `default` - while the call site it generated
|
|
71
|
+
* still reads `.default`. Every page that renders a dialog then throws
|
|
72
|
+
* `Cannot destructure property '__extends' of undefined`.
|
|
73
|
+
*
|
|
74
|
+
* Externalised, the file is never bundled: Nitro traces the package into the
|
|
75
|
+
* output and Node loads it with Node's own interop, which is correct. An
|
|
76
|
+
* alias to `tslib/tslib.es6.mjs` was tried first and is worse - it fixes
|
|
77
|
+
* Vite's copy and not Nitro's, because Nitro re-resolves externals itself,
|
|
78
|
+
* and the tracer then copies only the file the alias named.
|
|
79
|
+
*/
|
|
80
|
+
external: ["@vitnode/core", "tslib"],
|
|
81
|
+
},
|
|
82
|
+
plugins: [
|
|
83
|
+
/**
|
|
84
|
+
* Environment handling, the dev server's dependency pre-bundling and the
|
|
85
|
+
* plugin route registry, in the order they have to run.
|
|
86
|
+
*
|
|
87
|
+
* `appRoot` is `import.meta.dirname` because a Vite config is loaded with
|
|
88
|
+
* the working directory set to wherever the command ran, which in a
|
|
89
|
+
* monorepo is regularly the repository root.
|
|
90
|
+
*
|
|
91
|
+
* `clientEnv` is not passed: this app publishes nothing to the browser
|
|
92
|
+
* beyond the two keys VitNode inlines for every install
|
|
93
|
+
* (`NEXT_PUBLIC_API_URL`, `NEXT_PUBLIC_WEB_URL`). Anything named there is
|
|
94
|
+
* compiled into JavaScript anyone can read, so a key is added only when
|
|
95
|
+
* something in the browser genuinely reads it.
|
|
96
|
+
*/
|
|
97
|
+
vitnode({ appRoot: import.meta.dirname }),
|
|
98
|
+
devtools(),
|
|
99
|
+
nitro({ rollupConfig: { external: [/^@sentry\//] } }),
|
|
100
|
+
tailwindcss(),
|
|
101
|
+
tanstackStart(),
|
|
102
|
+
viteReact(),
|
|
103
|
+
],
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
export default config;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://swc.rs/schema.json",
|
|
3
|
+
"exclude": ["\\.test\\.tsx?$"],
|
|
4
|
+
"minify": true,
|
|
5
|
+
"jsc": {
|
|
6
|
+
"baseUrl": "./",
|
|
7
|
+
"target": "esnext",
|
|
8
|
+
"paths": {
|
|
9
|
+
"@/*": ["./src/*"]
|
|
10
|
+
},
|
|
11
|
+
"parser": {
|
|
12
|
+
"syntax": "typescript",
|
|
13
|
+
"tsx": true
|
|
14
|
+
},
|
|
15
|
+
"transform": {
|
|
16
|
+
"react": {
|
|
17
|
+
"runtime": "automatic"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"module": {
|
|
22
|
+
"type": "nodenext",
|
|
23
|
+
"strict": true,
|
|
24
|
+
"resolveFully": true
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/// <reference types="use-intl" />
|
|
2
|
+
|
|
3
|
+
import coreApi from "@vitnode/core/locales/api/en.json" with { type: "json" };
|
|
4
|
+
import core from "@vitnode/core/locales/en.json" with { type: "json" };
|
|
5
|
+
import plugin from "./src/locales/en.json" with { type: "json" };
|
|
6
|
+
|
|
7
|
+
// Augmenting `use-intl`, not `next-intl`. `AppConfig` is declared by `use-intl`,
|
|
8
|
+
// which is what VitNode renders every string through on every host, and a plugin
|
|
9
|
+
// is compiled into its own `dist` and imported by whichever app installed it -
|
|
10
|
+
// so a type-level dependency on one host's framework is one every installing app
|
|
11
|
+
// inherits. `use-intl` must be a direct dependency of this package for the
|
|
12
|
+
// reference above to resolve under pnpm's strict `node_modules`.
|
|
13
|
+
//
|
|
14
|
+
// A plugin can render on both sides (UI components and, e.g., emails), so it
|
|
15
|
+
// types keys against both of core's trees. Add your own server tree here too
|
|
16
|
+
// (`./src/locales/api/en.json`) once your plugin sends email.
|
|
17
|
+
declare module "use-intl" {
|
|
18
|
+
interface AppConfig {
|
|
19
|
+
Messages: typeof plugin & typeof core & typeof coreApi;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/src/*
|
|
2
|
+
!/src/routes
|
|
3
|
+
!/src/routes/**
|
|
4
|
+
!/src/locales
|
|
5
|
+
!/src/locales/**
|
|
6
|
+
|
|
7
|
+
/node_modules
|
|
8
|
+
/.turbo
|
|
9
|
+
/tsconfig.json
|
|
10
|
+
/.swcrc
|
|
11
|
+
/components.json
|
|
12
|
+
/global.d.ts
|
|
13
|
+
/tsup.config.ts
|
|
14
|
+
/vitest.config.ts
|
|
15
|
+
/tsconfig.json
|
|
16
|
+
/scripts
|
|
17
|
+
/config
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"extends": "@vitnode/config/tsconfig",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"target": "ESNext",
|
|
6
|
+
"module": "esnext",
|
|
7
|
+
"moduleResolution": "bundler",
|
|
8
|
+
"rootDir": "./",
|
|
9
|
+
"outDir": "./dist",
|
|
10
|
+
"jsx": "react-jsx",
|
|
11
|
+
"emitDeclarationOnly": true,
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"declarationMap": true,
|
|
14
|
+
"plugins": [
|
|
15
|
+
{
|
|
16
|
+
"name": "next"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"paths": {
|
|
20
|
+
"@/*": ["./src/*"]
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"exclude": ["node_modules"],
|
|
24
|
+
"include": ["src", "global.d.ts"]
|
|
25
|
+
}
|
|
@@ -1,66 +1,276 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { writeFile } from "fs/promises";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { getAvailablePackageManagers } from "../helpers/get-available-package-managers.js";
|
|
4
|
+
import { getVitnodePackageVersion } from "../helpers/get-vitnode-package-version.js";
|
|
5
|
+
import { withIf } from "../helpers/with-If.js";
|
|
6
|
+
import { versionsPackageJson } from "./package-versions.js";
|
|
7
|
+
const writeJson = async (path, data) => writeFile(path, JSON.stringify(data, null, 2));
|
|
8
|
+
const paths = (root) => ({
|
|
9
|
+
root,
|
|
10
|
+
api: join(root, "apps", "api"),
|
|
11
|
+
web: join(root, "apps", "web"),
|
|
12
|
+
});
|
|
13
|
+
const eslintScripts = {
|
|
14
|
+
lint: "eslint .",
|
|
15
|
+
"lint:fix": "eslint . --fix",
|
|
16
|
+
};
|
|
17
|
+
const i18nScripts = {
|
|
18
|
+
"i18n:create": "vitnode i18n:create",
|
|
19
|
+
"i18n:check": "vitnode i18n:check",
|
|
20
|
+
"i18n:delete": "vitnode i18n:delete",
|
|
21
|
+
"i18n:update": "vitnode i18n:update",
|
|
22
|
+
"i18n:update:ai": "vitnode i18n:update:ai",
|
|
23
|
+
};
|
|
24
|
+
const dockerDevScript = (appName) => `docker compose -f ./docker-compose.yml -p ${appName}-vitnode-dev up -d`;
|
|
25
|
+
export const rootScripts = (enableEslint, enableDocker, appName) => ({
|
|
26
|
+
"db:migrate": "turbo db:migrate",
|
|
27
|
+
"db:prepare": "turbo db:prepare",
|
|
28
|
+
dev: "turbo db:prepare && turbo dev",
|
|
29
|
+
build: "turbo build",
|
|
30
|
+
start: "turbo start",
|
|
31
|
+
"i18n:create": "turbo i18n:create",
|
|
32
|
+
"i18n:check": "turbo i18n:check",
|
|
33
|
+
"i18n:delete": "turbo i18n:delete",
|
|
34
|
+
"i18n:update": "turbo i18n:update",
|
|
35
|
+
"i18n:update:ai": "turbo i18n:update:ai",
|
|
36
|
+
...withIf(enableEslint, {
|
|
37
|
+
lint: "turbo lint",
|
|
38
|
+
"lint:fix": "turbo lint:fix",
|
|
39
|
+
}),
|
|
40
|
+
...withIf(enableDocker, { "docker:dev": dockerDevScript(appName) }),
|
|
41
|
+
});
|
|
42
|
+
export const apiScripts = (pm, eslint, docker, onlyApi, appName) => {
|
|
43
|
+
return {
|
|
44
|
+
"db:migrate": "vitnode migrate",
|
|
45
|
+
"db:prepare": "vitnode db:prepare",
|
|
46
|
+
...(pm === "bun"
|
|
47
|
+
? {
|
|
48
|
+
dev: "vitnode db:prepare && bun run --hot src/index.ts",
|
|
49
|
+
start: "NODE_ENV=production bun run src/index.ts",
|
|
50
|
+
}
|
|
51
|
+
: {
|
|
52
|
+
dev: "vitnode db:prepare && tsx watch src/index.ts",
|
|
53
|
+
build: "tsc && tsc-alias -p tsconfig.json",
|
|
54
|
+
start: "node dist/index.js",
|
|
55
|
+
}),
|
|
56
|
+
"dev:email": "email dev --dir src/emails",
|
|
57
|
+
...i18nScripts,
|
|
58
|
+
...withIf(eslint, eslintScripts),
|
|
59
|
+
...withIf(docker && onlyApi, { "docker:dev": dockerDevScript(appName) }),
|
|
60
|
+
"drizzle-kit": "drizzle-kit",
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
export const singleAppScripts = (eslint, docker, appName) => ({
|
|
64
|
+
"db:migrate": "vitnode migrate",
|
|
65
|
+
"db:prepare": "vitnode db:prepare",
|
|
66
|
+
dev: "vitnode db:prepare && vite dev --port 3000",
|
|
67
|
+
"dev:email": "email dev --dir src/emails",
|
|
68
|
+
build: "vite build",
|
|
69
|
+
start: "node .output/server/index.mjs",
|
|
70
|
+
...i18nScripts,
|
|
71
|
+
...withIf(eslint, eslintScripts),
|
|
72
|
+
...withIf(docker, { "docker:dev": dockerDevScript(appName) }),
|
|
73
|
+
"drizzle-kit": "drizzle-kit",
|
|
74
|
+
});
|
|
75
|
+
export const webScripts = (eslint) => ({
|
|
76
|
+
dev: "vite dev --port 3000",
|
|
77
|
+
build: "vite build",
|
|
78
|
+
start: "node .output/server/index.mjs",
|
|
79
|
+
...i18nScripts,
|
|
80
|
+
...withIf(eslint, eslintScripts),
|
|
81
|
+
});
|
|
82
|
+
const baseDevDeps = (eslint, includePrettier) => ({
|
|
83
|
+
"@types/node": versionsPackageJson.typesNode,
|
|
84
|
+
"@vitnode/config": "",
|
|
85
|
+
...withIf(eslint, {
|
|
86
|
+
eslint: versionsPackageJson.eslint,
|
|
87
|
+
...withIf(includePrettier, {
|
|
88
|
+
prettier: versionsPackageJson.prettier,
|
|
89
|
+
"prettier-plugin-tailwindcss": versionsPackageJson.prettierTailwind,
|
|
90
|
+
}),
|
|
91
|
+
}),
|
|
92
|
+
});
|
|
93
|
+
const rootDevDeps = (eslint) => ({
|
|
94
|
+
...baseDevDeps(eslint, true),
|
|
95
|
+
turbo: versionsPackageJson.turbo,
|
|
96
|
+
typescript: versionsPackageJson.typescript,
|
|
97
|
+
zod: versionsPackageJson.zod,
|
|
98
|
+
});
|
|
99
|
+
const apiDeps = {
|
|
100
|
+
"@hono/zod-openapi": versionsPackageJson.honoZodOpenapi,
|
|
101
|
+
"@hono/zod-validator": versionsPackageJson.honoZodValidator,
|
|
102
|
+
"@vitnode/core": "",
|
|
103
|
+
"drizzle-kit": versionsPackageJson.drizzleKit,
|
|
104
|
+
"drizzle-orm": versionsPackageJson.drizzleOrm,
|
|
105
|
+
hono: versionsPackageJson.hono,
|
|
106
|
+
react: versionsPackageJson.react,
|
|
107
|
+
"react-dom": versionsPackageJson.reactDom,
|
|
108
|
+
"react-email": versionsPackageJson.reactEmail,
|
|
109
|
+
ws: versionsPackageJson.ws,
|
|
110
|
+
zod: versionsPackageJson.zod,
|
|
111
|
+
};
|
|
112
|
+
const apiDevDeps = (pm, eslint) => ({
|
|
113
|
+
"@hono/node-server": "^2.0",
|
|
114
|
+
"@react-email/ui": versionsPackageJson.reactEmailUi,
|
|
115
|
+
...(pm === "bun" ? { "@types/bun": versionsPackageJson.typesBun } : {}),
|
|
116
|
+
"@types/node": versionsPackageJson.typesNode,
|
|
117
|
+
"@types/react": versionsPackageJson.typesReact,
|
|
118
|
+
"@types/react-dom": versionsPackageJson.typesReactDom,
|
|
119
|
+
"@vitnode/config": "",
|
|
120
|
+
dotenv: versionsPackageJson.dotenv,
|
|
121
|
+
...withIf(eslint, {
|
|
122
|
+
eslint: versionsPackageJson.eslint,
|
|
123
|
+
}),
|
|
124
|
+
"tsc-alias": versionsPackageJson.tscAlias,
|
|
125
|
+
tsx: versionsPackageJson.tsx,
|
|
126
|
+
typescript: versionsPackageJson.typescript,
|
|
127
|
+
});
|
|
128
|
+
const tanstackWebDeps = {
|
|
129
|
+
"@tailwindcss/vite": versionsPackageJson.tailwindVite,
|
|
130
|
+
"@tanstack/react-query": versionsPackageJson.tanstackReactQuery,
|
|
131
|
+
"@tanstack/react-router": versionsPackageJson.tanstackReactRouter,
|
|
132
|
+
"@tanstack/react-router-ssr-query": versionsPackageJson.tanstackRouterSsrQuery,
|
|
133
|
+
"@tanstack/react-start": versionsPackageJson.tanstackReactStart,
|
|
134
|
+
"@vitnode/core": "",
|
|
135
|
+
"lucide-react": versionsPackageJson.lucide,
|
|
136
|
+
nitro: versionsPackageJson.nitro,
|
|
137
|
+
react: versionsPackageJson.react,
|
|
138
|
+
"react-dom": versionsPackageJson.reactDom,
|
|
139
|
+
"react-hook-form": versionsPackageJson.rhf,
|
|
140
|
+
sonner: versionsPackageJson.sonner,
|
|
141
|
+
tailwindcss: versionsPackageJson.tailwind,
|
|
142
|
+
tslib: versionsPackageJson.tslib,
|
|
143
|
+
"use-intl": versionsPackageJson.useIntl,
|
|
144
|
+
zod: versionsPackageJson.zod,
|
|
145
|
+
};
|
|
146
|
+
const singleAppDeps = {
|
|
147
|
+
...tanstackWebDeps,
|
|
148
|
+
"@hono/zod-openapi": versionsPackageJson.honoZodOpenapi,
|
|
149
|
+
"@hono/zod-validator": versionsPackageJson.honoZodValidator,
|
|
150
|
+
"@hookform/resolvers": versionsPackageJson.rhfResolvers,
|
|
151
|
+
"drizzle-kit": versionsPackageJson.drizzleKit,
|
|
152
|
+
"drizzle-orm": versionsPackageJson.drizzleOrm,
|
|
153
|
+
hono: versionsPackageJson.hono,
|
|
154
|
+
"react-email": versionsPackageJson.reactEmail,
|
|
155
|
+
shadcn: versionsPackageJson.shadcn,
|
|
156
|
+
};
|
|
157
|
+
const tanstackWebDevDeps = {
|
|
158
|
+
"@tanstack/devtools-vite": versionsPackageJson.tanstackDevtoolsVite,
|
|
159
|
+
"@tanstack/react-devtools": versionsPackageJson.tanstackReactDevtools,
|
|
160
|
+
"@tanstack/react-query-devtools": versionsPackageJson.tanstackQueryDevtools,
|
|
161
|
+
"@tanstack/react-router-devtools": versionsPackageJson.tanstackRouterDevtools,
|
|
162
|
+
"@types/node": versionsPackageJson.typesNode,
|
|
163
|
+
"@types/react": versionsPackageJson.typesReact,
|
|
164
|
+
"@types/react-dom": versionsPackageJson.typesReactDom,
|
|
165
|
+
"@vitejs/plugin-react": versionsPackageJson.viteReact,
|
|
166
|
+
"@vitnode/config": "",
|
|
167
|
+
"tw-animate-css": versionsPackageJson.twAnimateCss,
|
|
168
|
+
typescript: versionsPackageJson.typescript,
|
|
169
|
+
vite: versionsPackageJson.vite,
|
|
170
|
+
};
|
|
171
|
+
const singleAppDevDeps = (eslint) => ({
|
|
172
|
+
...tanstackWebDevDeps,
|
|
173
|
+
"@react-email/ui": versionsPackageJson.reactEmailUi,
|
|
174
|
+
...withIf(eslint, {
|
|
175
|
+
eslint: versionsPackageJson.eslint,
|
|
176
|
+
prettier: versionsPackageJson.prettier,
|
|
177
|
+
"prettier-plugin-tailwindcss": versionsPackageJson.prettierTailwind,
|
|
178
|
+
}),
|
|
179
|
+
turbo: versionsPackageJson.turbo,
|
|
180
|
+
});
|
|
181
|
+
const webDeps = {
|
|
182
|
+
...tanstackWebDeps,
|
|
183
|
+
shadcn: versionsPackageJson.shadcn,
|
|
184
|
+
};
|
|
185
|
+
const webDevDeps = (eslint) => ({
|
|
186
|
+
...tanstackWebDevDeps,
|
|
187
|
+
"@hookform/resolvers": versionsPackageJson.rhfResolvers,
|
|
188
|
+
"class-variance-authority": versionsPackageJson.cva,
|
|
189
|
+
...withIf(eslint, { eslint: versionsPackageJson.eslint }),
|
|
190
|
+
});
|
|
191
|
+
export const createPackageJSON = async ({ appName, packageManager, root, eslint, docker, mode, monorepo, }) => {
|
|
192
|
+
const vitnodeVersionRange = await getVitnodePackageVersion();
|
|
193
|
+
const pmVersions = await getAvailablePackageManagers();
|
|
194
|
+
const pmSpec = `${packageManager}@${pmVersions[packageManager]}`;
|
|
195
|
+
const p = paths(root);
|
|
196
|
+
const isApiMonorepo = mode === "apiMonorepo" || !!monorepo;
|
|
197
|
+
const isOnlyApi = mode === "onlyApi";
|
|
198
|
+
const isSingleApp = mode === "singleApp";
|
|
199
|
+
if (isApiMonorepo) {
|
|
200
|
+
const rootPkg = {
|
|
201
|
+
name: appName,
|
|
202
|
+
private: true,
|
|
203
|
+
scripts: rootScripts(eslint, !!docker, appName),
|
|
204
|
+
devDependencies: {
|
|
205
|
+
...rootDevDeps(eslint),
|
|
206
|
+
"@vitnode/config": vitnodeVersionRange,
|
|
207
|
+
},
|
|
208
|
+
packageManager: pmSpec,
|
|
209
|
+
workspaces: ["apps/*", "plugins/*"],
|
|
210
|
+
};
|
|
211
|
+
await writeJson(join(p.root, "package.json"), rootPkg);
|
|
212
|
+
}
|
|
213
|
+
const apiPkg = {
|
|
214
|
+
name: isApiMonorepo ? "api" : appName,
|
|
215
|
+
version: "0.1.0",
|
|
11
216
|
private: true,
|
|
12
|
-
type:
|
|
13
|
-
scripts:
|
|
14
|
-
'drizzle-kit': 'drizzle-kit',
|
|
15
|
-
'db:push': 'drizzle-kit push',
|
|
16
|
-
'db:migrate': 'drizzle-kit up && drizzle-kit generate && drizzle-kit migrate',
|
|
17
|
-
dev: 'vitnode init && next dev --turbopack',
|
|
18
|
-
build: 'next build --turbopack',
|
|
19
|
-
start: 'next start',
|
|
20
|
-
...(eslint
|
|
21
|
-
? {
|
|
22
|
-
lint: 'eslint .',
|
|
23
|
-
'lint:fix': 'eslint . --fix',
|
|
24
|
-
}
|
|
25
|
-
: {}),
|
|
26
|
-
},
|
|
217
|
+
type: "module",
|
|
218
|
+
scripts: apiScripts(packageManager, eslint, !!docker, mode === "onlyApi", appName),
|
|
27
219
|
dependencies: {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
'@hookform/resolvers': '^5.0.1',
|
|
31
|
-
'@react-email/components': '^0.0.41',
|
|
32
|
-
'@vitnode/core': `^${pkg.version}`,
|
|
33
|
-
'babel-plugin-react-compiler': '19.1.0-rc.2',
|
|
34
|
-
'drizzle-kit': '^0.31.1',
|
|
35
|
-
'drizzle-orm': '^0.44.1',
|
|
36
|
-
hono: '^4.7.10',
|
|
37
|
-
'lucide-react': '^0.513.0',
|
|
38
|
-
next: '^15.3.3',
|
|
39
|
-
'next-intl': '^4.1.0',
|
|
40
|
-
react: '^19.1.0',
|
|
41
|
-
'react-dom': '^19.1.0',
|
|
42
|
-
'react-hook-form': '^7.56.4',
|
|
43
|
-
sonner: '^2.0.3',
|
|
44
|
-
zod: '^3.25.42',
|
|
220
|
+
...apiDeps,
|
|
221
|
+
"@vitnode/core": vitnodeVersionRange,
|
|
45
222
|
},
|
|
46
223
|
devDependencies: {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
'@types/react-dom': '^19.1.5',
|
|
51
|
-
...(eslint
|
|
224
|
+
...apiDevDeps(packageManager, eslint),
|
|
225
|
+
"@vitnode/config": vitnodeVersionRange,
|
|
226
|
+
...(eslint && mode === "onlyApi"
|
|
52
227
|
? {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
prettier: '^3.5.3',
|
|
228
|
+
prettier: versionsPackageJson.prettier,
|
|
229
|
+
"prettier-plugin-tailwindcss": versionsPackageJson.prettierTailwind,
|
|
56
230
|
}
|
|
57
231
|
: {}),
|
|
58
|
-
|
|
59
|
-
tailwindcss: '^4.1.8',
|
|
60
|
-
'tw-animate-css': '^1.3.2',
|
|
61
|
-
typescript: '^5.8.3',
|
|
232
|
+
...(packageManager === "bun" ? {} : {}),
|
|
62
233
|
},
|
|
63
|
-
packageManager,
|
|
64
234
|
};
|
|
65
|
-
|
|
235
|
+
if (isSingleApp) {
|
|
236
|
+
const singlePkg = {
|
|
237
|
+
name: monorepo ? "web" : appName,
|
|
238
|
+
version: "0.1.0",
|
|
239
|
+
private: true,
|
|
240
|
+
type: "module",
|
|
241
|
+
scripts: singleAppScripts(eslint, !!docker, appName),
|
|
242
|
+
dependencies: {
|
|
243
|
+
...singleAppDeps,
|
|
244
|
+
"@vitnode/core": vitnodeVersionRange,
|
|
245
|
+
},
|
|
246
|
+
devDependencies: {
|
|
247
|
+
...singleAppDevDeps(eslint),
|
|
248
|
+
"@vitnode/config": vitnodeVersionRange,
|
|
249
|
+
},
|
|
250
|
+
packageManager: pmSpec,
|
|
251
|
+
};
|
|
252
|
+
await writeJson(join(monorepo ? p.web : p.root, "package.json"), singlePkg);
|
|
253
|
+
}
|
|
254
|
+
if (mode === "apiMonorepo") {
|
|
255
|
+
await writeJson(join(p.api, "package.json"), apiPkg);
|
|
256
|
+
const webPkg = {
|
|
257
|
+
name: "web",
|
|
258
|
+
version: "0.1.0",
|
|
259
|
+
private: true,
|
|
260
|
+
type: "module",
|
|
261
|
+
scripts: webScripts(eslint),
|
|
262
|
+
dependencies: {
|
|
263
|
+
...webDeps,
|
|
264
|
+
"@vitnode/core": vitnodeVersionRange,
|
|
265
|
+
},
|
|
266
|
+
devDependencies: {
|
|
267
|
+
...webDevDeps(eslint),
|
|
268
|
+
"@vitnode/config": vitnodeVersionRange,
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
await writeJson(join(p.web, "package.json"), webPkg);
|
|
272
|
+
}
|
|
273
|
+
if (isOnlyApi) {
|
|
274
|
+
await writeJson(join(monorepo ? p.api : p.root, "package.json"), apiPkg);
|
|
275
|
+
}
|
|
66
276
|
};
|