create-stackkit-app 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 (59) hide show
  1. package/README.md +1 -0
  2. package/bin/create-stackkit.js +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/lib/create-project.js +329 -143
  5. package/dist/lib/template-composer.js +21 -21
  6. package/modules/auth/better-auth-express/adapters/mongoose-mongodb.ts +3 -3
  7. package/modules/auth/better-auth-express/adapters/prisma-mongodb.ts +4 -4
  8. package/modules/auth/better-auth-express/adapters/prisma-postgresql.ts +4 -4
  9. package/modules/auth/better-auth-express/files/lib/auth.ts +1 -1
  10. package/modules/auth/better-auth-express/files/routes/auth.ts +3 -3
  11. package/modules/auth/better-auth-nextjs/adapters/mongoose-mongodb.ts +3 -3
  12. package/modules/auth/better-auth-nextjs/adapters/prisma-mongodb.ts +4 -4
  13. package/modules/auth/better-auth-nextjs/adapters/prisma-postgresql.ts +4 -4
  14. package/modules/auth/better-auth-nextjs/files/api/auth/[...all]/route.ts +2 -3
  15. package/modules/auth/better-auth-nextjs/files/lib/auth.ts +4 -4
  16. package/modules/auth/better-auth-react/files/lib/auth-client.ts +2 -2
  17. package/modules/auth/clerk-express/files/lib/auth.ts +1 -1
  18. package/modules/auth/clerk-nextjs/files/lib/auth-provider.tsx +1 -1
  19. package/modules/auth/clerk-nextjs/files/middleware.ts +3 -3
  20. package/modules/auth/clerk-react/files/lib/auth-provider.tsx +2 -2
  21. package/modules/database/mongoose-mongodb/files/lib/db.ts +3 -3
  22. package/modules/database/prisma-mongodb/files/lib/db.ts +2 -2
  23. package/modules/database/prisma-postgresql/files/lib/db.ts +2 -2
  24. package/package.json +8 -3
  25. package/templates/express/package.json +1 -0
  26. package/templates/express/src/app.ts +17 -15
  27. package/templates/express/src/config/env.ts +8 -8
  28. package/templates/express/src/middlewares/error.middleware.ts +3 -3
  29. package/templates/express/src/server.ts +2 -2
  30. package/templates/express/template.json +38 -1
  31. package/templates/express/tsconfig.json +17 -0
  32. package/templates/nextjs/app/layout.tsx +1 -5
  33. package/templates/nextjs/app/page.tsx +26 -34
  34. package/templates/nextjs/package.json +2 -1
  35. package/templates/nextjs/template.json +13 -1
  36. package/templates/react-vite/eslint.config.js +9 -9
  37. package/templates/react-vite/package.json +1 -2
  38. package/templates/react-vite/src/api/client.ts +16 -16
  39. package/templates/react-vite/src/api/services/user.service.ts +2 -10
  40. package/templates/react-vite/src/components/ErrorBoundary.tsx +4 -4
  41. package/templates/react-vite/src/components/Layout.tsx +1 -1
  42. package/templates/react-vite/src/components/Loading.tsx +1 -1
  43. package/templates/react-vite/src/components/SEO.tsx +5 -5
  44. package/templates/react-vite/src/config/constants.ts +3 -3
  45. package/templates/react-vite/src/hooks/index.ts +5 -5
  46. package/templates/react-vite/src/lib/queryClient.ts +2 -2
  47. package/templates/react-vite/src/main.tsx +12 -12
  48. package/templates/react-vite/src/pages/About.tsx +6 -2
  49. package/templates/react-vite/src/pages/Home.tsx +8 -4
  50. package/templates/react-vite/src/pages/NotFound.tsx +2 -2
  51. package/templates/react-vite/src/pages/UserProfile.tsx +6 -6
  52. package/templates/react-vite/src/router.tsx +13 -13
  53. package/templates/react-vite/src/types/{api.ts → api.d.ts} +6 -6
  54. package/templates/react-vite/src/types/user.d.ts +6 -0
  55. package/templates/react-vite/src/utils/helpers.ts +11 -11
  56. package/templates/react-vite/src/utils/storage.ts +4 -4
  57. package/templates/react-vite/template.json +26 -0
  58. package/templates/react-vite/tsconfig.json +1 -4
  59. package/templates/react-vite/vite.config.ts +5 -5
