better-ts-stack 1.1.4 → 2.0.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.
Files changed (161) hide show
  1. package/README.md +113 -82
  2. package/dist/args.d.ts +12 -0
  3. package/dist/args.d.ts.map +1 -0
  4. package/dist/args.js +90 -0
  5. package/dist/args.js.map +1 -0
  6. package/dist/builder/configGenerator.d.ts.map +1 -1
  7. package/dist/builder/configGenerator.js +10 -3
  8. package/dist/builder/configGenerator.js.map +1 -1
  9. package/dist/builder/dependencyInstaller.d.ts.map +1 -1
  10. package/dist/builder/dependencyInstaller.js +8 -14
  11. package/dist/builder/dependencyInstaller.js.map +1 -1
  12. package/dist/builder/gitInitializer.d.ts.map +1 -1
  13. package/dist/builder/gitInitializer.js +8 -41
  14. package/dist/builder/gitInitializer.js.map +1 -1
  15. package/dist/builder/index.d.ts.map +1 -1
  16. package/dist/builder/index.js +24 -63
  17. package/dist/builder/index.js.map +1 -1
  18. package/dist/builder/moduleSelector.d.ts +1 -4
  19. package/dist/builder/moduleSelector.d.ts.map +1 -1
  20. package/dist/builder/moduleSelector.js +11 -15
  21. package/dist/builder/moduleSelector.js.map +1 -1
  22. package/dist/builder/templateContext.d.ts +2 -17
  23. package/dist/builder/templateContext.d.ts.map +1 -1
  24. package/dist/builder/templateContext.js +6 -5
  25. package/dist/builder/templateContext.js.map +1 -1
  26. package/dist/index.js +45 -20
  27. package/dist/index.js.map +1 -1
  28. package/dist/output/nextSteps.d.ts +1 -2
  29. package/dist/output/nextSteps.d.ts.map +1 -1
  30. package/dist/output/nextSteps.js +10 -19
  31. package/dist/output/nextSteps.js.map +1 -1
  32. package/dist/prompts/index.d.ts +3 -3
  33. package/dist/prompts/index.d.ts.map +1 -1
  34. package/dist/prompts/index.js +22 -58
  35. package/dist/prompts/index.js.map +1 -1
  36. package/dist/prompts/stack.d.ts +3 -2
  37. package/dist/prompts/stack.d.ts.map +1 -1
  38. package/dist/prompts/stack.js +81 -70
  39. package/dist/prompts/stack.js.map +1 -1
  40. package/dist/types/index.d.ts +20 -42
  41. package/dist/types/index.d.ts.map +1 -1
  42. package/dist/types/index.js +40 -38
  43. package/dist/types/index.js.map +1 -1
  44. package/dist/ui/index.d.ts +3 -0
  45. package/dist/ui/index.d.ts.map +1 -0
  46. package/dist/ui/index.js +19 -0
  47. package/dist/ui/index.js.map +1 -0
  48. package/dist/ui/messages.d.ts +9 -0
  49. package/dist/ui/messages.d.ts.map +1 -0
  50. package/dist/ui/messages.js +100 -0
  51. package/dist/ui/messages.js.map +1 -0
  52. package/dist/ui/prompts.d.ts +20 -0
  53. package/dist/ui/prompts.d.ts.map +1 -0
  54. package/dist/ui/prompts.js +71 -0
  55. package/dist/ui/prompts.js.map +1 -0
  56. package/dist/ui/theme.d.ts +9 -0
  57. package/dist/ui/theme.d.ts.map +1 -0
  58. package/dist/ui/theme.js +24 -0
  59. package/dist/ui/theme.js.map +1 -0
  60. package/dist/validators/index.d.ts +1 -0
  61. package/dist/validators/index.d.ts.map +1 -1
  62. package/dist/validators/index.js +6 -0
  63. package/dist/validators/index.js.map +1 -1
  64. package/package.json +70 -66
  65. package/templates/backend/express/config.json +44 -44
  66. package/templates/backend/express/eslint.config.mjs +40 -40
  67. package/templates/backend/express/gitignore +36 -36
  68. package/templates/backend/express/src/index.ts +76 -76
  69. package/templates/backend/express/src/routes/health.ts +12 -12
  70. package/templates/backend/express/tsconfig.json +25 -25
  71. package/templates/backend/nestjs/.prettierignore +52 -0
  72. package/templates/backend/nestjs/.prettierrc +16 -0
  73. package/templates/backend/nestjs/config.json +44 -0
  74. package/templates/backend/nestjs/eslint.config.mjs +40 -0
  75. package/templates/backend/nestjs/gitignore +36 -0
  76. package/templates/backend/nestjs/nest-cli.json +9 -0
  77. package/templates/backend/nestjs/src/app.module.ts.hbs +34 -0
  78. package/templates/backend/nestjs/src/health/health.controller.ts +12 -0
  79. package/templates/backend/nestjs/src/main.ts +23 -0
  80. package/templates/backend/nestjs/tsconfig.eslint.json +9 -0
  81. package/templates/backend/nestjs/tsconfig.json +25 -0
  82. package/templates/frontend/nextjs/app/layout.tsx +13 -13
  83. package/templates/frontend/nextjs/app/page.tsx.hbs +97 -97
  84. package/templates/frontend/nextjs/components/ui/button.tsx +51 -51
  85. package/templates/frontend/nextjs/components/ui/card.tsx +60 -60
  86. package/templates/frontend/nextjs/components/ui/field.tsx +67 -67
  87. package/templates/frontend/nextjs/components/ui/input.tsx +18 -18
  88. package/templates/frontend/nextjs/components.json +19 -19
  89. package/templates/frontend/nextjs/config.json +38 -38
  90. package/templates/frontend/nextjs/eslint.config.mjs +11 -11
  91. package/templates/frontend/nextjs/gitignore +42 -42
  92. package/templates/frontend/nextjs/lib/utils.ts +6 -6
  93. package/templates/frontend/nextjs/next.config.ts.hbs +12 -12
  94. package/templates/frontend/nextjs/proxy.ts.hbs +24 -24
  95. package/templates/frontend/nextjs/tsconfig.json +34 -34
  96. package/templates/frontend/tanstack/config.json +48 -48
  97. package/templates/frontend/tanstack/src/routeTree.gen.ts +68 -68
  98. package/templates/frontend/tanstack/src/styles/app.css +85 -85
  99. package/templates/modules/auth/express/config.json +27 -26
  100. package/templates/modules/auth/express/src/controllers/authController.ts.hbs +116 -130
  101. package/templates/modules/auth/express/src/middleware/requireAuth.ts.hbs +26 -26
  102. package/templates/modules/auth/express/src/services/userStore.ts.hbs +117 -117
  103. package/templates/modules/auth/nestjs/config.json +24 -0
  104. package/templates/modules/auth/nestjs/src/auth/auth.controller.ts +46 -0
  105. package/templates/modules/auth/nestjs/src/auth/auth.guard.ts +36 -0
  106. package/templates/modules/auth/nestjs/src/auth/auth.module.ts.hbs +22 -0
  107. package/templates/modules/auth/nestjs/src/auth/auth.schemas.ts +35 -0
  108. package/templates/modules/auth/nestjs/src/auth/auth.service.ts +70 -0
  109. package/templates/modules/auth/nestjs/src/auth/jwt.ts +27 -0
  110. package/templates/modules/auth/nestjs/src/auth/users.service.ts.hbs +144 -0
  111. package/templates/modules/auth/nestjs/src/auth/zod-validation.pipe.ts +16 -0
  112. package/templates/modules/auth/nextjs/app/dashboard/page.tsx +96 -96
  113. package/templates/modules/auth/nextjs/app/sign-in/page.tsx +35 -35
  114. package/templates/modules/auth/nextjs/app/sign-up/page.tsx +35 -35
  115. package/templates/modules/auth/nextjs/components/auth/sign-in-form.tsx +132 -132
  116. package/templates/modules/auth/nextjs/components/auth/sign-out-button.tsx +50 -50
  117. package/templates/modules/auth/nextjs/components/auth/sign-up-form.tsx +152 -152
  118. package/templates/modules/auth/nextjs/config.json +31 -31
  119. package/templates/modules/auth/nextjs/lib/auth-schema.ts +39 -39
  120. package/templates/modules/auth/nextjs/lib/auth.ts.hbs +37 -37
  121. package/templates/modules/auth/tanstack/src/lib/auth-functions.ts +4 -4
  122. package/templates/modules/auth/tanstack/src/routeTree.gen.ts +140 -140
  123. package/templates/modules/docker/.dockerignore +14 -14
  124. package/templates/modules/docker/Dockerfile.hbs +137 -133
  125. package/templates/modules/docker/config.json +19 -19
  126. package/templates/modules/docker/docker-compose.yml.hbs +9 -9
  127. package/templates/modules/drizzle/express/config.json +27 -27
  128. package/templates/modules/drizzle/express/drizzle.config.ts +13 -13
  129. package/templates/modules/drizzle/express/src/lib/db.ts +13 -13
  130. package/templates/modules/drizzle/express/src/lib/schema.ts +10 -10
  131. package/templates/modules/drizzle/nestjs/config.json +27 -0
  132. package/templates/modules/drizzle/nestjs/drizzle.config.ts +13 -0
  133. package/templates/modules/drizzle/nestjs/src/database/database.module.ts +30 -0
  134. package/templates/modules/drizzle/nestjs/src/database/schema.ts +10 -0
  135. package/templates/modules/drizzle/nextjs/config.json +29 -29
  136. package/templates/modules/drizzle/nextjs/lib/db.ts +13 -13
  137. package/templates/modules/drizzle/nextjs/lib/schema.ts.hbs +84 -84
  138. package/templates/modules/mongoose/express/config.json +16 -16
  139. package/templates/modules/mongoose/nestjs/config.json +16 -0
  140. package/templates/modules/mongoose/nestjs/src/users/user.schema.ts +21 -0
  141. package/templates/modules/mongoose/nextjs/config.json +16 -16
  142. package/templates/modules/mongoose/nextjs/lib/db.ts +36 -36
  143. package/templates/modules/mongoose/tanstack/config.json +17 -17
  144. package/templates/modules/mongoose/tanstack/src/lib/db.ts +37 -37
  145. package/templates/modules/prisma/express/config.json +28 -28
  146. package/templates/modules/prisma/express/prisma/schema.prisma +1 -1
  147. package/templates/modules/prisma/express/prisma.config.ts +12 -12
  148. package/templates/modules/prisma/express/src/lib/prisma.ts +24 -24
  149. package/templates/modules/prisma/nestjs/config.json +28 -0
  150. package/templates/modules/prisma/nestjs/prisma/schema.prisma +23 -0
  151. package/templates/modules/prisma/nestjs/prisma.config.ts +12 -0
  152. package/templates/modules/prisma/nestjs/src/prisma/prisma.module.ts +11 -0
  153. package/templates/modules/prisma/nestjs/src/prisma/prisma.service.ts +17 -0
  154. package/templates/modules/prisma/nextjs/config.json +29 -29
  155. package/templates/modules/prisma/nextjs/prisma/schema.prisma.hbs +91 -91
  156. package/templates/modules/prisma/tanstack/config.json +5 -5
  157. package/dist/intro.d.ts +0 -2
  158. package/dist/intro.d.ts.map +0 -1
  159. package/dist/intro.js +0 -27
  160. package/dist/intro.js.map +0 -1
  161. package/templates/backend/express/.eslintrc.js +0 -24
