create-stackkit-app 0.4.0 → 0.4.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 (109) hide show
  1. package/README.md +25 -11
  2. package/dist/lib/create-project.js +88 -8
  3. package/dist/lib/template-composer.js +1 -1
  4. package/modules/auth/better-auth-express/adapters/mongoose-mongodb.ts +13 -0
  5. package/modules/auth/better-auth-express/adapters/prisma-mongodb.ts +15 -0
  6. package/modules/auth/better-auth-express/adapters/prisma-postgresql.ts +15 -0
  7. package/modules/auth/better-auth-express/files/schemas/prisma-mongodb-schema.prisma +72 -0
  8. package/modules/auth/better-auth-express/files/schemas/prisma-postgresql-schema.prisma +72 -0
  9. package/modules/auth/better-auth-express/module.json +26 -3
  10. package/modules/auth/better-auth-nextjs/adapters/mongoose-mongodb.ts +24 -0
  11. package/modules/auth/better-auth-nextjs/adapters/prisma-mongodb.ts +26 -0
  12. package/modules/auth/better-auth-nextjs/adapters/prisma-postgresql.ts +26 -0
  13. package/modules/auth/better-auth-nextjs/files/schemas/prisma-mongodb-schema.prisma +72 -0
  14. package/modules/auth/better-auth-nextjs/files/schemas/prisma-postgresql-schema.prisma +72 -0
  15. package/modules/auth/better-auth-nextjs/module.json +26 -5
  16. package/modules/auth/better-auth-react/module.json +7 -5
  17. package/modules/auth/clerk-express/module.json +23 -8
  18. package/modules/auth/clerk-nextjs/module.json +51 -14
  19. package/modules/auth/clerk-react/module.json +17 -7
  20. package/modules/database/mongoose-mongodb/module.json +44 -6
  21. package/modules/database/prisma-mongodb/files/prisma/schema.prisma +1 -1
  22. package/modules/database/prisma-mongodb/module.json +28 -4
  23. package/modules/database/prisma-postgresql/files/prisma/schema.prisma +1 -1
  24. package/modules/database/prisma-postgresql/module.json +28 -4
  25. package/package.json +3 -3
  26. package/templates/express/.env.example +11 -0
  27. package/templates/express/eslint.config.cjs +42 -0
  28. package/templates/express/package.json +38 -0
  29. package/templates/express/src/app.ts +69 -0
  30. package/templates/express/src/config/env.ts +23 -0
  31. package/templates/express/src/middlewares/error.middleware.ts +18 -0
  32. package/templates/express/src/server.ts +8 -0
  33. package/templates/{bases/express-base → express}/template.json +1 -1
  34. package/templates/express/tsconfig.json +14 -0
  35. package/templates/{bases/nextjs-base → nextjs}/app/page.tsx +5 -5
  36. package/templates/{bases/nextjs-base → nextjs}/template.json +1 -1
  37. package/templates/react-vite/.env.example +2 -0
  38. package/templates/react-vite/README.md +85 -0
  39. package/templates/react-vite/eslint.config.js +23 -0
  40. package/templates/{bases/react-vite-base → react-vite}/index.html +2 -1
  41. package/templates/react-vite/package.json +45 -0
  42. package/templates/react-vite/public/vite.svg +1 -0
  43. package/templates/react-vite/src/api/client.ts +47 -0
  44. package/templates/react-vite/src/api/services/user.service.ts +26 -0
  45. package/templates/react-vite/src/assets/react.svg +1 -0
  46. package/templates/react-vite/src/components/ErrorBoundary.tsx +51 -0
  47. package/templates/react-vite/src/components/Layout.tsx +13 -0
  48. package/templates/react-vite/src/components/Loading.tsx +8 -0
  49. package/templates/react-vite/src/components/SEO.tsx +49 -0
  50. package/templates/react-vite/src/config/constants.ts +5 -0
  51. package/templates/react-vite/src/hooks/index.ts +64 -0
  52. package/templates/react-vite/src/index.css +1 -0
  53. package/templates/react-vite/src/lib/queryClient.ts +12 -0
  54. package/templates/react-vite/src/main.tsx +22 -0
  55. package/templates/react-vite/src/pages/About.tsx +74 -0
  56. package/templates/react-vite/src/pages/Home.tsx +45 -0
  57. package/templates/react-vite/src/pages/NotFound.tsx +24 -0
  58. package/templates/react-vite/src/pages/UserProfile.tsx +40 -0
  59. package/templates/react-vite/src/router.tsx +33 -0
  60. package/templates/react-vite/src/types/api.ts +20 -0
  61. package/templates/react-vite/src/utils/helpers.ts +51 -0
  62. package/templates/react-vite/src/utils/storage.ts +35 -0
  63. package/templates/react-vite/src/vite-env.d.ts +11 -0
  64. package/templates/react-vite/template.json +20 -0
  65. package/templates/{bases/react-vite-base/tsconfig.json → react-vite/tsconfig.app.json} +10 -3
  66. package/templates/react-vite/tsconfig.json +7 -0
  67. package/templates/react-vite/tsconfig.node.json +26 -0
  68. package/templates/react-vite/vite.config.ts +13 -0
  69. package/modules/auth/authjs-express/files/lib/auth.ts +0 -40
  70. package/modules/auth/authjs-express/files/routes/auth.ts +0 -12
  71. package/modules/auth/authjs-express/module.json +0 -39
  72. package/modules/auth/authjs-nextjs/files/api/auth/[...nextauth]/route.ts +0 -3
  73. package/modules/auth/authjs-nextjs/files/lib/auth.ts +0 -43
  74. package/modules/auth/authjs-nextjs/module.json +0 -38
  75. package/modules/auth/nextauth/files/app-router/api/auth/[...nextauth]/route.ts +0 -6
  76. package/modules/auth/nextauth/files/lib/auth.ts +0 -82
  77. package/modules/auth/nextauth/files/pages-router/api/auth/[...nextauth].ts +0 -4
  78. package/modules/auth/nextauth/module.json +0 -50
  79. package/modules/database/drizzle-postgresql/files/drizzle.config.ts +0 -10
  80. package/modules/database/drizzle-postgresql/files/lib/db.ts +0 -7
  81. package/modules/database/drizzle-postgresql/files/lib/schema.ts +0 -8
  82. package/modules/database/drizzle-postgresql/module.json +0 -34
  83. package/templates/bases/express-base/.env.example +0 -2
  84. package/templates/bases/express-base/package.json +0 -23
  85. package/templates/bases/express-base/src/index.ts +0 -27
  86. package/templates/bases/express-base/tsconfig.json +0 -17
  87. package/templates/bases/nextjs-base/package-lock.json +0 -6538
  88. package/templates/bases/react-vite-base/package.json +0 -27
  89. package/templates/bases/react-vite-base/src/App.css +0 -14
  90. package/templates/bases/react-vite-base/src/App.tsx +0 -23
  91. package/templates/bases/react-vite-base/src/index.css +0 -68
  92. package/templates/bases/react-vite-base/src/main.tsx +0 -10
  93. package/templates/bases/react-vite-base/src/vite-env.d.ts +0 -1
  94. package/templates/bases/react-vite-base/template.json +0 -5
  95. package/templates/bases/react-vite-base/vite.config.ts +0 -7
  96. /package/templates/{bases/nextjs-base → nextjs}/README.md +0 -0
  97. /package/templates/{bases/nextjs-base → nextjs}/app/favicon.ico +0 -0
  98. /package/templates/{bases/nextjs-base → nextjs}/app/globals.css +0 -0
  99. /package/templates/{bases/nextjs-base → nextjs}/app/layout.tsx +0 -0
  100. /package/templates/{bases/nextjs-base → nextjs}/eslint.config.mjs +0 -0
  101. /package/templates/{bases/nextjs-base → nextjs}/next.config.ts +0 -0
  102. /package/templates/{bases/nextjs-base → nextjs}/package.json +0 -0
  103. /package/templates/{bases/nextjs-base → nextjs}/postcss.config.mjs +0 -0
  104. /package/templates/{bases/nextjs-base → nextjs}/public/file.svg +0 -0
  105. /package/templates/{bases/nextjs-base → nextjs}/public/globe.svg +0 -0
  106. /package/templates/{bases/nextjs-base → nextjs}/public/next.svg +0 -0
  107. /package/templates/{bases/nextjs-base → nextjs}/public/vercel.svg +0 -0
  108. /package/templates/{bases/nextjs-base → nextjs}/public/window.svg +0 -0
  109. /package/templates/{bases/nextjs-base → nextjs}/tsconfig.json +0 -0
