@node-initializr/generator 0.1.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.
- package/dist/generate.d.ts +12 -0
- package/dist/generate.js +77 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +14 -0
- package/dist/template-engine.d.ts +24 -0
- package/dist/template-engine.js +472 -0
- package/dist/templates/arch-clean/express/src/application/use-cases/get-users.use-case.hbs +39 -0
- package/dist/templates/arch-clean/express/src/config/env.hbs +4 -0
- package/dist/templates/arch-clean/express/src/domain/entities/user.entity.hbs +7 -0
- package/dist/templates/arch-clean/express/src/index.hbs +66 -0
- package/dist/templates/arch-clean/express/src/infrastructure/http/health.routes.hbs +7 -0
- package/dist/templates/arch-clean/express/src/infrastructure/http/users.routes.hbs +9 -0
- package/dist/templates/arch-clean/express/src/shared/errors/app.error.hbs +5 -0
- package/dist/templates/arch-clean/fastify/src/application/use-cases/get-users.use-case.hbs +39 -0
- package/dist/templates/arch-clean/fastify/src/domain/entities/user.entity.hbs +7 -0
- package/dist/templates/arch-clean/fastify/src/index.hbs +53 -0
- package/dist/templates/arch-clean/fastify/src/infrastructure/http/routes.hbs +8 -0
- package/dist/templates/arch-clean/fastify/src/shared/errors/app.error.hbs +5 -0
- package/dist/templates/arch-clean/nestjs/src/app.module.ts.hbs +58 -0
- package/dist/templates/arch-clean/nestjs/src/application/use-cases/get-users.use-case.ts.hbs +14 -0
- package/dist/templates/arch-clean/nestjs/src/config/config.module.ts.hbs +4 -0
- package/dist/templates/arch-clean/nestjs/src/domain/entities/user.entity.ts.hbs +7 -0
- package/dist/templates/arch-clean/nestjs/src/domain/repositories/user.repository.ts.hbs +7 -0
- package/dist/templates/arch-clean/nestjs/src/infrastructure/http/health.controller.ts.hbs +11 -0
- package/dist/templates/arch-clean/nestjs/src/infrastructure/http/users.controller.ts.hbs +22 -0
- package/dist/templates/arch-clean/nestjs/src/infrastructure/persistence/drizzle-user.repository.ts.hbs +15 -0
- package/dist/templates/arch-clean/nestjs/src/infrastructure/persistence/in-memory-user.repository.ts.hbs +10 -0
- package/dist/templates/arch-clean/nestjs/src/infrastructure/persistence/prisma-user.repository.ts.hbs +14 -0
- package/dist/templates/arch-clean/nestjs/src/infrastructure/persistence/sequelize-user.repository.ts.hbs +18 -0
- package/dist/templates/arch-clean/nestjs/src/infrastructure/persistence/typeorm-user.repository.ts.hbs +19 -0
- package/dist/templates/arch-clean/nestjs/src/infrastructure/prisma/prisma.module.ts.hbs +6 -0
- package/dist/templates/arch-clean/nestjs/src/infrastructure/prisma/prisma.service.ts.hbs +8 -0
- package/dist/templates/arch-clean/nestjs/src/main.ts.hbs +21 -0
- package/dist/templates/arch-clean/nestjs/src/shared/errors/app.error.ts.hbs +9 -0
- package/dist/templates/arch-clean/nestjs/tests/health.spec.ts.hbs +17 -0
- package/dist/templates/arch-modular/express/src/index.hbs +46 -0
- package/dist/templates/arch-modular/express/src/infra/database.hbs +3 -0
- package/dist/templates/arch-modular/express/src/modules/health/health.routes.hbs +7 -0
- package/dist/templates/arch-modular/express/src/modules/users/users.routes.hbs +55 -0
- package/dist/templates/arch-modular/express/src/shared/constants.hbs +1 -0
- package/dist/templates/arch-modular/fastify/src/index.hbs +33 -0
- package/dist/templates/arch-modular/fastify/src/infra/database.hbs +3 -0
- package/dist/templates/arch-modular/fastify/src/modules/health/health.routes.hbs +9 -0
- package/dist/templates/arch-modular/fastify/src/modules/users/users.routes.hbs +48 -0
- package/dist/templates/arch-modular/fastify/src/shared/constants.hbs +1 -0
- package/dist/templates/arch-modular/nestjs/src/app.module.ts.hbs +63 -0
- package/dist/templates/arch-modular/nestjs/src/config/config.module.ts.hbs +4 -0
- package/dist/templates/arch-modular/nestjs/src/infra/prisma/prisma.module.ts.hbs +9 -0
- package/dist/templates/arch-modular/nestjs/src/infra/prisma/prisma.service.ts.hbs +13 -0
- package/dist/templates/arch-modular/nestjs/src/main.ts.hbs +28 -0
- package/dist/templates/arch-modular/nestjs/src/modules/health/health.controller.ts.hbs +17 -0
- package/dist/templates/arch-modular/nestjs/src/modules/health/health.module.ts.hbs +7 -0
- package/dist/templates/arch-modular/nestjs/src/modules/users/users.controller.ts.hbs +24 -0
- package/dist/templates/arch-modular/nestjs/src/modules/users/users.module.ts.hbs +10 -0
- package/dist/templates/arch-modular/nestjs/src/modules/users/users.service.ts.hbs +60 -0
- package/dist/templates/arch-modular/nestjs/src/shared/constants.ts.hbs +1 -0
- package/dist/templates/arch-modular/nestjs/tests/health.spec.ts.hbs +16 -0
- package/dist/templates/arch-mvc/express/src/controllers/health.controller.hbs +7 -0
- package/dist/templates/arch-mvc/express/src/controllers/users.controller.hbs +10 -0
- package/dist/templates/arch-mvc/express/src/index.hbs +60 -0
- package/dist/templates/arch-mvc/express/src/models/user.model.hbs +7 -0
- package/dist/templates/arch-mvc/express/src/services/users.service.hbs +39 -0
- package/dist/templates/arch-mvc/fastify/src/controllers/users.controller.hbs +9 -0
- package/dist/templates/arch-mvc/fastify/src/index.hbs +53 -0
- package/dist/templates/arch-mvc/fastify/src/models/user.model.hbs +7 -0
- package/dist/templates/arch-mvc/fastify/src/services/users.service.hbs +39 -0
- package/dist/templates/arch-mvc/nestjs/src/app.module.ts.hbs +44 -0
- package/dist/templates/arch-mvc/nestjs/src/config/config.module.ts.hbs +4 -0
- package/dist/templates/arch-mvc/nestjs/src/controllers/health.controller.ts.hbs +11 -0
- package/dist/templates/arch-mvc/nestjs/src/controllers/users.controller.ts.hbs +22 -0
- package/dist/templates/arch-mvc/nestjs/src/infra/prisma/prisma.module.ts.hbs +6 -0
- package/dist/templates/arch-mvc/nestjs/src/infra/prisma/prisma.service.ts.hbs +8 -0
- package/dist/templates/arch-mvc/nestjs/src/main.ts.hbs +21 -0
- package/dist/templates/arch-mvc/nestjs/src/models/user.model.ts.hbs +7 -0
- package/dist/templates/arch-mvc/nestjs/src/services/users.service.ts.hbs +61 -0
- package/dist/templates/arch-mvc/nestjs/tests/health.spec.ts.hbs +17 -0
- package/dist/templates/base-express/.env.example.hbs +21 -0
- package/dist/templates/base-express/.gitignore.hbs +6 -0
- package/dist/templates/base-express/README.md.hbs +10 -0
- package/dist/templates/base-express/docker/Dockerfile.hbs +21 -0
- package/dist/templates/base-express/docker/docker-compose.yml.hbs +61 -0
- package/dist/templates/base-express/drizzle/drizzle.config.hbs +10 -0
- package/dist/templates/base-express/github-actions/ci.yml.hbs +40 -0
- package/dist/templates/base-express/package.json.hbs +54 -0
- package/dist/templates/base-express/prisma/schema.prisma.hbs +16 -0
- package/dist/templates/base-express/tests/health.test.hbs +8 -0
- package/dist/templates/base-express/tsconfig.json.hbs +13 -0
- package/dist/templates/base-fastify/.env.example.hbs +21 -0
- package/dist/templates/base-fastify/.gitignore.hbs +6 -0
- package/dist/templates/base-fastify/README.md.hbs +10 -0
- package/dist/templates/base-fastify/docker/Dockerfile.hbs +21 -0
- package/dist/templates/base-fastify/docker/docker-compose.yml.hbs +61 -0
- package/dist/templates/base-fastify/drizzle/drizzle.config.hbs +10 -0
- package/dist/templates/base-fastify/github-actions/ci.yml.hbs +40 -0
- package/dist/templates/base-fastify/package.json.hbs +50 -0
- package/dist/templates/base-fastify/prisma/schema.prisma.hbs +16 -0
- package/dist/templates/base-fastify/tests/health.test.hbs +8 -0
- package/dist/templates/base-fastify/tsconfig.json.hbs +13 -0
- package/dist/templates/base-nestjs/.env.example.hbs +24 -0
- package/dist/templates/base-nestjs/.gitignore.hbs +10 -0
- package/dist/templates/base-nestjs/README.md.hbs +46 -0
- package/dist/templates/base-nestjs/docker/Dockerfile.hbs +21 -0
- package/dist/templates/base-nestjs/docker/docker-compose.yml.hbs +69 -0
- package/dist/templates/base-nestjs/drizzle/drizzle.config.ts.hbs +10 -0
- package/dist/templates/base-nestjs/github-actions/ci.yml.hbs +38 -0
- package/dist/templates/base-nestjs/nest-cli.json.hbs +8 -0
- package/dist/templates/base-nestjs/package.json.hbs +65 -0
- package/dist/templates/base-nestjs/prisma/schema.prisma.hbs +16 -0
- package/dist/templates/base-nestjs/tsconfig.json.hbs +19 -0
- package/dist/templates/shared-express/src/infra/auth/clerk.middleware.hbs +12 -0
- package/dist/templates/shared-express/src/infra/auth/jwt.middleware.hbs +18 -0
- package/dist/templates/shared-express/src/infra/drizzle/client.hbs +18 -0
- package/dist/templates/shared-express/src/infra/drizzle/schema.hbs +22 -0
- package/dist/templates/shared-express/src/infra/prisma/client.hbs +15 -0
- package/dist/templates/shared-express/src/infra/sequelize/models/user.model.ts.hbs +22 -0
- package/dist/templates/shared-express/src/infra/sequelize/sequelize.ts.hbs +16 -0
- package/dist/templates/shared-express/src/infra/swagger/setup.hbs +19 -0
- package/dist/templates/shared-express/src/infra/typeorm/data-source.hbs +17 -0
- package/dist/templates/shared-express/src/infra/typeorm/entities/user.entity.hbs +25 -0
- package/dist/templates/shared-fastify/src/infra/auth/clerk.middleware.hbs +16 -0
- package/dist/templates/shared-fastify/src/infra/auth/jwt.middleware.hbs +14 -0
- package/dist/templates/shared-fastify/src/infra/drizzle/client.hbs +18 -0
- package/dist/templates/shared-fastify/src/infra/drizzle/schema.hbs +22 -0
- package/dist/templates/shared-fastify/src/infra/prisma/client.hbs +15 -0
- package/dist/templates/shared-fastify/src/infra/sequelize/models/user.model.ts.hbs +22 -0
- package/dist/templates/shared-fastify/src/infra/sequelize/sequelize.ts.hbs +16 -0
- package/dist/templates/shared-fastify/src/infra/swagger/setup.hbs +16 -0
- package/dist/templates/shared-fastify/src/infra/typeorm/data-source.hbs +17 -0
- package/dist/templates/shared-fastify/src/infra/typeorm/entities/user.entity.hbs +25 -0
- package/dist/templates/shared-nestjs/src/infra/auth/clerk/clerk-auth.guard.ts.hbs +25 -0
- package/dist/templates/shared-nestjs/src/infra/auth/jwt/jwt-auth.guard.ts.hbs +5 -0
- package/dist/templates/shared-nestjs/src/infra/auth/jwt/jwt.module.ts.hbs +17 -0
- package/dist/templates/shared-nestjs/src/infra/auth/jwt/jwt.strategy.ts.hbs +18 -0
- package/dist/templates/shared-nestjs/src/infra/drizzle/drizzle.module.ts.hbs +9 -0
- package/dist/templates/shared-nestjs/src/infra/drizzle/drizzle.service.ts.hbs +31 -0
- package/dist/templates/shared-nestjs/src/infra/drizzle/schema.ts.hbs +22 -0
- package/dist/templates/shared-nestjs/src/infra/sequelize/models/user.model.ts.hbs +22 -0
- package/dist/templates/shared-nestjs/src/infra/sequelize/sequelize.module.ts.hbs +18 -0
- package/dist/templates/shared-nestjs/src/infra/typeorm/entities/user.entity.ts.hbs +25 -0
- package/dist/templates/shared-nestjs/src/infra/typeorm/typeorm.module.ts.hbs +18 -0
- package/dist/templates/shared-nestjs/src/infrastructure/drizzle/drizzle.module.ts.hbs +9 -0
- package/dist/templates/shared-nestjs/src/infrastructure/drizzle/drizzle.service.ts.hbs +31 -0
- package/dist/templates/shared-nestjs/src/infrastructure/drizzle/schema.ts.hbs +22 -0
- package/dist/templates/shared-nestjs/src/infrastructure/sequelize/models/user.model.ts.hbs +22 -0
- package/dist/templates/shared-nestjs/src/infrastructure/sequelize/sequelize.module.ts.hbs +18 -0
- package/dist/templates/shared-nestjs/src/infrastructure/typeorm/entities/user.entity.ts.hbs +25 -0
- package/dist/templates/shared-nestjs/src/infrastructure/typeorm/typeorm.module.ts.hbs +18 -0
- package/dist/validate.d.ts +2 -0
- package/dist/validate.js +41 -0
- package/dist/zip.d.ts +2 -0
- package/dist/zip.js +20 -0
- package/package.json +37 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import cors from 'cors';
|
|
4
|
+
import helmet from 'helmet';
|
|
5
|
+
import { GetUsersUseCase } from './application/use-cases/get-users.use-case.js';
|
|
6
|
+
{{#if useTypeorm}}
|
|
7
|
+
import { initTypeorm } from './infra/typeorm/data-source.js';
|
|
8
|
+
{{/if}}
|
|
9
|
+
{{#if useSequelize}}
|
|
10
|
+
import { initSequelize } from './infra/sequelize/sequelize.js';
|
|
11
|
+
{{/if}}
|
|
12
|
+
{{#if swagger}}
|
|
13
|
+
import { setupSwagger } from './infra/swagger/setup.js';
|
|
14
|
+
{{/if}}
|
|
15
|
+
{{#if useJwt}}
|
|
16
|
+
import { jwtMiddleware } from './infra/auth/jwt.middleware.js';
|
|
17
|
+
{{/if}}
|
|
18
|
+
{{#if useClerk}}
|
|
19
|
+
import { clerkAuth, requireClerkAuth } from './infra/auth/clerk.middleware.js';
|
|
20
|
+
{{/if}}
|
|
21
|
+
|
|
22
|
+
async function bootstrap() {
|
|
23
|
+
{{#if useTypeorm}}
|
|
24
|
+
await initTypeorm();
|
|
25
|
+
{{/if}}
|
|
26
|
+
{{#if useSequelize}}
|
|
27
|
+
await initSequelize();
|
|
28
|
+
{{/if}}
|
|
29
|
+
|
|
30
|
+
const app = express();
|
|
31
|
+
const getUsers = new GetUsersUseCase();
|
|
32
|
+
|
|
33
|
+
app.use(helmet());
|
|
34
|
+
app.use(cors());
|
|
35
|
+
app.use(express.json());
|
|
36
|
+
{{#if useClerk}}
|
|
37
|
+
app.use(clerkAuth);
|
|
38
|
+
{{/if}}
|
|
39
|
+
{{#if swagger}}
|
|
40
|
+
setupSwagger(app);
|
|
41
|
+
{{/if}}
|
|
42
|
+
|
|
43
|
+
app.get('/api/health', (_req, res) => {
|
|
44
|
+
res.json({ status: 'ok', service: '{{projectSlug}}', architecture: 'clean' });
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const usersHandler = async (_req: express.Request, res: express.Response) => {
|
|
48
|
+
const users = await getUsers.execute();
|
|
49
|
+
res.json(users);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
{{#if useJwt}}
|
|
53
|
+
app.get('/api/users', jwtMiddleware, usersHandler);
|
|
54
|
+
{{else}}
|
|
55
|
+
{{#if useClerk}}
|
|
56
|
+
app.get('/api/users', requireClerkAuth, usersHandler);
|
|
57
|
+
{{else}}
|
|
58
|
+
app.get('/api/users', usersHandler);
|
|
59
|
+
{{/if}}
|
|
60
|
+
{{/if}}
|
|
61
|
+
|
|
62
|
+
const port = process.env.PORT ?? 3000;
|
|
63
|
+
app.listen(port, () => console.log(`🚀 {{projectSlug}} (clean) on :${port}`));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
bootstrap();
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { GetUsersUseCase } from '../../application/use-cases/get-users.use-case.js';
|
|
3
|
+
|
|
4
|
+
const getUsers = new GetUsersUseCase();
|
|
5
|
+
export const usersRouter = Router();
|
|
6
|
+
|
|
7
|
+
usersRouter.get('/', async (_req, res) => {
|
|
8
|
+
res.json(await getUsers.execute());
|
|
9
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { User } from '../../domain/entities/user.entity.js';
|
|
2
|
+
{{#if usePrisma}}
|
|
3
|
+
import { prisma } from '../../infra/prisma/client.js';
|
|
4
|
+
{{/if}}
|
|
5
|
+
{{#if useTypeorm}}
|
|
6
|
+
import { AppDataSource } from '../../infra/typeorm/data-source.js';
|
|
7
|
+
import { UserEntity } from '../../infra/typeorm/entities/user.entity.js';
|
|
8
|
+
{{/if}}
|
|
9
|
+
{{#if useDrizzle}}
|
|
10
|
+
import { db } from '../../infra/drizzle/client.js';
|
|
11
|
+
import { users } from '../../infra/drizzle/schema.js';
|
|
12
|
+
{{/if}}
|
|
13
|
+
{{#if useSequelize}}
|
|
14
|
+
import { User } from '../../infra/sequelize/models/user.model.js';
|
|
15
|
+
{{/if}}
|
|
16
|
+
|
|
17
|
+
export class GetUsersUseCase {
|
|
18
|
+
async execute(): Promise<User[]> {
|
|
19
|
+
{{#if usePrisma}}
|
|
20
|
+
const rows = await prisma.user.findMany();
|
|
21
|
+
return rows.map((r) => new User(r.id, r.email, r.name ?? ''));
|
|
22
|
+
{{/if}}
|
|
23
|
+
{{#if useTypeorm}}
|
|
24
|
+
const rows = await AppDataSource.getRepository(UserEntity).find();
|
|
25
|
+
return rows.map((r) => new User(r.id, r.email, r.name ?? ''));
|
|
26
|
+
{{/if}}
|
|
27
|
+
{{#if useDrizzle}}
|
|
28
|
+
const rows = await db.select().from(users);
|
|
29
|
+
return rows.map((r) => new User(r.id, r.email, r.name ?? ''));
|
|
30
|
+
{{/if}}
|
|
31
|
+
{{#if useSequelize}}
|
|
32
|
+
const rows = await User.findAll();
|
|
33
|
+
return rows.map((r) => new User(r.id, r.email, r.name ?? ''));
|
|
34
|
+
{{/if}}
|
|
35
|
+
{{#unless hasRealOrm}}
|
|
36
|
+
return [new User('1', 'user@example.com', 'Demo User')];
|
|
37
|
+
{{/unless}}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import Fastify from 'fastify';
|
|
3
|
+
import cors from '@fastify/cors';
|
|
4
|
+
import helmet from '@fastify/helmet';
|
|
5
|
+
import { GetUsersUseCase } from './application/use-cases/get-users.use-case.js';
|
|
6
|
+
{{#if useTypeorm}}
|
|
7
|
+
import { initTypeorm } from './infra/typeorm/data-source.js';
|
|
8
|
+
{{/if}}
|
|
9
|
+
{{#if useSequelize}}
|
|
10
|
+
import { initSequelize } from './infra/sequelize/sequelize.js';
|
|
11
|
+
{{/if}}
|
|
12
|
+
{{#if swagger}}
|
|
13
|
+
import { setupSwagger } from './infra/swagger/setup.js';
|
|
14
|
+
{{/if}}
|
|
15
|
+
{{#if useJwt}}
|
|
16
|
+
import { jwtMiddleware } from './infra/auth/jwt.middleware.js';
|
|
17
|
+
{{/if}}
|
|
18
|
+
{{#if useClerk}}
|
|
19
|
+
import { clerkMiddleware } from './infra/auth/clerk.middleware.js';
|
|
20
|
+
{{/if}}
|
|
21
|
+
|
|
22
|
+
{{#if useTypeorm}}
|
|
23
|
+
await initTypeorm();
|
|
24
|
+
{{/if}}
|
|
25
|
+
{{#if useSequelize}}
|
|
26
|
+
await initSequelize();
|
|
27
|
+
{{/if}}
|
|
28
|
+
|
|
29
|
+
const app = Fastify({ logger: true });
|
|
30
|
+
const getUsers = new GetUsersUseCase();
|
|
31
|
+
|
|
32
|
+
await app.register(cors);
|
|
33
|
+
await app.register(helmet);
|
|
34
|
+
{{#if swagger}}
|
|
35
|
+
await setupSwagger(app);
|
|
36
|
+
{{/if}}
|
|
37
|
+
|
|
38
|
+
app.get('/api/health', async () => ({
|
|
39
|
+
status: 'ok',
|
|
40
|
+
service: '{{projectSlug}}',
|
|
41
|
+
architecture: 'clean',
|
|
42
|
+
}));
|
|
43
|
+
|
|
44
|
+
app.get('/api/users', {
|
|
45
|
+
{{#if useJwt}}
|
|
46
|
+
preHandler: jwtMiddleware,
|
|
47
|
+
{{/if}}
|
|
48
|
+
{{#if useClerk}}
|
|
49
|
+
preHandler: clerkMiddleware,
|
|
50
|
+
{{/if}}
|
|
51
|
+
}, async () => getUsers.execute());
|
|
52
|
+
|
|
53
|
+
await app.listen({ port: Number(process.env.PORT ?? 3000), host: '0.0.0.0' });
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FastifyInstance } from 'fastify';
|
|
2
|
+
import { GetUsersUseCase } from '../../application/use-cases/get-users.use-case.js';
|
|
3
|
+
|
|
4
|
+
export async function registerRoutes(app: FastifyInstance) {
|
|
5
|
+
const getUsers = new GetUsersUseCase();
|
|
6
|
+
|
|
7
|
+
app.get('/api/users', async () => getUsers.execute());
|
|
8
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { ConfigModule } from './config/config.module';
|
|
3
|
+
import { GetUsersUseCase } from './application/use-cases/get-users.use-case';
|
|
4
|
+
import { HealthController } from './infrastructure/http/health.controller';
|
|
5
|
+
import { UsersController } from './infrastructure/http/users.controller';
|
|
6
|
+
import { USER_REPOSITORY } from './domain/repositories/user.repository';
|
|
7
|
+
{{#if usePrisma}}
|
|
8
|
+
import { PrismaModule } from './infrastructure/prisma/prisma.module';
|
|
9
|
+
import { PrismaUserRepository } from './infrastructure/persistence/prisma-user.repository';
|
|
10
|
+
{{/if}}
|
|
11
|
+
{{#if useTypeorm}}
|
|
12
|
+
import { TypeormModule } from './infrastructure/typeorm/typeorm.module';
|
|
13
|
+
import { TypeormUserRepository } from './infrastructure/persistence/typeorm-user.repository';
|
|
14
|
+
{{/if}}
|
|
15
|
+
{{#if useDrizzle}}
|
|
16
|
+
import { DrizzleModule } from './infrastructure/drizzle/drizzle.module';
|
|
17
|
+
import { DrizzleUserRepository } from './infrastructure/persistence/drizzle-user.repository';
|
|
18
|
+
{{/if}}
|
|
19
|
+
{{#if useSequelize}}
|
|
20
|
+
import { SequelizeModule } from './infrastructure/sequelize/sequelize.module';
|
|
21
|
+
import { SequelizeUserRepository } from './infrastructure/persistence/sequelize-user.repository';
|
|
22
|
+
{{/if}}
|
|
23
|
+
{{#unless hasRealOrm}}
|
|
24
|
+
import { InMemoryUserRepository } from './infrastructure/persistence/in-memory-user.repository';
|
|
25
|
+
{{/unless}}
|
|
26
|
+
{{#if useJwt}}
|
|
27
|
+
import { AuthJwtModule } from './infra/auth/jwt/jwt.module';
|
|
28
|
+
{{/if}}
|
|
29
|
+
|
|
30
|
+
@Module({
|
|
31
|
+
imports: [
|
|
32
|
+
ConfigModule,
|
|
33
|
+
{{#if usePrisma}}
|
|
34
|
+
PrismaModule,
|
|
35
|
+
{{/if}}
|
|
36
|
+
{{#if useTypeorm}}
|
|
37
|
+
TypeormModule,
|
|
38
|
+
{{/if}}
|
|
39
|
+
{{#if useDrizzle}}
|
|
40
|
+
DrizzleModule,
|
|
41
|
+
{{/if}}
|
|
42
|
+
{{#if useSequelize}}
|
|
43
|
+
SequelizeModule,
|
|
44
|
+
{{/if}}
|
|
45
|
+
{{#if useJwt}}
|
|
46
|
+
AuthJwtModule,
|
|
47
|
+
{{/if}}
|
|
48
|
+
],
|
|
49
|
+
controllers: [HealthController, UsersController],
|
|
50
|
+
providers: [
|
|
51
|
+
GetUsersUseCase,
|
|
52
|
+
{
|
|
53
|
+
provide: USER_REPOSITORY,
|
|
54
|
+
useClass: {{#if usePrisma}}PrismaUserRepository{{/if}}{{#if useTypeorm}}TypeormUserRepository{{/if}}{{#if useDrizzle}}DrizzleUserRepository{{/if}}{{#if useSequelize}}SequelizeUserRepository{{/if}}{{#unless hasRealOrm}}InMemoryUserRepository{{/unless}},
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
})
|
|
58
|
+
export class AppModule {}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Inject, Injectable } from '@nestjs/common';
|
|
2
|
+
import { User } from '../../domain/entities/user.entity';
|
|
3
|
+
import { USER_REPOSITORY, UserRepository } from '../../domain/repositories/user.repository';
|
|
4
|
+
|
|
5
|
+
@Injectable()
|
|
6
|
+
export class GetUsersUseCase {
|
|
7
|
+
constructor(
|
|
8
|
+
@Inject(USER_REPOSITORY) private readonly users: UserRepository,
|
|
9
|
+
) {}
|
|
10
|
+
|
|
11
|
+
execute(): Promise<User[]> {
|
|
12
|
+
return this.users.findAll();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Controller, Get } from '@nestjs/common';
|
|
2
|
+
{{#if swagger}}import { ApiTags } from '@nestjs/swagger';{{/if}}
|
|
3
|
+
|
|
4
|
+
{{#if swagger}}@ApiTags('health'){{/if}}
|
|
5
|
+
@Controller('health')
|
|
6
|
+
export class HealthController {
|
|
7
|
+
@Get()
|
|
8
|
+
check() {
|
|
9
|
+
return { status: 'ok', service: '{{projectSlug}}', architecture: 'clean' };
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Controller, Get{{#if useJwt}}, UseGuards{{/if}}{{#if useClerk}}, UseGuards{{/if}} } from '@nestjs/common';
|
|
2
|
+
import { GetUsersUseCase } from '../../application/use-cases/get-users.use-case';
|
|
3
|
+
{{#if swagger}}import { ApiTags } from '@nestjs/swagger';{{/if}}
|
|
4
|
+
{{#if useJwt}}
|
|
5
|
+
import { JwtAuthGuard } from '../../infra/auth/jwt/jwt-auth.guard';
|
|
6
|
+
{{/if}}
|
|
7
|
+
{{#if useClerk}}
|
|
8
|
+
import { ClerkAuthGuard } from '../../infra/auth/clerk/clerk-auth.guard';
|
|
9
|
+
{{/if}}
|
|
10
|
+
|
|
11
|
+
{{#if swagger}}@ApiTags('users'){{/if}}
|
|
12
|
+
@Controller('users')
|
|
13
|
+
{{#if useJwt}}@UseGuards(JwtAuthGuard){{/if}}
|
|
14
|
+
{{#if useClerk}}@UseGuards(ClerkAuthGuard){{/if}}
|
|
15
|
+
export class UsersController {
|
|
16
|
+
constructor(private readonly getUsers: GetUsersUseCase) {}
|
|
17
|
+
|
|
18
|
+
@Get()
|
|
19
|
+
findAll() {
|
|
20
|
+
return this.getUsers.execute();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { User } from '../../domain/entities/user.entity';
|
|
3
|
+
import { UserRepository } from '../../domain/repositories/user.repository';
|
|
4
|
+
import { DrizzleService } from '../drizzle/drizzle.service';
|
|
5
|
+
import { users } from '../drizzle/schema';
|
|
6
|
+
|
|
7
|
+
@Injectable()
|
|
8
|
+
export class DrizzleUserRepository implements UserRepository {
|
|
9
|
+
constructor(private readonly drizzle: DrizzleService) {}
|
|
10
|
+
|
|
11
|
+
async findAll(): Promise<User[]> {
|
|
12
|
+
const rows = await this.drizzle.db.select().from(users);
|
|
13
|
+
return rows.map((r) => new User(r.id, r.email, r.name ?? ''));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { User } from '../../domain/entities/user.entity';
|
|
3
|
+
import { UserRepository } from '../../domain/repositories/user.repository';
|
|
4
|
+
|
|
5
|
+
@Injectable()
|
|
6
|
+
export class InMemoryUserRepository implements UserRepository {
|
|
7
|
+
async findAll(): Promise<User[]> {
|
|
8
|
+
return [new User('1', 'user@example.com', 'Demo User')];
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { User } from '../../domain/entities/user.entity';
|
|
3
|
+
import { UserRepository } from '../../domain/repositories/user.repository';
|
|
4
|
+
import { PrismaService } from '../prisma/prisma.service';
|
|
5
|
+
|
|
6
|
+
@Injectable()
|
|
7
|
+
export class PrismaUserRepository implements UserRepository {
|
|
8
|
+
constructor(private readonly prisma: PrismaService) {}
|
|
9
|
+
|
|
10
|
+
async findAll(): Promise<User[]> {
|
|
11
|
+
const rows = await this.prisma.user.findMany();
|
|
12
|
+
return rows.map((r) => new User(r.id, r.email, r.name));
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { InjectModel } from '@nestjs/sequelize';
|
|
3
|
+
import { User as DomainUser } from '../../domain/entities/user.entity';
|
|
4
|
+
import { UserRepository } from '../../domain/repositories/user.repository';
|
|
5
|
+
import { User } from '../sequelize/models/user.model';
|
|
6
|
+
|
|
7
|
+
@Injectable()
|
|
8
|
+
export class SequelizeUserRepository implements UserRepository {
|
|
9
|
+
constructor(
|
|
10
|
+
@InjectModel(User)
|
|
11
|
+
private readonly userModel: typeof User,
|
|
12
|
+
) {}
|
|
13
|
+
|
|
14
|
+
async findAll(): Promise<DomainUser[]> {
|
|
15
|
+
const rows = await this.userModel.findAll();
|
|
16
|
+
return rows.map((r) => new DomainUser(r.id, r.email, r.name ?? ''));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { InjectRepository } from '@nestjs/typeorm';
|
|
3
|
+
import { Repository } from 'typeorm';
|
|
4
|
+
import { User } from '../../domain/entities/user.entity';
|
|
5
|
+
import { UserRepository } from '../../domain/repositories/user.repository';
|
|
6
|
+
import { UserEntity } from '../typeorm/entities/user.entity';
|
|
7
|
+
|
|
8
|
+
@Injectable()
|
|
9
|
+
export class TypeormUserRepository implements UserRepository {
|
|
10
|
+
constructor(
|
|
11
|
+
@InjectRepository(UserEntity)
|
|
12
|
+
private readonly repo: Repository<UserEntity>,
|
|
13
|
+
) {}
|
|
14
|
+
|
|
15
|
+
async findAll(): Promise<User[]> {
|
|
16
|
+
const rows = await this.repo.find();
|
|
17
|
+
return rows.map((r) => new User(r.id, r.email, r.name ?? ''));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
|
2
|
+
import { PrismaClient } from '@prisma/client';
|
|
3
|
+
|
|
4
|
+
@Injectable()
|
|
5
|
+
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
|
|
6
|
+
async onModuleInit() { await this.$connect(); }
|
|
7
|
+
async onModuleDestroy() { await this.$disconnect(); }
|
|
8
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{{#if useReflectMetadata}}import 'reflect-metadata';
|
|
2
|
+
{{/if}}import { NestFactory } from '@nestjs/core';
|
|
3
|
+
import { AppModule } from './app.module';
|
|
4
|
+
{{#if swagger}}
|
|
5
|
+
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
|
6
|
+
{{/if}}
|
|
7
|
+
|
|
8
|
+
async function bootstrap() {
|
|
9
|
+
const app = await NestFactory.create(AppModule);
|
|
10
|
+
app.setGlobalPrefix('api');
|
|
11
|
+
{{#if swagger}}
|
|
12
|
+
const config = new DocumentBuilder()
|
|
13
|
+
.setTitle('{{projectSlug}}')
|
|
14
|
+
.setDescription('{{description}}')
|
|
15
|
+
.setVersion('1.0')
|
|
16
|
+
.build();
|
|
17
|
+
SwaggerModule.setup('docs', app, SwaggerModule.createDocument(app, config));
|
|
18
|
+
{{/if}}
|
|
19
|
+
await app.listen(process.env.PORT ?? 3000);
|
|
20
|
+
}
|
|
21
|
+
bootstrap();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Test } from '@nestjs/testing';
|
|
2
|
+
import { HealthController } from '../src/infrastructure/http/health.controller';
|
|
3
|
+
|
|
4
|
+
describe('HealthController', () => {
|
|
5
|
+
it('should return ok status', async () => {
|
|
6
|
+
const module = await Test.createTestingModule({
|
|
7
|
+
controllers: [HealthController],
|
|
8
|
+
}).compile();
|
|
9
|
+
|
|
10
|
+
const controller = module.get(HealthController);
|
|
11
|
+
const result = controller.check();
|
|
12
|
+
|
|
13
|
+
expect(result.status).toBe('ok');
|
|
14
|
+
expect(result.service).toBe('{{projectSlug}}');
|
|
15
|
+
expect(result.architecture).toBe('clean');
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import cors from 'cors';
|
|
4
|
+
import helmet from 'helmet';
|
|
5
|
+
import { healthRouter } from './modules/health/health.routes.js';
|
|
6
|
+
import { usersRouter } from './modules/users/users.routes.js';
|
|
7
|
+
{{#if useTypeorm}}
|
|
8
|
+
import { initTypeorm } from './infra/typeorm/data-source.js';
|
|
9
|
+
{{/if}}
|
|
10
|
+
{{#if useSequelize}}
|
|
11
|
+
import { initSequelize } from './infra/sequelize/sequelize.js';
|
|
12
|
+
{{/if}}
|
|
13
|
+
{{#if swagger}}
|
|
14
|
+
import { setupSwagger } from './infra/swagger/setup.js';
|
|
15
|
+
{{/if}}
|
|
16
|
+
{{#if useClerk}}
|
|
17
|
+
import { clerkAuth } from './infra/auth/clerk.middleware.js';
|
|
18
|
+
{{/if}}
|
|
19
|
+
|
|
20
|
+
async function bootstrap() {
|
|
21
|
+
{{#if useTypeorm}}
|
|
22
|
+
await initTypeorm();
|
|
23
|
+
{{/if}}
|
|
24
|
+
{{#if useSequelize}}
|
|
25
|
+
await initSequelize();
|
|
26
|
+
{{/if}}
|
|
27
|
+
|
|
28
|
+
const app = express();
|
|
29
|
+
app.use(helmet());
|
|
30
|
+
app.use(cors());
|
|
31
|
+
app.use(express.json());
|
|
32
|
+
{{#if useClerk}}
|
|
33
|
+
app.use(clerkAuth);
|
|
34
|
+
{{/if}}
|
|
35
|
+
{{#if swagger}}
|
|
36
|
+
setupSwagger(app);
|
|
37
|
+
{{/if}}
|
|
38
|
+
|
|
39
|
+
app.use('/api/health', healthRouter);
|
|
40
|
+
app.use('/api/users', usersRouter);
|
|
41
|
+
|
|
42
|
+
const port = process.env.PORT ?? 3000;
|
|
43
|
+
app.listen(port, () => console.log(`🚀 {{projectSlug}} (modular) on :${port}`));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
bootstrap();
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
{{#if usePrisma}}
|
|
3
|
+
import { prisma } from '../../infra/prisma/client.js';
|
|
4
|
+
{{/if}}
|
|
5
|
+
{{#if useTypeorm}}
|
|
6
|
+
import { AppDataSource } from '../../infra/typeorm/data-source.js';
|
|
7
|
+
import { UserEntity } from '../../infra/typeorm/entities/user.entity.js';
|
|
8
|
+
{{/if}}
|
|
9
|
+
{{#if useDrizzle}}
|
|
10
|
+
import { db } from '../../infra/drizzle/client.js';
|
|
11
|
+
import { users } from '../../infra/drizzle/schema.js';
|
|
12
|
+
{{/if}}
|
|
13
|
+
{{#if useSequelize}}
|
|
14
|
+
import { User } from '../../infra/sequelize/models/user.model.js';
|
|
15
|
+
{{/if}}
|
|
16
|
+
{{#if useJwt}}
|
|
17
|
+
import { jwtMiddleware } from '../../infra/auth/jwt.middleware.js';
|
|
18
|
+
{{/if}}
|
|
19
|
+
{{#if useClerk}}
|
|
20
|
+
import { requireClerkAuth } from '../../infra/auth/clerk.middleware.js';
|
|
21
|
+
{{/if}}
|
|
22
|
+
|
|
23
|
+
export const usersRouter = Router();
|
|
24
|
+
|
|
25
|
+
const listUsers = async (_req: import('express').Request, res: import('express').Response) => {
|
|
26
|
+
{{#if usePrisma}}
|
|
27
|
+
const rows = await prisma.user.findMany();
|
|
28
|
+
res.json(rows);
|
|
29
|
+
{{/if}}
|
|
30
|
+
{{#if useTypeorm}}
|
|
31
|
+
const rows = await AppDataSource.getRepository(UserEntity).find();
|
|
32
|
+
res.json(rows);
|
|
33
|
+
{{/if}}
|
|
34
|
+
{{#if useDrizzle}}
|
|
35
|
+
const rows = await db.select().from(users);
|
|
36
|
+
res.json(rows);
|
|
37
|
+
{{/if}}
|
|
38
|
+
{{#if useSequelize}}
|
|
39
|
+
const rows = await User.findAll();
|
|
40
|
+
res.json(rows);
|
|
41
|
+
{{/if}}
|
|
42
|
+
{{#unless hasRealOrm}}
|
|
43
|
+
res.json([{ id: '1', email: 'user@example.com', name: 'Demo User' }]);
|
|
44
|
+
{{/unless}}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
{{#if useJwt}}
|
|
48
|
+
usersRouter.get('/', jwtMiddleware, listUsers);
|
|
49
|
+
{{else}}
|
|
50
|
+
{{#if useClerk}}
|
|
51
|
+
usersRouter.get('/', requireClerkAuth, listUsers);
|
|
52
|
+
{{else}}
|
|
53
|
+
usersRouter.get('/', listUsers);
|
|
54
|
+
{{/if}}
|
|
55
|
+
{{/if}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const APP_NAME = '{{projectSlug}}';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import Fastify from 'fastify';
|
|
3
|
+
import cors from '@fastify/cors';
|
|
4
|
+
import helmet from '@fastify/helmet';
|
|
5
|
+
import { healthRoutes } from './modules/health/health.routes.js';
|
|
6
|
+
import { usersRoutes } from './modules/users/users.routes.js';
|
|
7
|
+
{{#if useTypeorm}}
|
|
8
|
+
import { initTypeorm } from './infra/typeorm/data-source.js';
|
|
9
|
+
{{/if}}
|
|
10
|
+
{{#if useSequelize}}
|
|
11
|
+
import { initSequelize } from './infra/sequelize/sequelize.js';
|
|
12
|
+
{{/if}}
|
|
13
|
+
{{#if swagger}}
|
|
14
|
+
import { setupSwagger } from './infra/swagger/setup.js';
|
|
15
|
+
{{/if}}
|
|
16
|
+
|
|
17
|
+
{{#if useTypeorm}}
|
|
18
|
+
await initTypeorm();
|
|
19
|
+
{{/if}}
|
|
20
|
+
{{#if useSequelize}}
|
|
21
|
+
await initSequelize();
|
|
22
|
+
{{/if}}
|
|
23
|
+
|
|
24
|
+
const app = Fastify({ logger: true });
|
|
25
|
+
await app.register(cors);
|
|
26
|
+
await app.register(helmet);
|
|
27
|
+
{{#if swagger}}
|
|
28
|
+
await setupSwagger(app);
|
|
29
|
+
{{/if}}
|
|
30
|
+
await app.register(healthRoutes);
|
|
31
|
+
await app.register(usersRoutes);
|
|
32
|
+
|
|
33
|
+
await app.listen({ port: Number(process.env.PORT ?? 3000), host: '0.0.0.0' });
|