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.
Files changed (107) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +58 -18
  3. package/copy-of-vitnode-app/.vscode/settings.json +10 -0
  4. package/copy-of-vitnode-app/README.md +62 -0
  5. package/copy-of-vitnode-app/api/.gitignore_template +32 -0
  6. package/copy-of-vitnode-app/api/drizzle.config.ts +12 -0
  7. package/copy-of-vitnode-app/api/src/index.ts +27 -0
  8. package/copy-of-vitnode-app/api/src/vitnode.api.config.ts +57 -0
  9. package/copy-of-vitnode-app/api/tsconfig.json +17 -0
  10. package/copy-of-vitnode-app/api-bun/src/index.ts +16 -0
  11. package/copy-of-vitnode-app/api-single-app/drizzle.config.ts +12 -0
  12. package/copy-of-vitnode-app/api-single-app/src/routes/api/$.ts +32 -0
  13. package/copy-of-vitnode-app/api-single-app/src/server/api-bridge.ts +22 -0
  14. package/copy-of-vitnode-app/api-single-app/src/server/vitnode-api.server.ts +29 -0
  15. package/copy-of-vitnode-app/api-single-app/src/vitnode.api.config.ts +36 -0
  16. package/copy-of-vitnode-app/docker/docker-compose.yml +30 -0
  17. package/copy-of-vitnode-app/eslint/.prettierrc.mjs +1 -1
  18. package/copy-of-vitnode-app/eslint/eslint.config.mjs +18 -2
  19. package/copy-of-vitnode-app/{root → eslint-react}/.prettierrc.mjs +1 -1
  20. package/copy-of-vitnode-app/eslint-react/eslint.config.mjs +19 -0
  21. package/copy-of-vitnode-app/monorepo/.gitignore_template +41 -0
  22. package/copy-of-vitnode-app/monorepo/apps/api/.env.example +12 -0
  23. package/copy-of-vitnode-app/monorepo/apps/web/.env.example +12 -0
  24. package/copy-of-vitnode-app/monorepo/turbo.json +53 -0
  25. package/copy-of-vitnode-app/root/.env.example +16 -5
  26. package/copy-of-vitnode-app/root/.gitignore_template +41 -0
  27. package/copy-of-vitnode-app/root/global.d.ts +28 -0
  28. package/copy-of-vitnode-app/root/src/components/admin-shell.tsx +72 -0
  29. package/copy-of-vitnode-app/root/src/components/main-header.tsx +33 -0
  30. package/copy-of-vitnode-app/root/src/lib/admin-auth.ts +11 -0
  31. package/copy-of-vitnode-app/root/src/lib/admin-nav.ts +43 -0
  32. package/copy-of-vitnode-app/root/src/lib/admin-search.ts +37 -0
  33. package/copy-of-vitnode-app/root/src/lib/auth.ts +66 -0
  34. package/copy-of-vitnode-app/root/src/lib/content-registry.ts +52 -0
  35. package/copy-of-vitnode-app/root/src/lib/i18n/runtime.ts +75 -0
  36. package/copy-of-vitnode-app/root/src/lib/i18n/shared.ts +20 -0
  37. package/copy-of-vitnode-app/root/src/lib/navigation.ts +24 -0
  38. package/copy-of-vitnode-app/root/src/lib/page-head.ts +19 -0
  39. package/copy-of-vitnode-app/root/src/locales/app.ts +28 -0
  40. package/copy-of-vitnode-app/root/src/locales/packages.ts +43 -0
  41. package/copy-of-vitnode-app/root/src/router.tsx +227 -0
  42. package/copy-of-vitnode-app/root/src/routes/__root.tsx +212 -0
  43. package/copy-of-vitnode-app/root/src/routes/_admin/admin.core.index.tsx +69 -0
  44. package/copy-of-vitnode-app/root/src/routes/_admin.tsx +258 -0
  45. package/copy-of-vitnode-app/root/src/routes/_main/index.tsx +60 -0
  46. package/copy-of-vitnode-app/root/src/routes/_main.tsx +64 -0
  47. package/copy-of-vitnode-app/root/src/server/messages.server.ts +21 -0
  48. package/copy-of-vitnode-app/root/src/start.ts +24 -0
  49. package/copy-of-vitnode-app/root/src/styles.css +139 -0
  50. package/copy-of-vitnode-app/root/src/vitnode.config.ts +73 -0
  51. package/copy-of-vitnode-app/root/src/vitnode.server.config.ts +23 -0
  52. package/copy-of-vitnode-app/root/tsconfig.json +24 -16
  53. package/copy-of-vitnode-app/root/tsr.config.json +3 -0
  54. package/copy-of-vitnode-app/root/vite.config.ts +106 -0
  55. package/copy-of-vitnode-plugin/root/.swcrc +26 -0
  56. package/copy-of-vitnode-plugin/root/global.d.ts +21 -0
  57. package/copy-of-vitnode-plugin/root/npmignore.template +17 -0
  58. package/copy-of-vitnode-plugin/root/tsconfig.build.json +5 -0
  59. package/copy-of-vitnode-plugin/root/tsconfig.json +25 -0
  60. package/dist/src/create/create-package-json.js +266 -56
  61. package/dist/src/create/create-vitnode.js +177 -28
  62. package/dist/src/create/package-versions.js +49 -0
  63. package/dist/src/helpers/get-available-package-managers.js +6 -6
  64. package/dist/src/helpers/get-package-json.js +2 -2
  65. package/dist/src/helpers/get-package-manager-from-root.js +15 -0
  66. package/dist/src/helpers/get-vitnode-package-version.js +9 -0
  67. package/dist/src/helpers/init-vitnode.js +34 -0
  68. package/dist/src/helpers/install-dependencies.js +55 -14
  69. package/dist/src/helpers/is-folder-empty.js +25 -26
  70. package/dist/src/helpers/is-online.js +16 -16
  71. package/dist/src/helpers/is-writeable.js +3 -3
  72. package/dist/src/helpers/validate-pkg.js +1 -1
  73. package/dist/src/helpers/with-If.js +1 -0
  74. package/dist/src/index.js +29 -26
  75. package/dist/src/plugin/create/add-plugin-to-workspace.js +74 -0
  76. package/dist/src/plugin/create/create-package-json.js +54 -0
  77. package/dist/src/plugin/create/create-plugin-vitnode.js +80 -0
  78. package/dist/src/plugin/create/route-templates.js +144 -0
  79. package/dist/src/plugin/index.js +17 -6
  80. package/dist/src/plugin/questions.js +14 -0
  81. package/dist/src/plugin/validation.js +76 -0
  82. package/dist/src/prepare/prepare.js +11 -8
  83. package/dist/src/questions.js +52 -15
  84. package/dist/src/validation.js +15 -15
  85. package/dist/tsconfig.build.tsbuildinfo +1 -0
  86. package/package.json +22 -12
  87. package/copy-of-vitnode-app/root/README.md +0 -1
  88. package/copy-of-vitnode-app/root/drizzle.config.ts +0 -12
  89. package/copy-of-vitnode-app/root/gitignore_template +0 -43
  90. package/copy-of-vitnode-app/root/next.config.ts +0 -11
  91. package/copy-of-vitnode-app/root/postcss.config.mjs +0 -8
  92. package/copy-of-vitnode-app/root/src/app/[locale]/(main)/[...rest]/page.tsx +0 -5
  93. package/copy-of-vitnode-app/root/src/app/[locale]/(main)/layout.tsx +0 -10
  94. package/copy-of-vitnode-app/root/src/app/[locale]/(main)/not-found.tsx +0 -5
  95. package/copy-of-vitnode-app/root/src/app/[locale]/(main)/page.tsx +0 -113
  96. package/copy-of-vitnode-app/root/src/app/[locale]/admin/(auth)/layout.tsx +0 -10
  97. package/copy-of-vitnode-app/root/src/app/[locale]/admin/not-found.tsx +0 -5
  98. package/copy-of-vitnode-app/root/src/app/[locale]/admin/page.tsx +0 -5
  99. package/copy-of-vitnode-app/root/src/app/[locale]/layout.tsx +0 -36
  100. package/copy-of-vitnode-app/root/src/app/api/[...route]/route.ts +0 -18
  101. package/copy-of-vitnode-app/root/src/app/favicon.ico +0 -0
  102. package/copy-of-vitnode-app/root/src/app/global-error.tsx +0 -27
  103. package/copy-of-vitnode-app/root/src/app/global.css +0 -128
  104. package/copy-of-vitnode-app/root/src/app/layout.tsx +0 -9
  105. package/copy-of-vitnode-app/root/src/app/not-found.tsx +0 -13
  106. package/copy-of-vitnode-app/root/src/vitnode.api.config.ts +0 -5
  107. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,21 +1,29 @@