@@ -1,14 +1,35 @@
1
1
  {
2
- "name": "auth",
2
+ "name": "better-auth-nextjs",
3
3
  "displayName": "Better Auth (Next.js)",
4
4
  "description": "Modern authentication with Better Auth for Next.js App Router",
5
5
  "category": "auth",
6
6
  "provider": "better-auth",
7
7
  "supportedFrameworks": ["nextjs"],
8
- "compatibleDatabases": ["prisma-postgresql", "prisma-mongodb"],
9
- "dependencies": {
10
- "better-auth": "^1.1.4",
11
- "@better-auth/prisma": "^1.1.4"
8
+ "databaseAdapters": {
9
+ "prisma-postgresql": {
10
+ "adapter": "adapters/prisma-postgresql.ts",
11
+ "schema": "files/schemas/prisma-postgresql-schema.prisma",
12
+ "schemaDestination": "prisma/schema.prisma",
13
+ "dependencies": {
14
+ "better-auth": "^1.1.4",
15
+ "@better-auth/prisma": "^1.1.4"
16
+ }
17
+ },
18
+ "prisma-mongodb": {
19
+ "adapter": "adapters/prisma-mongodb.ts",
20
+ "schema": "files/schemas/prisma-mongodb-schema.prisma",
21
+ "schemaDestination": "prisma/schema.prisma",
22
+ "dependencies": {
23
+ "better-auth": "^1.1.4",
24
+ "@better-auth/prisma": "^1.1.4"
25
+ }
26
+ },
27
+ "mongoose-mongodb": {
28
+ "adapter": "adapters/mongoose-mongodb.ts",
29
+ "dependencies": {
30
+ "better-auth": "^1.1.4"
31
+ }
32
+ }
12
33
  },
13
34
  "envVars": [
14
35
  {
@@ -1,18 +1,20 @@
1
1
  {
2
- "name": "auth",
2
+ "name": "better-auth-react",
3
3
  "displayName": "Better Auth (React)",
4
4
  "description": "Client-side authentication with Better Auth for React",
5
5
  "category": "auth",
6
- "supportedFrameworks": ["react", "react-vite"],
6
+ "provider": "better-auth",
7
+ "supportedFrameworks": ["react-vite"],
7
8
  "dependencies": {
8
- "better-auth": "^1.0.0"
9
+ "better-auth": "^1.1.4"
9
10
  },
11
+ "devDependencies": {},
10
12
  "envVars": [
11
13
  {
12
14
  "key": "VITE_AUTH_URL",
13
15
  "value": "http://localhost:3000",
14
- "description": "Base URL of your auth server (optional if same domain)",
15
- "required": false
16
+ "description": "Base URL of your auth server",
17
+ "required": true
16
18
  }
17
19
  ],
18
20
  "patches": [
@@ -1,19 +1,34 @@
1
1
  {
2
2
  "name": "clerk-express",
3
+ "displayName": "Clerk (Express)",
3
4
  "description": "Clerk Authentication for Express.js",
4
5
  "category": "auth",
5
- "framework": "express",
6
+ "provider": "clerk",
7
+ "supportedFrameworks": ["express"],
6
8
  "dependencies": {
7
9
  "@clerk/express": "^1.4.5"
8
10
  },
9
- "env": {
10
- "CLERK_PUBLISHABLE_KEY": "pk_test_your_key_here",
11
- "CLERK_SECRET_KEY": "sk_test_your_key_here"
12
- },
13
- "files": [
11
+ "devDependencies": {},
12
+ "envVars": [
13
+ {
14
+ "key": "CLERK_PUBLISHABLE_KEY",
15
+ "value": "",
16
+ "description": "Clerk publishable key (from Clerk dashboard)",
17
+ "required": true
18
+ },
19
+ {
20
+ "key": "CLERK_SECRET_KEY",
21
+ "value": "",
22
+ "description": "Clerk secret key (from Clerk dashboard)",
23
+ "required": true
24
+ }
25
+ ],
26
+ "patches": [
14
27
  {
15
- "source": "files/lib/auth.ts",
16
- "destination": "lib/auth.ts"
28
+ "type": "create-file",
29
+ "description": "Create Clerk auth middleware",
30
+ "source": "lib/auth.ts",
31
+ "destination": "{{lib}}/auth.ts"
17
32
  }
18
33
  ]
19
34
  }
@@ -1,26 +1,63 @@
1
1
  {
2
2
  "name": "clerk-nextjs",
3
- "description": "Clerk Authentication for Next.js",
3
+ "displayName": "Clerk (Next.js)",
4
+ "description": "Clerk Authentication for Next.js App Router",
4
5
  "category": "auth",
5
- "framework": "nextjs",
6
+ "provider": "clerk",
7
+ "supportedFrameworks": ["nextjs"],
6
8
  "dependencies": {
7
9
  "@clerk/nextjs": "^6.10.2"
8
10
  },
9
- "env": {
10
- "NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY": "pk_test_your_key_here",
11
- "CLERK_SECRET_KEY": "sk_test_your_key_here",
12
- "NEXT_PUBLIC_CLERK_SIGN_IN_URL": "/sign-in",
13
- "NEXT_PUBLIC_CLERK_SIGN_UP_URL": "/sign-up",
14
- "NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL": "/",
15
- "NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL": "/"
16
- },
17
- "files": [
11
+ "devDependencies": {},
12
+ "envVars": [
13
+ {
14
+ "key": "NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY",
15
+ "value": "",
16
+ "description": "Clerk publishable key (from Clerk dashboard)",
17
+ "required": true
18
+ },
19
+ {
20
+ "key": "CLERK_SECRET_KEY",
21
+ "value": "",
22
+ "description": "Clerk secret key (from Clerk dashboard)",
23
+ "required": true
24
+ },
25
+ {
26
+ "key": "NEXT_PUBLIC_CLERK_SIGN_IN_URL",
27
+ "value": "/sign-in",
28
+ "description": "Sign in page URL",
29
+ "required": true
30
+ },
31
+ {
32
+ "key": "NEXT_PUBLIC_CLERK_SIGN_UP_URL",
33
+ "value": "/sign-up",
34
+ "description": "Sign up page URL",
35
+ "required": true
36
+ },
37
+ {
38
+ "key": "NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL",
39
+ "value": "/",
40
+ "description": "Redirect URL after sign in",
41
+ "required": true
42
+ },
43
+ {
44
+ "key": "NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL",
45
+ "value": "/",
46
+ "description": "Redirect URL after sign up",
47
+ "required": true
48
+ }
49
+ ],
50
+ "patches": [
18
51
  {
19
- "source": "files/lib/auth-provider.tsx",
20
- "destination": "lib/auth-provider.tsx"
52
+ "type": "create-file",
53
+ "description": "Create Clerk auth provider",
54
+ "source": "lib/auth-provider.tsx",
55
+ "destination": "{{lib}}/auth-provider.tsx"
21
56
  },
22
57
  {
23
- "source": "files/middleware.ts",
58
+ "type": "create-file",
59
+ "description": "Create Clerk middleware",
60
+ "source": "middleware.ts",
24
61
  "destination": "middleware.ts"
25
62
  }
26
63
  ]
@@ -1,18 +1,28 @@
1
1
  {
2
2
  "name": "clerk-react",
3
+ "displayName": "Clerk (React)",
3
4
  "description": "Clerk Authentication for React",
4
5
  "category": "auth",
5
- "framework": "react-vite",
6
+ "provider": "clerk",
7
+ "supportedFrameworks": ["react-vite"],
6
8
  "dependencies": {
7
9
  "@clerk/clerk-react": "^5.19.2"
8
10
  },
9
- "env": {
10
- "VITE_CLERK_PUBLISHABLE_KEY": "pk_test_your_key_here"
11
- },
12
- "files": [
11
+ "devDependencies": {},
12
+ "envVars": [
13
+ {
14
+ "key": "VITE_CLERK_PUBLISHABLE_KEY",
15
+ "value": "",
16
+ "description": "Clerk publishable key (from Clerk dashboard)",
17
+ "required": true
18
+ }
19
+ ],
20
+ "patches": [
13
21
  {
14
- "source": "files/lib/auth-provider.tsx",
15
- "destination": "lib/auth-provider.tsx"
22
+ "type": "create-file",
23
+ "description": "Create Clerk auth provider",
24
+ "source": "lib/auth-provider.tsx",
25
+ "destination": "src/lib/auth-provider.tsx"
16
26
  }
17
27
  ]
18
28
  }
@@ -1,17 +1,55 @@
1
1
  {
2
2
  "name": "mongoose-mongodb",
3
- "description": "Mongoose ODM for MongoDB",
3
+ "displayName": "Mongoose + MongoDB",
4
+ "description": "Mongoose ODM for MongoDB database",
4
5
  "category": "database",
6
+ "provider": "mongoose",
7
+ "database": "mongodb",
8
+ "supportedFrameworks": ["nextjs", "express"],
5
9
  "dependencies": {
6
10
  "mongoose": "^8.8.4"
7
11
  },
8
- "env": {
9
- "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
+ }
10
46
  },
11
- "files": [
47
+ "patches": [
12
48
  {
13
- "source": "files/lib/db.ts",
14
- "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"
15
53
  }
16
54
  ]
17
55
  }
@@ -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
  ],
@@ -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": "create-stackkit-app",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Create a new StackKit project with modular composition",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -37,7 +37,7 @@
37
37
  "nextjs",
38
38
  "template"
39
39
  ],
40
- "author": "Your Name",
40
+ "author": "Tariqul Islam",
41
41
  "license": "MIT",
42
42
  "dependencies": {
43
43
  "chalk": "^4.1.2",
@@ -53,4 +53,4 @@
53
53
  "@types/validate-npm-package-name": "^4.0.2",
54
54
  "typescript": "^5.3.3"
55
55
  }
56
- }
56
+ }
@@ -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,38 @@
1
+ {
2
+ "name": "my-app",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "tsx watch src/server.ts",
7
+ "clean": "rimraf dist",
8
+ "prebuild": "npm run clean",
9
+ "build": "tsc",
10
+ "lint": "eslint src --ext .ts",
11
+ "lint:fix": "eslint src --ext .ts --fix",
12
+ "start": "node dist/server.js",
13
+ "start:prod": "cross-env NODE_ENV=production node dist/server.js"
14
+ },
15
+ "dependencies": {
16
+ "compression": "^1.7.4",
17
+ "cors": "^2.8.5",
18
+ "dotenv": "^16.4.7",
19
+ "express": "^4.21.2",
20
+ "express-rate-limit": "^6.7.0",
21
+ "helmet": "^7.0.0",
22
+ "morgan": "^1.10.0"
23
+ },
24
+ "devDependencies": {
25
+ "@types/compression": "^1.8.1",
26
+ "@types/cors": "^2.8.17",
27
+ "@types/express": "^4.17.21",
28
+ "@types/morgan": "^1.9.4",
29
+ "@types/node": "^22.10.5",
30
+ "@typescript-eslint/eslint-plugin": "^8.52.0",
31
+ "@typescript-eslint/parser": "^8.52.0",
32
+ "cross-env": "^7.0.3",
33
+ "eslint": "^9.39.2",
34
+ "rimraf": "^5.0.0",
35
+ "tsx": "^4.19.2",
36
+ "typescript": "^5.7.2"
37
+ }
38
+ }
@@ -0,0 +1,69 @@
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: 'StackKit - Production-ready project generator',
53
+ description:
54
+ 'Modern CLI tool for creating production-ready web applications with modular architecture. Build with Next.js, Express, or React.',
55
+ });
56
+ });
57
+
58
+ // unhandled routes
59
+ app.use((req: Request, res: Response, next: NextFunction) => {
60
+ const error: any = new Error(`Can't find ${req.originalUrl} on this server!`);
61
+ error.status = 404;
62
+
63
+ next(error);
64
+ });
65
+
66
+ // Global error handler
67
+ app.use(errorHandler);
68
+
69
+ 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
+ };
@@ -0,0 +1,8 @@
1
+ import app from './app';
2
+ import { env } from './config/env';
3
+
4
+ const port = env.app.port;
5
+
6
+ app.listen(port, () => {
7
+ console.log(`Server is running on http://localhost:${port}`);
8
+ });
@@ -3,5 +3,5 @@
3
3
  "displayName": "Express.js",
4
4
  "framework": "express",
5
5
  "description": "Express.js REST API with TypeScript",
6
- "files": ["src/", "tsconfig.json", "package.json"]
6
+ "files": ["src/", ".env.example", ".gitignore", "package.json", "tsconfig.json"]
7
7
  }