stackkit-cli 0.4.2 → 0.4.3

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 (133) hide show
  1. package/README.md +17 -10
  2. package/bin/stackkit.js +1 -1
  3. package/dist/commands/add.js +26 -24
  4. package/dist/commands/init.d.ts +1 -1
  5. package/dist/commands/init.js +34 -29
  6. package/dist/commands/list.js +12 -12
  7. package/dist/index.js +25 -23
  8. package/dist/types/index.d.ts +14 -14
  9. package/dist/utils/code-inject.d.ts +1 -1
  10. package/dist/utils/code-inject.js +6 -6
  11. package/dist/utils/detect.d.ts +1 -1
  12. package/dist/utils/detect.js +48 -44
  13. package/dist/utils/env-editor.js +20 -20
  14. package/dist/utils/files.js +4 -4
  15. package/dist/utils/json-editor.d.ts +3 -3
  16. package/dist/utils/json-editor.js +10 -14
  17. package/dist/utils/logger.d.ts +1 -1
  18. package/dist/utils/logger.js +8 -8
  19. package/dist/utils/package-manager.d.ts +2 -2
  20. package/dist/utils/package-manager.js +33 -26
  21. package/modules/auth/better-auth-express/adapters/mongoose-mongodb.ts +13 -0
  22. package/modules/auth/better-auth-express/adapters/prisma-mongodb.ts +15 -0
  23. package/modules/auth/better-auth-express/adapters/prisma-postgresql.ts +15 -0
  24. package/modules/auth/better-auth-express/files/lib/auth.ts +1 -1
  25. package/modules/auth/better-auth-express/files/routes/auth.ts +3 -3
  26. package/modules/auth/better-auth-express/files/schemas/prisma-mongodb-schema.prisma +72 -0
  27. package/modules/auth/better-auth-express/files/schemas/prisma-postgresql-schema.prisma +72 -0
  28. package/modules/auth/better-auth-express/module.json +26 -3
  29. package/modules/auth/better-auth-nextjs/adapters/mongoose-mongodb.ts +24 -0
  30. package/modules/auth/better-auth-nextjs/adapters/prisma-mongodb.ts +26 -0
  31. package/modules/auth/better-auth-nextjs/adapters/prisma-postgresql.ts +26 -0
  32. package/modules/auth/better-auth-nextjs/files/api/auth/[...all]/route.ts +2 -3
  33. package/modules/auth/better-auth-nextjs/files/lib/auth.ts +4 -4
  34. package/modules/auth/better-auth-nextjs/files/schemas/prisma-mongodb-schema.prisma +72 -0
  35. package/modules/auth/better-auth-nextjs/files/schemas/prisma-postgresql-schema.prisma +72 -0
  36. package/modules/auth/better-auth-nextjs/module.json +26 -5
  37. package/modules/auth/better-auth-react/files/lib/auth-client.ts +2 -2
  38. package/modules/auth/better-auth-react/module.json +7 -5
  39. package/modules/auth/clerk-express/files/lib/auth.ts +1 -1
  40. package/modules/auth/clerk-express/module.json +22 -8
  41. package/modules/auth/clerk-nextjs/files/lib/auth-provider.tsx +1 -1
  42. package/modules/auth/clerk-nextjs/files/middleware.ts +3 -3
  43. package/modules/auth/clerk-nextjs/module.json +50 -14
  44. package/modules/auth/clerk-react/files/lib/auth-provider.tsx +2 -2
  45. package/modules/auth/clerk-react/module.json +16 -7
  46. package/modules/database/mongoose-mongodb/files/lib/db.ts +3 -3
  47. package/modules/database/mongoose-mongodb/module.json +43 -6
  48. package/modules/database/prisma-mongodb/files/lib/db.ts +2 -2
  49. package/modules/database/prisma-mongodb/files/prisma/schema.prisma +1 -1
  50. package/modules/database/prisma-mongodb/module.json +28 -4
  51. package/modules/database/prisma-postgresql/files/lib/db.ts +2 -2
  52. package/modules/database/prisma-postgresql/files/prisma/schema.prisma +1 -1
  53. package/modules/database/prisma-postgresql/module.json +28 -4
  54. package/package.json +1 -1
  55. package/templates/express/.env.example +11 -0
  56. package/templates/express/eslint.config.cjs +42 -0
  57. package/templates/express/package.json +39 -0
  58. package/templates/express/src/app.ts +71 -0
  59. package/templates/express/src/config/env.ts +23 -0
  60. package/templates/express/src/middlewares/error.middleware.ts +18 -0
  61. package/templates/{bases/express-base → express}/src/server.ts +2 -2
  62. package/templates/express/template.json +44 -0
  63. package/templates/express/tsconfig.json +31 -0
  64. package/templates/{bases/nextjs-base → nextjs}/app/layout.tsx +1 -5
  65. package/templates/nextjs/app/page.tsx +57 -0
  66. package/templates/{bases/nextjs-base → nextjs}/package.json +2 -1
  67. package/templates/{bases/nextjs-base → nextjs}/template.json +13 -1
  68. package/templates/react-vite/.env.example +2 -0
  69. package/templates/react-vite/README.md +85 -0
  70. package/templates/react-vite/eslint.config.js +23 -0
  71. package/templates/{bases/react-vite-base → react-vite}/index.html +1 -0
  72. package/templates/{bases/react-vite-base → react-vite}/package.json +16 -2
  73. package/templates/react-vite/src/api/client.ts +47 -0
  74. package/templates/react-vite/src/api/services/user.service.ts +18 -0
  75. package/templates/react-vite/src/components/ErrorBoundary.tsx +51 -0
  76. package/templates/react-vite/src/components/Layout.tsx +13 -0
  77. package/templates/react-vite/src/components/Loading.tsx +8 -0
  78. package/templates/react-vite/src/components/SEO.tsx +49 -0
  79. package/templates/react-vite/src/config/constants.ts +5 -0
  80. package/templates/react-vite/src/hooks/index.ts +64 -0
  81. package/templates/react-vite/src/index.css +1 -0
  82. package/templates/react-vite/src/lib/queryClient.ts +12 -0
  83. package/templates/react-vite/src/main.tsx +22 -0
  84. package/templates/react-vite/src/pages/About.tsx +78 -0
  85. package/templates/react-vite/src/pages/Home.tsx +49 -0
  86. package/templates/react-vite/src/pages/NotFound.tsx +24 -0
  87. package/templates/react-vite/src/pages/UserProfile.tsx +40 -0
  88. package/templates/react-vite/src/router.tsx +33 -0
  89. package/templates/react-vite/src/types/api.d.ts +20 -0
  90. package/templates/react-vite/src/types/user.d.ts +6 -0
  91. package/templates/react-vite/src/utils/helpers.ts +51 -0
  92. package/templates/react-vite/src/utils/storage.ts +35 -0
  93. package/templates/react-vite/src/vite-env.d.ts +11 -0
  94. package/templates/react-vite/template.json +46 -0
  95. package/templates/react-vite/tsconfig.json +4 -0
  96. package/templates/react-vite/vite.config.ts +13 -0
  97. package/modules/database/drizzle-postgresql/files/drizzle.config.ts +0 -10
  98. package/modules/database/drizzle-postgresql/files/lib/db.ts +0 -7
  99. package/modules/database/drizzle-postgresql/files/lib/schema.ts +0 -8
  100. package/modules/database/drizzle-postgresql/module.json +0 -35
  101. package/templates/bases/express-base/.env.example +0 -2
  102. package/templates/bases/express-base/package.json +0 -23
  103. package/templates/bases/express-base/src/app.ts +0 -34
  104. package/templates/bases/express-base/src/config/env.ts +0 -14
  105. package/templates/bases/express-base/src/middlewares/error.middleware.ts +0 -12
  106. package/templates/bases/express-base/template.json +0 -7
  107. package/templates/bases/express-base/tsconfig.json +0 -14
  108. package/templates/bases/nextjs-base/app/page.tsx +0 -65
  109. package/templates/bases/react-vite-base/README.md +0 -73
  110. package/templates/bases/react-vite-base/eslint.config.js +0 -23
  111. package/templates/bases/react-vite-base/src/App.css +0 -42
  112. package/templates/bases/react-vite-base/src/App.tsx +0 -35
  113. package/templates/bases/react-vite-base/src/index.css +0 -68
  114. package/templates/bases/react-vite-base/src/main.tsx +0 -10
  115. package/templates/bases/react-vite-base/template.json +0 -19
  116. package/templates/bases/react-vite-base/tsconfig.json +0 -7
  117. package/templates/bases/react-vite-base/vite.config.ts +0 -7
  118. /package/templates/{bases/nextjs-base → nextjs}/README.md +0 -0
  119. /package/templates/{bases/nextjs-base → nextjs}/app/favicon.ico +0 -0
  120. /package/templates/{bases/nextjs-base → nextjs}/app/globals.css +0 -0
  121. /package/templates/{bases/nextjs-base → nextjs}/eslint.config.mjs +0 -0
  122. /package/templates/{bases/nextjs-base → nextjs}/next.config.ts +0 -0
  123. /package/templates/{bases/nextjs-base → nextjs}/postcss.config.mjs +0 -0
  124. /package/templates/{bases/nextjs-base → nextjs}/public/file.svg +0 -0
  125. /package/templates/{bases/nextjs-base → nextjs}/public/globe.svg +0 -0
  126. /package/templates/{bases/nextjs-base → nextjs}/public/next.svg +0 -0
  127. /package/templates/{bases/nextjs-base → nextjs}/public/vercel.svg +0 -0
  128. /package/templates/{bases/nextjs-base → nextjs}/public/window.svg +0 -0
  129. /package/templates/{bases/nextjs-base → nextjs}/tsconfig.json +0 -0
  130. /package/templates/{bases/react-vite-base → react-vite}/public/vite.svg +0 -0
  131. /package/templates/{bases/react-vite-base → react-vite}/src/assets/react.svg +0 -0
  132. /package/templates/{bases/react-vite-base → react-vite}/tsconfig.app.json +0 -0
  133. /package/templates/{bases/react-vite-base → react-vite}/tsconfig.node.json +0 -0
