create-arktos 2.0.0 → 2.0.1
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.
- package/cli/ui.js +12 -12
- package/package.json +10 -10
- package/templates/backend/eslint.config.js +1 -0
- package/templates/backend/pnpm-workspace.yaml +4 -0
- package/templates/backend/src/app.ts +3 -3
- package/templates/backend/src/controllers/auth.controller.ts +10 -1
- package/templates/backend/src/routes/auth.routes.ts +1 -1
- package/templates/backend/src/routes/index.ts +1 -1
- package/templates/backend/tsconfig.json +2 -4
package/cli/ui.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
import prompts from 'prompts'
|
|
3
|
-
import { validateProjectName } from './project-name.js'
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import prompts from 'prompts';
|
|
3
|
+
import { validateProjectName } from './project-name.js';
|
|
4
4
|
|
|
5
5
|
export function printBanner(version) {
|
|
6
6
|
console.log(`
|
|
7
7
|
${chalk.blue.bold('❄️ ARKTOS')} ${chalk.dim(`v${version}`)}
|
|
8
8
|
${chalk.gray('Production-ready Node.js & TypeScript Backend Generator')}
|
|
9
9
|
${chalk.dim('Express • JWT • Prisma ORM • PostgreSQL • Resend')}
|
|
10
|
-
`)
|
|
10
|
+
`);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export async function promptProjectName(defaultName = 'my-arktos-api') {
|
|
@@ -16,13 +16,13 @@ export async function promptProjectName(defaultName = 'my-arktos-api') {
|
|
|
16
16
|
name: 'projectName',
|
|
17
17
|
message: 'What is your backend project named?',
|
|
18
18
|
initial: defaultName,
|
|
19
|
-
validate:
|
|
20
|
-
const res = validateProjectName(val)
|
|
21
|
-
return res.isValid ? true : res.message
|
|
19
|
+
validate: val => {
|
|
20
|
+
const res = validateProjectName(val);
|
|
21
|
+
return res.isValid ? true : res.message;
|
|
22
22
|
},
|
|
23
|
-
})
|
|
23
|
+
});
|
|
24
24
|
|
|
25
|
-
return response.projectName
|
|
25
|
+
return response.projectName;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export async function promptOverwrite(targetDir) {
|
|
@@ -31,9 +31,9 @@ export async function promptOverwrite(targetDir) {
|
|
|
31
31
|
name: 'overwrite',
|
|
32
32
|
message: `Directory "${chalk.yellow(targetDir)}" already exists. Overwrite?`,
|
|
33
33
|
initial: false,
|
|
34
|
-
})
|
|
34
|
+
});
|
|
35
35
|
|
|
36
|
-
return Boolean(response.overwrite)
|
|
36
|
+
return Boolean(response.overwrite);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export function printSuccess({ projectName, targetDir, packageManager, commands }) {
|
|
@@ -50,5 +50,5 @@ export function printSuccess({ projectName, targetDir, packageManager, commands
|
|
|
50
50
|
${chalk.cyan(`6. ${commands.dev}`)} ${chalk.dim('# Start dev server at http://localhost:3001')}
|
|
51
51
|
|
|
52
52
|
${chalk.dim('Repository & issues:')} ${chalk.blue('https://github.com/zzafergok/arktos')}
|
|
53
|
-
`)
|
|
53
|
+
`);
|
|
54
54
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-arktos",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "🚀 Production-ready Node.js & TypeScript backend boilerplate generator with Express, JWT, Prisma ORM, PostgreSQL (Neon), and Resend",
|
|
6
6
|
"license": "BSL-1.1",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"LICENSE"
|
|
13
13
|
],
|
|
14
14
|
"bin": {
|
|
15
|
-
"create-arktos": "
|
|
15
|
+
"create-arktos": "index.js"
|
|
16
16
|
},
|
|
17
17
|
"engines": {
|
|
18
18
|
"node": ">=18.0.0"
|
|
@@ -22,6 +22,13 @@
|
|
|
22
22
|
"email": "gok.zaferr@gmail.com",
|
|
23
23
|
"url": "https://github.com/zzafergok"
|
|
24
24
|
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"start": "node index.js",
|
|
27
|
+
"build": "node -e 'process.exit(0)'",
|
|
28
|
+
"type-check": "node -e 'process.exit(0)'",
|
|
29
|
+
"pack:check": "node scripts/check-tarball-size.mjs",
|
|
30
|
+
"test:smoke": "node scripts/smoke-test-template.mjs"
|
|
31
|
+
},
|
|
25
32
|
"keywords": [
|
|
26
33
|
"nodejs",
|
|
27
34
|
"typescript",
|
|
@@ -70,12 +77,5 @@
|
|
|
70
77
|
"@types/fs-extra": "^11.0.4",
|
|
71
78
|
"@types/node": "^22.0.0",
|
|
72
79
|
"@types/prompts": "^2.4.9"
|
|
73
|
-
},
|
|
74
|
-
"scripts": {
|
|
75
|
-
"start": "node index.js",
|
|
76
|
-
"build": "node -e 'process.exit(0)'",
|
|
77
|
-
"type-check": "node -e 'process.exit(0)'",
|
|
78
|
-
"pack:check": "node scripts/check-tarball-size.mjs",
|
|
79
|
-
"test:smoke": "node scripts/smoke-test-template.mjs"
|
|
80
80
|
}
|
|
81
|
-
}
|
|
81
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import express from 'express';
|
|
1
|
+
import express, { Express, Request, Response } from 'express';
|
|
2
2
|
import dotenv from 'dotenv';
|
|
3
3
|
import routes from './routes';
|
|
4
4
|
import { errorHandling, securityMiddleware, rateLimiter } from './middleware';
|
|
@@ -8,7 +8,7 @@ import logger from './config/logger';
|
|
|
8
8
|
// Load environment variables
|
|
9
9
|
dotenv.config();
|
|
10
10
|
|
|
11
|
-
const app = express();
|
|
11
|
+
const app: Express = express();
|
|
12
12
|
const PORT = process.env.PORT || 3001;
|
|
13
13
|
|
|
14
14
|
// Security middleware stack
|
|
@@ -28,7 +28,7 @@ app.set('trust proxy', 1);
|
|
|
28
28
|
app.use('/api', routes);
|
|
29
29
|
|
|
30
30
|
// Health check route (outside of rate limiting)
|
|
31
|
-
app.get('/health', async (req, res) => {
|
|
31
|
+
app.get('/health', async (req: Request, res: Response) => {
|
|
32
32
|
try {
|
|
33
33
|
const dbService = DatabaseService.getInstance();
|
|
34
34
|
const dbHealth = await dbService.healthCheck();
|
|
@@ -353,7 +353,16 @@ export const logout = async (req: Request, res: Response): Promise<void> => {
|
|
|
353
353
|
|
|
354
354
|
export const verifyEmail = async (req: Request, res: Response): Promise<void> => {
|
|
355
355
|
try {
|
|
356
|
-
const
|
|
356
|
+
const rawToken = req.params.token;
|
|
357
|
+
const token = Array.isArray(rawToken) ? rawToken[0] : rawToken;
|
|
358
|
+
|
|
359
|
+
if (!token) {
|
|
360
|
+
res.status(400).json(createErrorResponse(
|
|
361
|
+
'Verification token is required',
|
|
362
|
+
ERROR_CODES.AUTH_INVALID_TOKEN
|
|
363
|
+
));
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
357
366
|
|
|
358
367
|
const verification = await prisma.emailVerification.findUnique({
|
|
359
368
|
where: { token },
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from '../controllers/auth.controller';
|
|
12
12
|
import { auth, rateLimiter } from '../middleware';
|
|
13
13
|
|
|
14
|
-
const router = Router();
|
|
14
|
+
const router: Router = Router();
|
|
15
15
|
|
|
16
16
|
// Public routes (with auth rate limiting)
|
|
17
17
|
router.post('/register', rateLimiter.auth, register);
|
|
@@ -3,7 +3,7 @@ import authRoutes from './auth.routes';
|
|
|
3
3
|
import { createSuccessResponse } from '../utils/response';
|
|
4
4
|
import DatabaseService from '../services/database.service';
|
|
5
5
|
|
|
6
|
-
const router = Router();
|
|
6
|
+
const router: Router = Router();
|
|
7
7
|
|
|
8
8
|
// Health check endpoint
|
|
9
9
|
router.get('/health', async (req: Request, res: Response) => {
|
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
"skipLibCheck": true,
|
|
11
11
|
"forceConsistentCasingInFileNames": true,
|
|
12
12
|
"resolveJsonModule": true,
|
|
13
|
-
"declaration":
|
|
14
|
-
"declarationMap": true,
|
|
13
|
+
"declaration": false,
|
|
15
14
|
"sourceMap": true,
|
|
16
15
|
"removeComments": true,
|
|
17
16
|
"noImplicitAny": true,
|
|
@@ -27,8 +26,7 @@
|
|
|
27
26
|
},
|
|
28
27
|
"allowSyntheticDefaultImports": true,
|
|
29
28
|
"experimentalDecorators": true,
|
|
30
|
-
"emitDecoratorMetadata": true
|
|
31
|
-
"typeRoots": ["./node_modules/@types"]
|
|
29
|
+
"emitDecoratorMetadata": true
|
|
32
30
|
},
|
|
33
31
|
"include": ["src/**/*"],
|
|
34
32
|
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|