@@ -1,140 +1,140 @@
1
- /* eslint-disable */
2
-
3
- // @ts-nocheck
4
-
5
- // noinspection JSUnusedGlobalSymbols
6
-
7
- // This file was automatically generated by TanStack Router.
8
- // You should NOT make any changes in this file as it will be overwritten.
9
- // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
10
-
11
- import { Route as rootRouteImport } from './routes/__root'
12
- import { Route as IndexRouteImport } from './routes/index'
13
- import { Route as DashboardRouteImport } from './routes/dashboard'
14
- import { Route as SignInRouteImport } from './routes/sign-in'
15
- import { Route as SignUpRouteImport } from './routes/sign-up'
16
- import { Route as ApiAuthSplatRouteImport } from './routes/api/auth/$'
17
-
18
- const IndexRoute = IndexRouteImport.update({
19
- id: '/',
20
- path: '/',
21
- getParentRoute: () => rootRouteImport,
22
- } as any)
23
- const DashboardRoute = DashboardRouteImport.update({
24
- id: '/dashboard',
25
- path: '/dashboard',
26
- getParentRoute: () => rootRouteImport,
27
- } as any)
28
- const SignInRoute = SignInRouteImport.update({
29
- id: '/sign-in',
30
- path: '/sign-in',
31
- getParentRoute: () => rootRouteImport,
32
- } as any)
33
- const SignUpRoute = SignUpRouteImport.update({
34
- id: '/sign-up',
35
- path: '/sign-up',
36
- getParentRoute: () => rootRouteImport,
37
- } as any)
38
- const ApiAuthSplatRoute = ApiAuthSplatRouteImport.update({
39
- id: '/api/auth/$',
40
- path: '/api/auth/$',
41
- getParentRoute: () => rootRouteImport,
42
- } as any)
43
-
44
- export interface FileRoutesByFullPath {
45
- '/': typeof IndexRoute
46
- '/dashboard': typeof DashboardRoute
47
- '/sign-in': typeof SignInRoute
48
- '/sign-up': typeof SignUpRoute
49
- '/api/auth/$': typeof ApiAuthSplatRoute
50
- }
51
- export interface FileRoutesByTo {
52
- '/': typeof IndexRoute
53
- '/dashboard': typeof DashboardRoute
54
- '/sign-in': typeof SignInRoute
55
- '/sign-up': typeof SignUpRoute
56
- '/api/auth/$': typeof ApiAuthSplatRoute
57
- }
58
- export interface FileRoutesById {
59
- __root__: typeof rootRouteImport
60
- '/': typeof IndexRoute
61
- '/dashboard': typeof DashboardRoute
62
- '/sign-in': typeof SignInRoute
63
- '/sign-up': typeof SignUpRoute
64
- '/api/auth/$': typeof ApiAuthSplatRoute
65
- }
66
- export interface FileRouteTypes {
67
- fileRoutesByFullPath: FileRoutesByFullPath
68
- fullPaths: '/' | '/dashboard' | '/sign-in' | '/sign-up' | '/api/auth/$'
69
- fileRoutesByTo: FileRoutesByTo
70
- to: '/' | '/dashboard' | '/sign-in' | '/sign-up' | '/api/auth/$'
71
- id: '__root__' | '/' | '/dashboard' | '/sign-in' | '/sign-up' | '/api/auth/$'
72
- fileRoutesById: FileRoutesById
73
- }
74
- export interface RootRouteChildren {
75
- IndexRoute: typeof IndexRoute
76
- DashboardRoute: typeof DashboardRoute
77
- SignInRoute: typeof SignInRoute
78
- SignUpRoute: typeof SignUpRoute
79
- ApiAuthSplatRoute: typeof ApiAuthSplatRoute
80
- }
81
-
82
- declare module '@tanstack/react-router' {
83
- interface FileRoutesByPath {
84
- '/': {
85
- id: '/'
86
- path: '/'
87
- fullPath: '/'
88
- preLoaderRoute: typeof IndexRouteImport
89
- parentRoute: typeof rootRouteImport
90
- }
91
- '/dashboard': {
92
- id: '/dashboard'
93
- path: '/dashboard'
94
- fullPath: '/dashboard'
95
- preLoaderRoute: typeof DashboardRouteImport
96
- parentRoute: typeof rootRouteImport
97
- }
98
- '/sign-in': {
99
- id: '/sign-in'
100
- path: '/sign-in'
101
- fullPath: '/sign-in'
102
- preLoaderRoute: typeof SignInRouteImport
103
- parentRoute: typeof rootRouteImport
104
- }
105
- '/sign-up': {
106
- id: '/sign-up'
107
- path: '/sign-up'
108
- fullPath: '/sign-up'
109
- preLoaderRoute: typeof SignUpRouteImport
110
- parentRoute: typeof rootRouteImport
111
- }
112
- '/api/auth/$': {
113
- id: '/api/auth/$'
114
- path: '/api/auth/$'
115
- fullPath: '/api/auth/$'
116
- preLoaderRoute: typeof ApiAuthSplatRouteImport
117
- parentRoute: typeof rootRouteImport
118
- }
119
- }
120
- }
121
-
122
- const rootRouteChildren: RootRouteChildren = {
123
- IndexRoute: IndexRoute,
124
- DashboardRoute: DashboardRoute,
125
- SignInRoute: SignInRoute,
126
- SignUpRoute: SignUpRoute,
127
- ApiAuthSplatRoute: ApiAuthSplatRoute,
128
- }
129
- export const routeTree = rootRouteImport
130
- ._addFileChildren(rootRouteChildren)
131
- ._addFileTypes<FileRouteTypes>()
132
-
133
- import type { getRouter } from './router.tsx'
134
- import type { createStart } from '@tanstack/react-start'
135
- declare module '@tanstack/react-start' {
136
- interface Register {
137
- ssr: true
138
- router: Awaited<ReturnType<typeof getRouter>>
139
- }
140
- }
1
+ /* eslint-disable */
2
+
3
+ // @ts-nocheck
4
+
5
+ // noinspection JSUnusedGlobalSymbols
6
+
7
+ // This file was automatically generated by TanStack Router.
8
+ // You should NOT make any changes in this file as it will be overwritten.
9
+ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
10
+
11
+ import { Route as rootRouteImport } from './routes/__root'
12
+ import { Route as IndexRouteImport } from './routes/index'
13
+ import { Route as DashboardRouteImport } from './routes/dashboard'
14
+ import { Route as SignInRouteImport } from './routes/sign-in'
15
+ import { Route as SignUpRouteImport } from './routes/sign-up'
16
+ import { Route as ApiAuthSplatRouteImport } from './routes/api/auth/$'
17
+
18
+ const IndexRoute = IndexRouteImport.update({
19
+ id: '/',
20
+ path: '/',
21
+ getParentRoute: () => rootRouteImport,
22
+ } as any)
23
+ const DashboardRoute = DashboardRouteImport.update({
24
+ id: '/dashboard',
25
+ path: '/dashboard',
26
+ getParentRoute: () => rootRouteImport,
27
+ } as any)
28
+ const SignInRoute = SignInRouteImport.update({
29
+ id: '/sign-in',
30
+ path: '/sign-in',
31
+ getParentRoute: () => rootRouteImport,
32
+ } as any)
33
+ const SignUpRoute = SignUpRouteImport.update({
34
+ id: '/sign-up',
35
+ path: '/sign-up',
36
+ getParentRoute: () => rootRouteImport,
37
+ } as any)
38
+ const ApiAuthSplatRoute = ApiAuthSplatRouteImport.update({
39
+ id: '/api/auth/$',
40
+ path: '/api/auth/$',
41
+ getParentRoute: () => rootRouteImport,
42
+ } as any)
43
+
44
+ export interface FileRoutesByFullPath {
45
+ '/': typeof IndexRoute
46
+ '/dashboard': typeof DashboardRoute
47
+ '/sign-in': typeof SignInRoute
48
+ '/sign-up': typeof SignUpRoute
49
+ '/api/auth/$': typeof ApiAuthSplatRoute
50
+ }
51
+ export interface FileRoutesByTo {
52
+ '/': typeof IndexRoute
53
+ '/dashboard': typeof DashboardRoute
54
+ '/sign-in': typeof SignInRoute
55
+ '/sign-up': typeof SignUpRoute
56
+ '/api/auth/$': typeof ApiAuthSplatRoute
57
+ }
58
+ export interface FileRoutesById {
59
+ __root__: typeof rootRouteImport
60
+ '/': typeof IndexRoute
61
+ '/dashboard': typeof DashboardRoute
62
+ '/sign-in': typeof SignInRoute
63
+ '/sign-up': typeof SignUpRoute
64
+ '/api/auth/$': typeof ApiAuthSplatRoute
65
+ }
66
+ export interface FileRouteTypes {
67
+ fileRoutesByFullPath: FileRoutesByFullPath
68
+ fullPaths: '/' | '/dashboard' | '/sign-in' | '/sign-up' | '/api/auth/$'
69
+ fileRoutesByTo: FileRoutesByTo
70
+ to: '/' | '/dashboard' | '/sign-in' | '/sign-up' | '/api/auth/$'
71
+ id: '__root__' | '/' | '/dashboard' | '/sign-in' | '/sign-up' | '/api/auth/$'
72
+ fileRoutesById: FileRoutesById
73
+ }
74
+ export interface RootRouteChildren {
75
+ IndexRoute: typeof IndexRoute
76
+ DashboardRoute: typeof DashboardRoute
77
+ SignInRoute: typeof SignInRoute
78
+ SignUpRoute: typeof SignUpRoute
79
+ ApiAuthSplatRoute: typeof ApiAuthSplatRoute
80
+ }
81
+
82
+ declare module '@tanstack/react-router' {
83
+ interface FileRoutesByPath {
84
+ '/': {
85
+ id: '/'
86
+ path: '/'
87
+ fullPath: '/'
88
+ preLoaderRoute: typeof IndexRouteImport
89
+ parentRoute: typeof rootRouteImport
90
+ }
91
+ '/dashboard': {
92
+ id: '/dashboard'
93
+ path: '/dashboard'
94
+ fullPath: '/dashboard'
95
+ preLoaderRoute: typeof DashboardRouteImport
96
+ parentRoute: typeof rootRouteImport
97
+ }
98
+ '/sign-in': {
99
+ id: '/sign-in'
100
+ path: '/sign-in'
101
+ fullPath: '/sign-in'
102
+ preLoaderRoute: typeof SignInRouteImport
103
+ parentRoute: typeof rootRouteImport
104
+ }
105
+ '/sign-up': {
106
+ id: '/sign-up'
107
+ path: '/sign-up'
108
+ fullPath: '/sign-up'
109
+ preLoaderRoute: typeof SignUpRouteImport
110
+ parentRoute: typeof rootRouteImport
111
+ }
112
+ '/api/auth/$': {
113
+ id: '/api/auth/$'
114
+ path: '/api/auth/$'
115
+ fullPath: '/api/auth/$'
116
+ preLoaderRoute: typeof ApiAuthSplatRouteImport
117
+ parentRoute: typeof rootRouteImport
118
+ }
119
+ }
120
+ }
121
+
122
+ const rootRouteChildren: RootRouteChildren = {
123
+ IndexRoute: IndexRoute,
124
+ DashboardRoute: DashboardRoute,
125
+ SignInRoute: SignInRoute,
126
+ SignUpRoute: SignUpRoute,
127
+ ApiAuthSplatRoute: ApiAuthSplatRoute,
128
+ }
129
+ export const routeTree = rootRouteImport
130
+ ._addFileChildren(rootRouteChildren)
131
+ ._addFileTypes<FileRouteTypes>()
132
+
133
+ import type { getRouter } from './router.tsx'
134
+ import type { createStart } from '@tanstack/react-start'
135
+ declare module '@tanstack/react-start' {
136
+ interface Register {
137
+ ssr: true
138
+ router: Awaited<ReturnType<typeof getRouter>>
139
+ }
140
+ }
@@ -1,14 +1,14 @@
1
- node_modules
2
- npm-debug.log
3
- .env*
4
- .git
5
- .gitignore
6
- README.md
7
- .vscode
8
- .idea
9
- dist
10
- coverage
11
- .DS_Store
12
- *.log
13
-
14
- .next
1
+ node_modules
2
+ npm-debug.log
3
+ .env*
4
+ .git
5
+ .gitignore
6
+ README.md
7
+ .vscode
8
+ .idea
9
+ dist
10
+ coverage
11
+ .DS_Store
12
+ *.log
13
+
14
+ .next
@@ -1,134 +1,138 @@
1
- {{#if (eq framework 'nextjs')}}
2
- # Base stage
3
- FROM node:24-alpine AS base
4
- WORKDIR /app
5
- RUN apk add --no-cache libc6-compat
6
-
7
- # Dependencies stage
8
- FROM base AS deps
9
- COPY package*.json ./
10
- RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi
11
-
12
- # Build stage
13
- FROM base AS builder
14
- COPY --from=deps /app/node_modules ./node_modules
15
- COPY . .
16
- {{#if useAuth}}
17
- # next build loads the auth route, which initializes Better Auth. The build gets
18
- # a placeholder secret for this command only; the real one is supplied at runtime.
19
- {{/if}}
20
- {{#if (eq database 'prisma')}}
21
- RUN {{#if useAuth}}BETTER_AUTH_SECRET="build-only-placeholder-secret-not-used-at-runtime" {{/if}}DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres" npm run build
22
- {{else if (eq database 'mongoose')}}
23
- RUN {{#if useAuth}}BETTER_AUTH_SECRET="build-only-placeholder-secret-not-used-at-runtime" {{/if}}MONGODB_URI="mongodb://localhost:27017/build" npm run build
24
- {{else}}
25
- RUN {{#if useAuth}}BETTER_AUTH_SECRET="build-only-placeholder-secret-not-used-at-runtime" {{/if}}npm run build
26
- {{/if}}
27
-
28
- # Production stage
29
- FROM node:24-alpine AS runner
30
- WORKDIR /app
31
- ENV NODE_ENV=production
32
-
33
- RUN addgroup --system --gid 1001 nodejs && \
34
- adduser --system --uid 1001 nextjs
35
-
36
- COPY --from=builder /app/public ./public
37
- COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
38
- COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
39
-
40
- USER nextjs
41
- EXPOSE {{port}}
42
- ENV PORT={{port}} HOSTNAME=0.0.0.0
43
-
44
- CMD ["node", "server.js"]
45
-
46
- {{else if (eq framework 'tanstack')}}
47
- # Build stage
48
- FROM node:24-alpine AS builder
49
- WORKDIR /app
50
-
51
- COPY package*.json ./
52
- RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi
53
-
54
- COPY . .
55
-
56
- # Only build if package.json has a build script
57
- {{#if (eq database 'prisma')}}
58
- RUN DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres" npm run build
59
- {{else if (eq database 'mongoose')}}
60
- RUN MONGODB_URI="mongodb://localhost:27017/build" npm run build
61
- {{else}}
62
- RUN npm run build
63
- {{/if}}
64
-
65
- # Production stage
66
- FROM node:24-alpine
67
- WORKDIR /app
68
- ENV NODE_ENV=production
69
-
70
- # Create non-root user for security
71
- RUN addgroup --system --gid 1001 nodejs && \
72
- adduser --system --uid 1001 tanstackuser
73
-
74
- COPY package*.json ./
75
- # Clear the npm cache in the same layer so it does not ship in the image
76
- RUN if [ -f package-lock.json ]; then npm ci --omit=dev; else npm install --omit=dev; fi \
77
- && npm cache clean --force
78
-
79
- # Copy built output (dist/server/server.js + dist/client)
80
- COPY --from=builder --chown=tanstackuser:nodejs /app/dist ./dist
81
-
82
- # Include the Prisma client generated during the build stage
83
- {{#if (eq database 'prisma')}}
84
- COPY --from=builder --chown=tanstackuser:nodejs /app/generated ./generated
85
- {{/if}}
86
-
87
- USER tanstackuser
88
- EXPOSE {{port}}
89
- ENV PORT={{port}}
90
-
91
- CMD ["node_modules/.bin/srvx", "--prod", "-s", "../client", "dist/server/server.js"]
92
-
93
- {{else}}
94
- # Build stage
95
- FROM node:24-alpine AS builder
96
- WORKDIR /app
97
-
98
- COPY package*.json ./
99
- RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi
100
-
101
- COPY . .
102
-
103
- # Only build if package.json has a build script
104
- {{#if (eq database 'prisma')}}
105
- RUN DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres" npm run build
106
- {{else if (eq database 'mongoose')}}
107
- RUN MONGODB_URI="mongodb://localhost:27017/build" npm run build
108
- {{else}}
109
- RUN npm run build
110
- {{/if}}
111
-
112
- # Production stage
113
- FROM node:24-alpine
114
- WORKDIR /app
115
- ENV NODE_ENV=production
116
-
117
- # Create non-root user for security
118
- RUN addgroup --system --gid 1001 nodejs && \
119
- adduser --system --uid 1001 expressuser
120
-
121
- COPY package*.json ./
122
- # Clear the npm cache in the same layer so it does not ship in the image
123
- RUN if [ -f package-lock.json ]; then npm ci --omit=dev; else npm install --omit=dev; fi \
124
- && npm cache clean --force
125
-
126
- # Copy built files (if TypeScript) or source files (if JavaScript)
127
- COPY --from=builder --chown=expressuser:nodejs /app/dist ./dist
128
-
129
- USER expressuser
130
- EXPOSE {{port}}
131
- ENV PORT={{port}}
132
-
133
- CMD ["node", "dist/index.js"]
1
+ {{#if (eq framework 'nextjs')}}
2
+ # Base stage
3
+ FROM node:24-alpine AS base
4
+ WORKDIR /app
5
+ RUN apk add --no-cache libc6-compat
6
+
7
+ # Dependencies stage
8
+ FROM base AS deps
9
+ COPY package*.json ./
10
+ RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi
11
+
12
+ # Build stage
13
+ FROM base AS builder
14
+ COPY --from=deps /app/node_modules ./node_modules
15
+ COPY . .
16
+ {{#if useAuth}}
17
+ # next build loads the auth route, which initializes Better Auth. The build gets
18
+ # a placeholder secret for this command only; the real one is supplied at runtime.
19
+ {{/if}}
20
+ {{#if (eq database 'prisma')}}
21
+ RUN {{#if useAuth}}BETTER_AUTH_SECRET="build-only-placeholder-secret-not-used-at-runtime" {{/if}}DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres" npm run build
22
+ {{else if (eq database 'mongoose')}}
23
+ RUN {{#if useAuth}}BETTER_AUTH_SECRET="build-only-placeholder-secret-not-used-at-runtime" {{/if}}MONGODB_URI="mongodb://localhost:27017/build" npm run build
24
+ {{else}}
25
+ RUN {{#if useAuth}}BETTER_AUTH_SECRET="build-only-placeholder-secret-not-used-at-runtime" {{/if}}npm run build
26
+ {{/if}}
27
+
28
+ # Production stage
29
+ FROM node:24-alpine AS runner
30
+ WORKDIR /app
31
+ ENV NODE_ENV=production
32
+
33
+ RUN addgroup --system --gid 1001 nodejs && \
34
+ adduser --system --uid 1001 nextjs
35
+
36
+ COPY --from=builder /app/public ./public
37
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
38
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
39
+
40
+ USER nextjs
41
+ EXPOSE {{port}}
42
+ ENV PORT={{port}} HOSTNAME=0.0.0.0
43
+
44
+ CMD ["node", "server.js"]
45
+
46
+ {{else if (eq framework 'tanstack')}}
47
+ # Build stage
48
+ FROM node:24-alpine AS builder
49
+ WORKDIR /app
50
+
51
+ COPY package*.json ./
52
+ RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi
53
+
54
+ COPY . .
55
+
56
+ # Only build if package.json has a build script
57
+ {{#if (eq database 'prisma')}}
58
+ RUN DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres" npm run build
59
+ {{else if (eq database 'mongoose')}}
60
+ RUN MONGODB_URI="mongodb://localhost:27017/build" npm run build
61
+ {{else}}
62
+ RUN npm run build
63
+ {{/if}}
64
+
65
+ # Production stage
66
+ FROM node:24-alpine
67
+ WORKDIR /app
68
+ ENV NODE_ENV=production
69
+
70
+ # Create non-root user for security
71
+ RUN addgroup --system --gid 1001 nodejs && \
72
+ adduser --system --uid 1001 tanstackuser
73
+
74
+ COPY package*.json ./
75
+ # Clear the npm cache in the same layer so it does not ship in the image
76
+ RUN if [ -f package-lock.json ]; then npm ci --omit=dev; else npm install --omit=dev; fi \
77
+ && npm cache clean --force
78
+
79
+ # Copy built output (dist/server/server.js + dist/client)
80
+ COPY --from=builder --chown=tanstackuser:nodejs /app/dist ./dist
81
+
82
+ # Include the Prisma client generated during the build stage
83
+ {{#if (eq database 'prisma')}}
84
+ COPY --from=builder --chown=tanstackuser:nodejs /app/generated ./generated
85
+ {{/if}}
86
+
87
+ USER tanstackuser
88
+ EXPOSE {{port}}
89
+ ENV PORT={{port}}
90
+
91
+ CMD ["node_modules/.bin/srvx", "--prod", "-s", "../client", "dist/server/server.js"]
92
+
93
+ {{else}}
94
+ # Build stage
95
+ FROM node:24-alpine AS builder
96
+ WORKDIR /app
97
+
98
+ COPY package*.json ./
99
+ RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi
100
+
101
+ COPY . .
102
+
103
+ # Only build if package.json has a build script
104
+ {{#if (eq database 'prisma')}}
105
+ RUN DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres" npm run build
106
+ {{else if (eq database 'mongoose')}}
107
+ RUN MONGODB_URI="mongodb://localhost:27017/build" npm run build
108
+ {{else}}
109
+ RUN npm run build
110
+ {{/if}}
111
+
112
+ # Production stage
113
+ FROM node:24-alpine
114
+ WORKDIR /app
115
+ ENV NODE_ENV=production
116
+
117
+ # Create non-root user for security
118
+ RUN addgroup --system --gid 1001 nodejs && \
119
+ adduser --system --uid 1001 appuser
120
+
121
+ COPY package*.json ./
122
+ # Clear the npm cache in the same layer so it does not ship in the image
123
+ RUN if [ -f package-lock.json ]; then npm ci --omit=dev; else npm install --omit=dev; fi \
124
+ && npm cache clean --force
125
+
126
+ # Copy built files (if TypeScript) or source files (if JavaScript)
127
+ COPY --from=builder --chown=appuser:nodejs /app/dist ./dist
128
+
129
+ USER appuser
130
+ EXPOSE {{port}}
131
+ ENV PORT={{port}}
132
+
133
+ {{#if (eq framework 'nestjs')}}
134
+ CMD ["node", "dist/main.js"]
135
+ {{else}}
136
+ CMD ["node", "dist/index.js"]
137
+ {{/if}}
134
138
  {{/if}}
@@ -1,19 +1,19 @@
1
- {
2
- "id": "docker",
3
- "name": "Docker",
4
- "description": "Docker containerization with multi-stage build and docker-compose",
5
- "type": "feature",
6
- "dependencies": {},
7
- "devDependencies": {},
8
- "scripts": {
9
- "docker:build": "docker build -t {{projectName}} .",
10
- "docker:up": "docker compose up -d --build",
11
- "docker:down": "docker compose down",
12
- "docker:logs": "docker compose logs -f"
13
- },
14
- "envVars": {},
15
- "templateFiles": [
16
- "docker-compose.yml.hbs",
17
- "Dockerfile.hbs"
18
- ]
19
- }
1
+ {
2
+ "id": "docker",
3
+ "name": "Docker",
4
+ "description": "Docker containerization with multi-stage build and docker-compose",
5
+ "type": "feature",
6
+ "dependencies": {},
7
+ "devDependencies": {},
8
+ "scripts": {
9
+ "docker:build": "docker build -t {{projectName}} .",
10
+ "docker:up": "docker compose up -d --build",
11
+ "docker:down": "docker compose down",
12
+ "docker:logs": "docker compose logs -f"
13
+ },
14
+ "envVars": {},
15
+ "templateFiles": [
16
+ "docker-compose.yml.hbs",
17
+ "Dockerfile.hbs"
18
+ ]
19
+ }
@@ -1,10 +1,10 @@
1
- services:
2
- {{projectName}}:
3
- build: .
4
- ports:
5
- - "{{port}}:{{port}}"
6
- env_file:
7
- - .env
8
- environment:
9
- - NODE_ENV=production
1
+ services:
2
+ {{projectName}}:
3
+ build: .
4
+ ports:
5
+ - "{{port}}:{{port}}"
6
+ env_file:
7
+ - .env
8
+ environment:
9
+ - NODE_ENV=production
10
10
  restart: unless-stopped