@@ -1,18 +1,55 @@
1
1
  {
2
2
  "name": "mongoose-mongodb",
3
3
  "displayName": "Mongoose + MongoDB",
4
- "description": "Mongoose ODM for MongoDB",
4
+ "description": "Mongoose ODM for MongoDB database",
5
5
  "category": "database",
6
+ "provider": "mongoose",
7
+ "database": "mongodb",
8
+ "supportedFrameworks": ["nextjs", "express"],
6
9
  "dependencies": {
7
10
  "mongoose": "^8.8.4"
8
11
  },
9
- "env": {
10
- "MONGODB_URI": "mongodb://localhost:27017/myapp"
12
+ "devDependencies": {},
13
+ "envVars": [
14
+ {
15
+ "key": "MONGODB_URI",
16
+ "value": "mongodb://localhost:27017/myapp",
17
+ "description": "MongoDB connection string",
18
+ "required": true
19
+ }
20
+ ],
21
+ "frameworkPatches": {
22
+ "express": {
23
+ "tsconfig.json": {
24
+ "merge": {
25
+ "compilerOptions": {
26
+ "paths": {
27
+ "@/*": ["./src/*"],
28
+ "@/models/*": ["./src/models/*"]
29
+ }
30
+ },
31
+ "include": ["src/**/*", "src/models/**/*"]
32
+ }
33
+ }
34
+ },
35
+ "nextjs": {
36
+ "tsconfig.json": {
37
+ "merge": {
38
+ "compilerOptions": {
39
+ "paths": {
40
+ "@/models/*": ["./models/*"]
41
+ }
42
+ }
43
+ }
44
+ }
45
+ }
11
46
  },
12
- "files": [
47
+ "patches": [
13
48
  {
14
- "source": "files/lib/db.ts",
15
- "destination": "lib/db.ts"
49
+ "type": "create-file",
50
+ "description": "Create MongoDB connection with Mongoose",
51
+ "source": "lib/db.ts",
52
+ "destination": "{{lib}}/db.ts"
16
53
  }
17
54
  ]
18
55
  }
@@ -1,4 +1,4 @@
1
- import { PrismaClient } from '@prisma/client';
1
+ import { PrismaClient } from "@prisma/client";
2
2
 
3
3
  const globalForPrisma = globalThis as unknown as {
4
4
  prisma: PrismaClient | undefined;
@@ -6,4 +6,4 @@ const globalForPrisma = globalThis as unknown as {
6
6
 
7
7
  export const db = globalForPrisma.prisma ?? new PrismaClient();
8
8
 
9
- if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = db;
9
+ if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db;
@@ -7,7 +7,7 @@ datasource db {
7
7
  url = env("DATABASE_URL")
8
8
  }
9
9
 
10
- // Example model - customize as needed
10
+ // Example model - customize based on your auth provider
11
11
  model User {
12
12
  id String @id @default(auto()) @map("_id") @db.ObjectId
13
13
  email String @unique
@@ -1,8 +1,10 @@
1
1
  {
2
- "name": "database",
2
+ "name": "prisma-mongodb",
3
3
  "displayName": "Prisma + MongoDB",
4
- "description": "Add Prisma ORM with MongoDB database",
4
+ "description": "Prisma ORM with MongoDB database",
5
5
  "category": "database",
6
+ "provider": "prisma",
7
+ "database": "mongodb",
6
8
  "supportedFrameworks": ["nextjs", "express"],
7
9
  "dependencies": {
8
10
  "@prisma/client": "^6.1.0"
@@ -18,17 +20,39 @@
18
20
  "required": true
19
21
  }
20
22
  ],
23
+ "frameworkPatches": {
24
+ "express": {
25
+ "tsconfig.json": {
26
+ "merge": {
27
+ "compilerOptions": {
28
+ "paths": {
29
+ "@/*": ["./src/*"]
30
+ }
31
+ },
32
+ "include": ["src/**/*"],
33
+ "exclude": ["node_modules", "dist", "prisma/migrations"]
34
+ }
35
+ }
36
+ },
37
+ "nextjs": {
38
+ "tsconfig.json": {
39
+ "merge": {
40
+ "exclude": ["node_modules", ".next", "out", "prisma/migrations"]
41
+ }
42
+ }
43
+ }
44
+ },
21
45
  "patches": [
22
46
  {
23
47
  "type": "create-file",
24
48
  "description": "Create Prisma schema for MongoDB",
25
- "source": "prisma/schema.prisma",
49
+ "source": "files/prisma/schema.prisma",
26
50
  "destination": "prisma/schema.prisma"
27
51
  },
28
52
  {
29
53
  "type": "create-file",
30
54
  "description": "Create Prisma client singleton",
31
- "source": "lib/db.ts",
55
+ "source": "files/lib/db.ts",
32
56
  "destination": "{{lib}}/db.ts"
33
57
  }
34
58
  ],
@@ -1,4 +1,4 @@
1
- import { PrismaClient } from '@prisma/client';
1
+ import { PrismaClient } from "@prisma/client";
2
2
 
3
3
  const globalForPrisma = globalThis as unknown as {
4
4
  prisma: PrismaClient | undefined;
@@ -6,4 +6,4 @@ const globalForPrisma = globalThis as unknown as {
6
6
 
7
7
  export const db = globalForPrisma.prisma ?? new PrismaClient();
8
8
 
9
- if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = db;
9
+ if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db;
@@ -7,7 +7,7 @@ datasource db {
7
7
  url = env("DATABASE_URL")
8
8
  }
9
9
 
10
- // Example model - customize as needed
10
+ // Example model - customize based on your auth provider
11
11
  model User {
12
12
  id String @id @default(cuid())
13
13
  email String @unique
@@ -1,8 +1,10 @@
1
1
  {
2
- "name": "database",
2
+ "name": "prisma-postgresql",
3
3
  "displayName": "Prisma + PostgreSQL",
4
- "description": "Add Prisma ORM with PostgreSQL database",
4
+ "description": "Prisma ORM with PostgreSQL database",
5
5
  "category": "database",
6
+ "provider": "prisma",
7
+ "database": "postgresql",
6
8
  "supportedFrameworks": ["nextjs", "express"],
7
9
  "dependencies": {
8
10
  "@prisma/client": "^6.1.0"
@@ -18,17 +20,39 @@
18
20
  "required": true
19
21
  }
20
22
  ],
23
+ "frameworkPatches": {
24
+ "express": {
25
+ "tsconfig.json": {
26
+ "merge": {
27
+ "compilerOptions": {
28
+ "paths": {
29
+ "@/*": ["./src/*"]
30
+ }
31
+ },
32
+ "include": ["src/**/*"],
33
+ "exclude": ["node_modules", "dist", "prisma/migrations"]
34
+ }
35
+ }
36
+ },
37
+ "nextjs": {
38
+ "tsconfig.json": {
39
+ "merge": {
40
+ "exclude": ["node_modules", ".next", "out", "prisma/migrations"]
41
+ }
42
+ }
43
+ }
44
+ },
21
45
  "patches": [
22
46
  {
23
47
  "type": "create-file",
24
48
  "description": "Create Prisma schema",
25
- "source": "prisma/schema.prisma",
49
+ "source": "files/prisma/schema.prisma",
26
50
  "destination": "prisma/schema.prisma"
27
51
  },
28
52
  {
29
53
  "type": "create-file",
30
54
  "description": "Create Prisma client singleton",
31
- "source": "lib/db.ts",
55
+ "source": "files/lib/db.ts",
32
56
  "destination": "{{lib}}/db.ts"
33
57
  }
34
58
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stackkit-cli",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "CLI for StackKit - Production-ready project generator and module system",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -0,0 +1,11 @@
1
+ PORT=3000
2
+ NODE_ENV=development
3
+ APP_URL=http://localhost:3000
4
+ SITE_URL=http://localhost:5173
5
+
6
+ # Proxy (set to true if running behind a proxy/load-balancer)
7
+ TRUST_PROXY=false
8
+
9
+ # Rate limit
10
+ RATE_LIMIT_MAX=100
11
+ RATE_LIMIT_WINDOW_MS=900000
@@ -0,0 +1,42 @@
1
+ module.exports = [
2
+ // Global ignores
3
+ {
4
+ ignores: ['**/node_modules/**', '**/dist/**', '.env'],
5
+ },
6
+
7
+ // TypeScript files
8
+ {
9
+ files: ['**/*.ts', '**/*.tsx'],
10
+ languageOptions: {
11
+ parser: require('@typescript-eslint/parser'),
12
+ parserOptions: {
13
+ project: './tsconfig.json',
14
+ ecmaVersion: 'latest',
15
+ sourceType: 'module',
16
+ },
17
+ },
18
+ plugins: {
19
+ '@typescript-eslint': require('@typescript-eslint/eslint-plugin'),
20
+ },
21
+ rules: {
22
+ 'prefer-const': 'error',
23
+ 'no-console': 'off',
24
+ eqeqeq: ['error', 'always'],
25
+ curly: ['error', 'multi-line'],
26
+ 'no-implicit-coercion': ['warn', { allow: ['!!'] }],
27
+ '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^(?:_|next)$' }],
28
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
29
+ '@typescript-eslint/no-explicit-any': 'off',
30
+ },
31
+ },
32
+
33
+ // JavaScript files
34
+ {
35
+ files: ['**/*.js'],
36
+ languageOptions: {
37
+ ecmaVersion: 'latest',
38
+ sourceType: 'module',
39
+ },
40
+ rules: {},
41
+ },
42
+ ];
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "my-app",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "tsx watch src/server.ts",
8
+ "clean": "rimraf dist",
9
+ "prebuild": "npm run clean",
10
+ "build": "tsc",
11
+ "lint": "eslint src --ext .ts",
12
+ "lint:fix": "eslint src --ext .ts --fix",
13
+ "start": "node dist/server.js",
14
+ "start:prod": "cross-env NODE_ENV=production node dist/server.js"
15
+ },
16
+ "dependencies": {
17
+ "compression": "^1.7.4",
18
+ "cors": "^2.8.5",
19
+ "dotenv": "^16.4.7",
20
+ "express": "^4.21.2",
21
+ "express-rate-limit": "^6.7.0",
22
+ "helmet": "^7.0.0",
23
+ "morgan": "^1.10.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/compression": "^1.8.1",
27
+ "@types/cors": "^2.8.17",
28
+ "@types/express": "^4.17.21",
29
+ "@types/morgan": "^1.9.4",
30
+ "@types/node": "^22.10.5",
31
+ "@typescript-eslint/eslint-plugin": "^8.52.0",
32
+ "@typescript-eslint/parser": "^8.52.0",
33
+ "cross-env": "^7.0.3",
34
+ "eslint": "^9.39.2",
35
+ "rimraf": "^5.0.0",
36
+ "tsx": "^4.19.2",
37
+ "typescript": "^5.7.2"
38
+ }
39
+ }
@@ -0,0 +1,71 @@
1
+ import compression from "compression";
2
+ import cors from "cors";
3
+ import express, { Application, NextFunction, Request, Response } from "express";
4
+ import rateLimit from "express-rate-limit";
5
+ import helmet from "helmet";
6
+ import morgan from "morgan";
7
+ import { env } from "./config/env";
8
+ import { errorHandler } from "./middlewares/error.middleware";
9
+
10
+ // app initialization
11
+ const app: Application = express();
12
+ app.use(express.json());
13
+
14
+ // trust proxy when behind reverse proxy (like Heroku, Vercel, Load Balancers)
15
+ if (env.app.trust_proxy) {
16
+ app.set("trust proxy", 1);
17
+ }
18
+
19
+ // security headers
20
+ app.use(helmet());
21
+
22
+ // response compression
23
+ app.use(compression());
24
+
25
+ // rate limiting
26
+ const limiter = rateLimit({
27
+ windowMs: env.app.rateLimit.windowMs,
28
+ max: env.app.rateLimit.max,
29
+ standardHeaders: true,
30
+ legacyHeaders: false,
31
+ });
32
+ app.use(limiter);
33
+
34
+ // logging
35
+ if (env.node.isProduction) {
36
+ app.use(morgan("combined"));
37
+ } else {
38
+ app.use(morgan("dev"));
39
+ }
40
+
41
+ // cors configuration
42
+ app.use(
43
+ cors({
44
+ origin: [env.app.site_url],
45
+ credentials: true,
46
+ }),
47
+ );
48
+
49
+ // Home page route
50
+ app.get("/", (req: Request, res: Response) => {
51
+ res.json({
52
+ title: "Welcome to your Express app",
53
+ description:
54
+ "Built with StackKit - A production-ready Express template with TypeScript, security, and best practices.",
55
+ version: "1.0.0",
56
+ docs: "https://github.com/tariqul420/stackkit",
57
+ });
58
+ });
59
+
60
+ // unhandled routes
61
+ app.use((req: Request, res: Response, next: NextFunction) => {
62
+ const error: any = new Error(`Can't find ${req.originalUrl} on this server!`);
63
+ error.status = 404;
64
+
65
+ next(error);
66
+ });
67
+
68
+ // Global error handler
69
+ app.use(errorHandler);
70
+
71
+ export default app;
@@ -0,0 +1,23 @@
1
+ import dotenv from "dotenv";
2
+ import path from "path";
3
+
4
+ dotenv.config({ path: path.join(process.cwd(), ".env") });
5
+
6
+ const env = {
7
+ app: {
8
+ port: Number(process.env.PORT) || 3000,
9
+ url: process.env.APP_URL || "http://localhost:3000",
10
+ site_url: process.env.SITE_URL || "http://localhost:5173",
11
+ trust_proxy: (process.env.TRUST_PROXY || "false") === "true",
12
+ rateLimit: {
13
+ max: Number(process.env.RATE_LIMIT_MAX) || 100,
14
+ windowMs: Number(process.env.RATE_LIMIT_WINDOW_MS) || 15 * 60 * 1000,
15
+ },
16
+ },
17
+ node: {
18
+ env: process.env.NODE_ENV || "development",
19
+ isProduction: (process.env.NODE_ENV || "development") === "production",
20
+ },
21
+ };
22
+
23
+ export { env };
@@ -0,0 +1,18 @@
1
+ import { NextFunction, Request, Response } from "express";
2
+ import { env } from "../config/env";
3
+
4
+ export const errorHandler = (err: any, req: Request, res: Response, next: NextFunction) => {
5
+ const statusCode = err.status || 500;
6
+ const errorMessage = err?.message || "Internal server error!";
7
+
8
+ const payload: any = {
9
+ success: false,
10
+ message: errorMessage,
11
+ };
12
+
13
+ if (!env.node.isProduction) {
14
+ payload.errors = err?.stack || err;
15
+ }
16
+
17
+ res.status(statusCode).json(payload);
18
+ };
@@ -1,5 +1,5 @@
1
- import app from './app';
2
- import { env } from './config/env';
1
+ import app from "./app";
2
+ import { env } from "./config/env";
3
3
 
4
4
  const port = env.app.port;
5
5
 
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "express-base",
3
+ "displayName": "Express.js",
4
+ "framework": "express",
5
+ "description": "Express.js REST API with TypeScript",
6
+ "files": ["src/", ".env.example", ".gitignore", "package.json", "tsconfig.json"],
7
+ "scripts": {
8
+ "dev": "tsx watch src/server.ts",
9
+ "clean": "rimraf dist",
10
+ "prebuild": "npm run clean",
11
+ "build": "tsc",
12
+ "lint": "eslint src --ext .ts",
13
+ "lint:fix": "eslint src --ext .ts --fix",
14
+ "start": "node dist/server.js",
15
+ "start:prod": "cross-env NODE_ENV=production node dist/server.js"
16
+ },
17
+ "jsScripts": {
18
+ "dev": "tsx --watch src/server.js",
19
+ "clean": "rimraf dist",
20
+ "prebuild": "npm run clean",
21
+ "build": "echo 'No build step for JavaScript'",
22
+ "lint": "eslint src --ext .js",
23
+ "lint:fix": "eslint src --ext .js --fix",
24
+ "start": "node src/server.js",
25
+ "start:prod": "cross-env NODE_ENV=production node src/server.js"
26
+ },
27
+ "fileReplacements": [
28
+ {
29
+ "file": "src/server.js",
30
+ "from": "import app from './app'",
31
+ "to": "import app from './app.js'"
32
+ },
33
+ {
34
+ "file": "src/app.js",
35
+ "from": "import { env } from './config/env'",
36
+ "to": "import { env } from './config/env.js'"
37
+ },
38
+ {
39
+ "file": "src/app.js",
40
+ "from": "import { errorHandler } from './middlewares/error.middleware'",
41
+ "to": "import { errorHandler } from './middlewares/error.middleware.js'"
42
+ }
43
+ ]
44
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "compilerOptions": {
3
+ "rootDir": "./src",
4
+ "outDir": "./dist",
5
+ "module": "ESNext",
6
+ "moduleResolution": "node",
7
+ "target": "ES2023",
8
+ "lib": ["ES2023"],
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "allowSyntheticDefaultImports": true,
12
+ "resolveJsonModule": true,
13
+ "skipLibCheck": true,
14
+ "forceConsistentCasingInFileNames": true,
15
+ "sourceMap": true,
16
+ "declaration": false,
17
+ "declarationMap": false,
18
+ "removeComments": false,
19
+ "noImplicitAny": true,
20
+ "noImplicitReturns": true,
21
+ "noImplicitThis": true,
22
+ "noUnusedLocals": true,
23
+ "noUnusedParameters": true,
24
+ "exactOptionalPropertyTypes": true,
25
+ "noEmitOnError": true,
26
+ "incremental": false,
27
+ "ignoreDeprecations": "5.0"
28
+ },
29
+ "include": ["src/**/*"],
30
+ "exclude": ["node_modules", "dist"]
31
+ }
@@ -24,11 +24,7 @@ export default function RootLayout({
24
24
  }>) {
25
25
  return (
26
26
  <html lang="en">
27
- <body
28
- className={`${geistSans.variable} ${geistMono.variable} antialiased`}
29
- >
30
- {children}
31
- </body>
27
+ <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>{children}</body>
32
28
  </html>
33
29
  );
34
30
  }
@@ -0,0 +1,57 @@
1
+ import Image from "next/image";
2
+
3
+ export default function Home() {
4
+ return (
5
+ <div className="flex min-h-screen items-center justify-center bg-zinc-50 font-sans dark:bg-black">
6
+ <main className="flex min-h-screen w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-white dark:bg-black sm:items-start">
7
+ <div className="flex items-center gap-4 mb-8">
8
+ <div className="text-2xl font-bold text-black dark:text-white">Stackkit</div>
9
+ <span className="text-xl text-zinc-400">+</span>
10
+ <Image
11
+ className="dark:invert"
12
+ src="/next.svg"
13
+ alt="Next.js logo"
14
+ width={100}
15
+ height={20}
16
+ priority
17
+ />
18
+ </div>
19
+ <div className="flex flex-col items-center gap-6 text-center sm:items-start sm:text-left">
20
+ <h1 className="max-w-xs text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50">
21
+ To get started, edit the page.tsx file.
22
+ </h1>
23
+ <p className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400">
24
+ This template includes Next.js, Tailwind CSS, and Stackkit best practices. Check out the{" "}
25
+ <a
26
+ href="https://github.com/tariqul420/stackkit"
27
+ className="font-medium text-zinc-950 dark:text-zinc-50 hover:underline"
28
+ target="_blank"
29
+ rel="noopener noreferrer"
30
+ >
31
+ Stackkit repository
32
+ </a>{" "}
33
+ for more info.
34
+ </p>
35
+ </div>
36
+ <div className="flex flex-col gap-4 text-base font-medium sm:flex-row">
37
+ <a
38
+ className="flex h-12 w-full items-center justify-center rounded-full bg-white text-black px-5 transition-colors hover:bg-zinc-200 md:w-40"
39
+ href="https://nextjs.org/docs"
40
+ target="_blank"
41
+ rel="noopener noreferrer"
42
+ >
43
+ Documentation
44
+ </a>
45
+ <a
46
+ className="flex h-12 w-full items-center justify-center rounded-full bg-black text-white px-5 transition-colors hover:bg-zinc-900 md:w-40"
47
+ href="https://github.com/tariqul420/stackkit"
48
+ target="_blank"
49
+ rel="noopener noreferrer"
50
+ >
51
+ Stackkit GitHub
52
+ </a>
53
+ </div>
54
+ </main>
55
+ </div>
56
+ );
57
+ }
@@ -2,6 +2,7 @@
2
2
  "name": "my-app",
3
3
  "version": "0.1.0",
4
4
  "private": true,
5
+ "type": "module",
5
6
  "scripts": {
6
7
  "dev": "next dev",
7
8
  "build": "next build",
@@ -23,4 +24,4 @@
23
24
  "tailwindcss": "^4",
24
25
  "typescript": "^5"
25
26
  }
26
- }
27
+ }
@@ -14,5 +14,17 @@
14
14
  "postcss.config.mjs",
15
15
  "README.md",
16
16
  "tsconfig.json"
17
- ]
17
+ ],
18
+ "scripts": {
19
+ "dev": "next dev",
20
+ "build": "next build",
21
+ "start": "next start",
22
+ "lint": "eslint"
23
+ },
24
+ "jsScripts": {
25
+ "dev": "next dev",
26
+ "build": "next build",
27
+ "start": "next start",
28
+ "lint": "eslint"
29
+ }
18
30
  }
@@ -0,0 +1,2 @@
1
+ # API Configuration
2
+ VITE_API_URL=http://localhost:3000