@@ -23,8 +23,8 @@ class TemplateComposer {
23
23
  const baseFiles = await this.getBaseFiles(framework);
24
24
  filesToCopy.push(...baseFiles);
25
25
  // 2. Load database configuration if not "none"
26
- if (database !== 'none') {
27
- const dbConfig = await this.loadConfig(path_1.default.join(this.templatesDir, 'databases', database));
26
+ if (database !== "none") {
27
+ const dbConfig = await this.loadConfig(path_1.default.join(this.templatesDir, "databases", database));
28
28
  // Check compatibility
29
29
  if (dbConfig.compatibleWith?.frameworks &&
30
30
  !dbConfig.compatibleWith.frameworks.includes(framework)) {
@@ -32,17 +32,17 @@ class TemplateComposer {
32
32
  }
33
33
  configs.push(dbConfig);
34
34
  // Copy database files
35
- const dbDir = path_1.default.join(this.templatesDir, 'databases', database);
35
+ const dbDir = path_1.default.join(this.templatesDir, "databases", database);
36
36
  const dbFiles = await this.collectFiles(dbDir);
37
37
  filesToCopy.push(...dbFiles.map((f) => ({
38
38
  source: f,
39
- dest: path_1.default.join(targetDir, f.replace(dbDir + path_1.default.sep, '')),
39
+ dest: path_1.default.join(targetDir, f.replace(dbDir + path_1.default.sep, "")),
40
40
  })));
41
41
  }
42
42
  // 3. Load auth configuration if not "none"
43
- if (auth !== 'none') {
43
+ if (auth !== "none") {
44
44
  const authKey = this.getAuthKey(framework, auth);
45
- const authDir = path_1.default.join(this.templatesDir, 'auth', authKey);
45
+ const authDir = path_1.default.join(this.templatesDir, "auth", authKey);
46
46
  if (await fs_extra_1.default.pathExists(authDir)) {
47
47
  const authConfig = await this.loadConfig(authDir);
48
48
  // Check compatibility
@@ -59,7 +59,7 @@ class TemplateComposer {
59
59
  const authFiles = await this.collectFiles(authDir);
60
60
  filesToCopy.push(...authFiles.map((f) => ({
61
61
  source: f,
62
- dest: path_1.default.join(targetDir, f.replace(authDir + path_1.default.sep, '')),
62
+ dest: path_1.default.join(targetDir, f.replace(authDir + path_1.default.sep, "")),
63
63
  })));
64
64
  }
65
65
  }
@@ -73,8 +73,8 @@ class TemplateComposer {
73
73
  await this.writeEnvFile(targetDir, mergedConfig);
74
74
  }
75
75
  async loadConfig(dir) {
76
- const configPath = path_1.default.join(dir, 'config.json');
77
- const templatePath = path_1.default.join(dir, 'template.json');
76
+ const configPath = path_1.default.join(dir, "config.json");
77
+ const templatePath = path_1.default.join(dir, "template.json");
78
78
  if (await fs_extra_1.default.pathExists(configPath)) {
79
79
  return await fs_extra_1.default.readJson(configPath);
80
80
  }
@@ -86,14 +86,14 @@ class TemplateComposer {
86
86
  async getBaseFiles(framework) {
87
87
  // For now, use existing complete template
88
88
  // In future, this will use minimal base templates
89
- const baseDir = path_1.default.join(this.templatesDir, 'next-prisma-postgres-shadcn');
89
+ const baseDir = path_1.default.join(this.templatesDir, "next-prisma-postgres-shadcn");
90
90
  const files = await this.collectFiles(baseDir);
91
91
  return files.map((source) => ({
92
92
  source,
93
- dest: source.replace(baseDir, ''),
93
+ dest: source.replace(baseDir, ""),
94
94
  }));
95
95
  }
96
- async collectFiles(dir, exclude = ['config.json', 'template.json', 'node_modules']) {
96
+ async collectFiles(dir, exclude = ["config.json", "template.json", "node_modules"]) {
97
97
  const files = [];
98
98
  if (!(await fs_extra_1.default.pathExists(dir))) {
99
99
  return files;
@@ -143,7 +143,7 @@ class TemplateComposer {
143
143
  }, {});
144
144
  }
145
145
  async writePackageJson(targetDir, config) {
146
- const pkgPath = path_1.default.join(targetDir, 'package.json');
146
+ const pkgPath = path_1.default.join(targetDir, "package.json");
147
147
  let pkg = {};
148
148
  if (await fs_extra_1.default.pathExists(pkgPath)) {
149
149
  pkg = await fs_extra_1.default.readJson(pkgPath);
@@ -164,16 +164,16 @@ class TemplateComposer {
164
164
  if (!config.env || Object.keys(config.env).length === 0) {
165
165
  return;
166
166
  }
167
- const envPath = path_1.default.join(targetDir, '.env');
168
- const envExamplePath = path_1.default.join(targetDir, '.env.example');
167
+ const envPath = path_1.default.join(targetDir, ".env");
168
+ const envExamplePath = path_1.default.join(targetDir, ".env.example");
169
169
  const envContent = Object.entries(config.env)
170
170
  .map(([key, value]) => `${key}="${value}"`)
171
- .join('\n') + '\n';
171
+ .join("\n") + "\n";
172
172
  // Append or create .env.example
173
173
  if (await fs_extra_1.default.pathExists(envExamplePath)) {
174
- const existing = await fs_extra_1.default.readFile(envExamplePath, 'utf-8');
174
+ const existing = await fs_extra_1.default.readFile(envExamplePath, "utf-8");
175
175
  if (!existing.includes(envContent)) {
176
- await fs_extra_1.default.appendFile(envExamplePath, '\n' + envContent);
176
+ await fs_extra_1.default.appendFile(envExamplePath, "\n" + envContent);
177
177
  }
178
178
  }
179
179
  else {
@@ -187,9 +187,9 @@ class TemplateComposer {
187
187
  getAuthKey(framework, auth) {
188
188
  // Map framework + auth to specific implementation
189
189
  const mapping = {
190
- 'nextjs-nextauth': 'nextauth',
191
- 'nextjs-better-auth': 'better-auth-nextjs',
192
- 'express-better-auth': 'better-auth-express',
190
+ "nextjs-nextauth": "nextauth",
191
+ "nextjs-better-auth": "better-auth-nextjs",
192
+ "express-better-auth": "better-auth-express",
193
193
  };
194
194
  return mapping[`${framework}-${auth}`] || auth;
195
195
  }
@@ -1,6 +1,6 @@
1
- import { betterAuth } from 'better-auth';
2
- import { mongodbAdapter } from 'better-auth/adapters/mongodb';
3
- import { client } from './db';
1
+ import { betterAuth } from "better-auth";
2
+ import { mongodbAdapter } from "better-auth/adapters/mongodb";
3
+ import { client } from "./db";
4
4
 
5
5
  export const auth = betterAuth({
6
6
  database: mongodbAdapter(client),
@@ -1,10 +1,10 @@
1
- import { prismaAdapter } from '@better-auth/prisma';
2
- import { betterAuth } from 'better-auth';
3
- import { prisma } from './db';
1
+ import { prismaAdapter } from "@better-auth/prisma";
2
+ import { betterAuth } from "better-auth";
3
+ import { prisma } from "./db";
4
4
 
5
5
  export const auth = betterAuth({
6
6
  database: prismaAdapter(prisma, {
7
- provider: 'mongodb',
7
+ provider: "mongodb",
8
8
  }),
9
9
  emailAndPassword: {
10
10
  enabled: true,
@@ -1,10 +1,10 @@
1
- import { prismaAdapter } from '@better-auth/prisma';
2
- import { betterAuth } from 'better-auth';
3
- import { prisma } from './db';
1
+ import { prismaAdapter } from "@better-auth/prisma";
2
+ import { betterAuth } from "better-auth";
3
+ import { prisma } from "./db";
4
4
 
5
5
  export const auth = betterAuth({
6
6
  database: prismaAdapter(prisma, {
7
- provider: 'postgresql',
7
+ provider: "postgresql",
8
8
  }),
9
9
  emailAndPassword: {
10
10
  enabled: true,
@@ -1,4 +1,4 @@
1
- import { betterAuth } from 'better-auth';
1
+ import { betterAuth } from "better-auth";
2
2
 
3
3
  export const auth = betterAuth({
4
4
  secret: process.env.BETTER_AUTH_SECRET!,
@@ -1,10 +1,10 @@
1
- import { Router } from 'express';
2
- import { auth } from '../lib/auth';
1
+ import { Router } from "express";
2
+ import { auth } from "../lib/auth";
3
3
 
4
4
  const router = Router();
5
5
 
6
6
  // Mount Better Auth handlers
7
- router.all('/auth/*', async (req, res) => {
7
+ router.all("/auth/*", async (req, res) => {
8
8
  const response = await auth.handler(req);
9
9
  return res.status(response.status).json(response.body);
10
10
  });
@@ -1,6 +1,6 @@
1
- import { client } from '@/lib/db';
2
- import { betterAuth } from 'better-auth';
3
- import { mongodbAdapter } from 'better-auth/adapters/mongodb';
1
+ import { client } from "@/lib/db";
2
+ import { betterAuth } from "better-auth";
3
+ import { mongodbAdapter } from "better-auth/adapters/mongodb";
4
4
 
5
5
  export const auth = betterAuth({
6
6
  database: mongodbAdapter(client),
@@ -1,10 +1,10 @@
1
- import { prisma } from '@/lib/db';
2
- import { prismaAdapter } from '@better-auth/prisma';
3
- import { betterAuth } from 'better-auth';
1
+ import { prisma } from "@/lib/db";
2
+ import { prismaAdapter } from "@better-auth/prisma";
3
+ import { betterAuth } from "better-auth";
4
4
 
5
5
  export const auth = betterAuth({
6
6
  database: prismaAdapter(prisma, {
7
- provider: 'mongodb',
7
+ provider: "mongodb",
8
8
  }),
9
9
  emailAndPassword: {
10
10
  enabled: true,
@@ -1,10 +1,10 @@
1
- import { prisma } from '@/lib/db';
2
- import { prismaAdapter } from '@better-auth/prisma';
3
- import { betterAuth } from 'better-auth';
1
+ import { prisma } from "@/lib/db";
2
+ import { prismaAdapter } from "@better-auth/prisma";
3
+ import { betterAuth } from "better-auth";
4
4
 
5
5
  export const auth = betterAuth({
6
6
  database: prismaAdapter(prisma, {
7
- provider: 'postgresql',
7
+ provider: "postgresql",
8
8
  }),
9
9
  emailAndPassword: {
10
10
  enabled: true,
@@ -1,5 +1,4 @@
1
- import { auth } from '@/lib/auth';
2
- import { toNextJsHandler } from 'better-auth/next-js';
1
+ import { auth } from "@/lib/auth";
2
+ import { toNextJsHandler } from "better-auth/next-js";
3
3
 
4
4
  export const { GET, POST } = toNextJsHandler(auth);
5
-
@@ -1,10 +1,10 @@
1
- import { prismaAdapter } from '@better-auth/prisma';
2
- import { betterAuth } from 'better-auth';
3
- import { prisma } from './db';
1
+ import { prismaAdapter } from "@better-auth/prisma";
2
+ import { betterAuth } from "better-auth";
3
+ import { prisma } from "./db";
4
4
 
5
5
  export const auth = betterAuth({
6
6
  database: prismaAdapter(prisma, {
7
- provider: 'postgresql', // Change to 'mongodb' if using MongoDB
7
+ provider: "postgresql", // Change to 'mongodb' if using MongoDB
8
8
  }),
9
9
  emailAndPassword: {
10
10
  enabled: true,
@@ -1,8 +1,8 @@
1
- import { createAuthClient } from 'better-auth/react';
1
+ import { createAuthClient } from "better-auth/react";
2
2
 
3
3
  export const authClient = createAuthClient({
4
4
  /** The base URL of the server (optional if you're using the same domain) */
5
- baseURL: import.meta.env.VITE_AUTH_URL || 'http://localhost:3000',
5
+ baseURL: import.meta.env.VITE_AUTH_URL || "http://localhost:3000",
6
6
  });
7
7
 
8
8
  // Export specific methods for convenience
@@ -1,4 +1,4 @@
1
- import { clerkClient, clerkMiddleware, requireAuth } from '@clerk/express';
1
+ import { clerkClient, clerkMiddleware, requireAuth } from "@clerk/express";
2
2
 
3
3
  export { clerkMiddleware, requireAuth };
4
4
 
@@ -1,4 +1,4 @@
1
- import { ClerkProvider } from '@clerk/nextjs';
1
+ import { ClerkProvider } from "@clerk/nextjs";
2
2
 
3
3
  export function AuthProvider({ children }: { children: React.ReactNode }) {
4
4
  return <ClerkProvider>{children}</ClerkProvider>;
@@ -1,9 +1,9 @@
1
- import { authMiddleware } from '@clerk/nextjs';
1
+ import { authMiddleware } from "@clerk/nextjs";
2
2
 
3
3
  export default authMiddleware({
4
- publicRoutes: ['/'],
4
+ publicRoutes: ["/"],
5
5
  });
6
6
 
7
7
  export const config = {
8
- matcher: ['/((?!.+\\.[\\w]+$|_next).*)', '/', '/(api|trpc)(.*)'],
8
+ matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/", "/(api|trpc)(.*)"],
9
9
  };
@@ -1,9 +1,9 @@
1
- import { ClerkProvider } from '@clerk/clerk-react';
1
+ import { ClerkProvider } from "@clerk/clerk-react";
2
2
 
3
3
  const publishableKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY;
4
4
 
5
5
  if (!publishableKey) {
6
- throw new Error('Missing Publishable Key');
6
+ throw new Error("Missing Publishable Key");
7
7
  }
8
8
 
9
9
  export function AuthProvider({ children }: { children: React.ReactNode }) {
@@ -1,9 +1,9 @@
1
- import mongoose from 'mongoose';
1
+ import mongoose from "mongoose";
2
2
 
3
- const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017/myapp';
3
+ const MONGODB_URI = process.env.MONGODB_URI || "mongodb://localhost:27017/myapp";
4
4
 
5
5
  if (!MONGODB_URI) {
6
- throw new Error('Please define the MONGODB_URI environment variable');
6
+ throw new Error("Please define the MONGODB_URI environment variable");
7
7
  }
8
8
 
9
9
  let cached = global.mongoose;
@@ -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;
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-stackkit-app",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "Create a new StackKit project with modular composition",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -51,6 +51,11 @@
51
51
  "@types/inquirer": "^9.0.7",
52
52
  "@types/node": "^20.11.0",
53
53
  "@types/validate-npm-package-name": "^4.0.2",
54
- "typescript": "^5.3.3"
54
+ "typescript": "^5.3.3",
55
+ "recast": "^0.20.5",
56
+ "@babel/core": "^7.28.5",
57
+ "@babel/plugin-transform-typescript": "^7.28.5",
58
+ "@babel/parser": "^7.28.5",
59
+ "@babel/plugin-transform-react-jsx": "^7.27.1"
55
60
  }
56
- }
61
+ }
@@ -2,6 +2,7 @@
2
2
  "name": "my-app",
3
3
  "version": "1.0.0",
4
4
  "private": true,
5
+ "type": "module",
5
6
  "scripts": {
6
7
  "dev": "tsx watch src/server.ts",
7
8
  "clean": "rimraf dist",
@@ -1,11 +1,11 @@
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';
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
9
 
10
10
  // app initialization
11
11
  const app: Application = express();
@@ -13,7 +13,7 @@ app.use(express.json());
13
13
 
14
14
  // trust proxy when behind reverse proxy (like Heroku, Vercel, Load Balancers)
15
15
  if (env.app.trust_proxy) {
16
- app.set('trust proxy', 1);
16
+ app.set("trust proxy", 1);
17
17
  }
18
18
 
19
19
  // security headers
@@ -33,9 +33,9 @@ app.use(limiter);
33
33
 
34
34
  // logging
35
35
  if (env.node.isProduction) {
36
- app.use(morgan('combined'));
36
+ app.use(morgan("combined"));
37
37
  } else {
38
- app.use(morgan('dev'));
38
+ app.use(morgan("dev"));
39
39
  }
40
40
 
41
41
  // cors configuration
@@ -43,15 +43,17 @@ app.use(
43
43
  cors({
44
44
  origin: [env.app.site_url],
45
45
  credentials: true,
46
- })
46
+ }),
47
47
  );
48
48
 
49
49
  // Home page route
50
- app.get('/', (req: Request, res: Response) => {
50
+ app.get("/", (req: Request, res: Response) => {
51
51
  res.json({
52
- title: 'StackKit - Production-ready project generator',
52
+ title: "Welcome to your Express app",
53
53
  description:
54
- 'Modern CLI tool for creating production-ready web applications with modular architecture. Build with Next.js, Express, or React.',
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",
55
57
  });
56
58
  });
57
59
 
@@ -1,22 +1,22 @@
1
- import dotenv from 'dotenv';
2
- import path from 'path';
1
+ import dotenv from "dotenv";
2
+ import path from "path";
3
3
 
4
- dotenv.config({ path: path.join(process.cwd(), '.env') });
4
+ dotenv.config({ path: path.join(process.cwd(), ".env") });
5
5
 
6
6
  const env = {
7
7
  app: {
8
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',
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
12
  rateLimit: {
13
13
  max: Number(process.env.RATE_LIMIT_MAX) || 100,
14
14
  windowMs: Number(process.env.RATE_LIMIT_WINDOW_MS) || 15 * 60 * 1000,
15
15
  },
16
16
  },
17
17
  node: {
18
- env: process.env.NODE_ENV || 'development',
19
- isProduction: (process.env.NODE_ENV || 'development') === 'production',
18
+ env: process.env.NODE_ENV || "development",
19
+ isProduction: (process.env.NODE_ENV || "development") === "production",
20
20
  },
21
21
  };
22
22
 
@@ -1,9 +1,9 @@
1
- import { NextFunction, Request, Response } from 'express';
2
- import { env } from '../config/env';
1
+ import { NextFunction, Request, Response } from "express";
2
+ import { env } from "../config/env";
3
3
 
4
4
  export const errorHandler = (err: any, req: Request, res: Response, next: NextFunction) => {
5
5
  const statusCode = err.status || 500;
6
- const errorMessage = err?.message || 'Internal server error!';
6
+ const errorMessage = err?.message || "Internal server error!";
7
7
 
8
8
  const payload: any = {
9
9
  success: false,
@@ -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
 
@@ -3,5 +3,42 @@
3
3
  "displayName": "Express.js",
4
4
  "framework": "express",
5
5
  "description": "Express.js REST API with TypeScript",
6
- "files": ["src/", ".env.example", ".gitignore", "package.json", "tsconfig.json"]
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
+ ]
7
44
  }
@@ -5,8 +5,25 @@
5
5
  "module": "ESNext",
6
6
  "moduleResolution": "node",
7
7
  "target": "ES2023",
8
+ "lib": ["ES2023"],
8
9
  "strict": true,
9
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,
10
27
  "ignoreDeprecations": "5.0"
11
28
  },
12
29
  "include": ["src/**/*"],
@@ -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
  }