1
1
  {
2
- "$schema": "https://json.schemastore.org/tsconfig",
3
- "extends": "eslint-config-typescript-vitnode/tsconfig",
2
+ "include": ["**/*.ts", "**/*.tsx", "eslint.config.js", "prettier.config.js", "vite.config.js"],
3
+
4
4
  "compilerOptions": {
5
- "target": "ESNext",
6
- "module": "esnext",
7
- "moduleResolution": "bundler",
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
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
20
- "exclude": ["node_modules"]
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,3 @@
1
+ {
2
+ "target": "react"
3
+ }
@@ -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,5 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/tsconfig",
3
+ "extends": "./tsconfig.json",
4
+ "exclude": ["node_modules", "**/*.test.ts", "**/*.test.tsx"]
5
+ }
@@ -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 { readFile, writeFile } from 'fs/promises';
2
- import { dirname, join } from 'path';
3
- import { fileURLToPath } from 'url';
4
- const __filename = fileURLToPath(import.meta.url);
5
- const __dirname = dirname(__filename);
6
- export const createPackageJSON = async ({ appName, packageManager, root, eslint, }) => {
7
- const pkg = JSON.parse(await readFile(join(__dirname, '..', '..', '..', 'package.json'), 'utf-8'));
8
- const packageJson = {
9
- name: appName,
10
- version: '0.1.0',
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: 'module',
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
- '@hono/zod-openapi': '^0.19.8',
29
- '@hono/zod-validator': '^0.7.0',
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
- '@tailwindcss/postcss': '^4.1.8',
48
- '@types/node': '^22.15.29',
49
- '@types/react': '^19.1.6',
50
- '@types/react-dom': '^19.1.5',
51
- ...(eslint
224
+ ...apiDevDeps(packageManager, eslint),
225
+ "@vitnode/config": vitnodeVersionRange,
226
+ ...(eslint && mode === "onlyApi"
52
227
  ? {
53
- eslint: '^9.27.0',
54
- 'eslint-config-typescript-vitnode': `^${pkg.version}`,
55
- prettier: '^3.5.3',
228
+ prettier: versionsPackageJson.prettier,
229
+ "prettier-plugin-tailwindcss": versionsPackageJson.prettierTailwind,
56
230
  }
57
231
  : {}),
58
- 'react-email': '^4.0.15',
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
- await writeFile(join(root, 'package.json'), JSON.stringify(packageJson, null, 2));
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
  };