@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,16 @@
|
|
|
1
|
+
import fastifySwagger from '@fastify/swagger';
|
|
2
|
+
import fastifySwaggerUi from '@fastify/swagger-ui';
|
|
3
|
+
import type { FastifyInstance } from 'fastify';
|
|
4
|
+
|
|
5
|
+
export async function setupSwagger(app: FastifyInstance) {
|
|
6
|
+
await app.register(fastifySwagger, {
|
|
7
|
+
openapi: {
|
|
8
|
+
info: {
|
|
9
|
+
title: '{{projectSlug}}',
|
|
10
|
+
description: '{{description}}',
|
|
11
|
+
version: '1.0.0',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
await app.register(fastifySwaggerUi, { routePrefix: '/docs' });
|
|
16
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { DataSource } from 'typeorm';
|
|
3
|
+
import { UserEntity } from './entities/user.entity.js';
|
|
4
|
+
|
|
5
|
+
export const AppDataSource = new DataSource({
|
|
6
|
+
type: '{{typeormDriver}}',
|
|
7
|
+
url: process.env.DATABASE_URL,
|
|
8
|
+
entities: [UserEntity],
|
|
9
|
+
synchronize: process.env.NODE_ENV !== 'production',
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export async function initTypeorm() {
|
|
13
|
+
if (!AppDataSource.isInitialized) {
|
|
14
|
+
await AppDataSource.initialize();
|
|
15
|
+
}
|
|
16
|
+
return AppDataSource;
|
|
17
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Column,
|
|
3
|
+
CreateDateColumn,
|
|
4
|
+
Entity,
|
|
5
|
+
PrimaryGeneratedColumn,
|
|
6
|
+
UpdateDateColumn,
|
|
7
|
+
} from 'typeorm';
|
|
8
|
+
|
|
9
|
+
@Entity('users')
|
|
10
|
+
export class UserEntity {
|
|
11
|
+
@PrimaryGeneratedColumn('uuid')
|
|
12
|
+
id!: string;
|
|
13
|
+
|
|
14
|
+
@Column({ unique: true })
|
|
15
|
+
email!: string;
|
|
16
|
+
|
|
17
|
+
@Column({ nullable: true })
|
|
18
|
+
name!: string | null;
|
|
19
|
+
|
|
20
|
+
@CreateDateColumn()
|
|
21
|
+
createdAt!: Date;
|
|
22
|
+
|
|
23
|
+
@UpdateDateColumn()
|
|
24
|
+
updatedAt!: Date;
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common';
|
|
2
|
+
import { createClerkClient } from '@clerk/clerk-sdk-node';
|
|
3
|
+
|
|
4
|
+
@Injectable()
|
|
5
|
+
export class ClerkAuthGuard implements CanActivate {
|
|
6
|
+
private readonly clerk = createClerkClient({
|
|
7
|
+
secretKey: process.env.CLERK_SECRET_KEY,
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
11
|
+
const request = context.switchToHttp().getRequest();
|
|
12
|
+
const token = request.headers.authorization?.replace('Bearer ', '');
|
|
13
|
+
|
|
14
|
+
if (!token) {
|
|
15
|
+
throw new UnauthorizedException('Missing Clerk token');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
request.user = await this.clerk.verifyToken(token);
|
|
20
|
+
return true;
|
|
21
|
+
} catch {
|
|
22
|
+
throw new UnauthorizedException('Invalid Clerk token');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { JwtModule } from '@nestjs/jwt';
|
|
3
|
+
import { PassportModule } from '@nestjs/passport';
|
|
4
|
+
import { JwtStrategy } from './jwt.strategy';
|
|
5
|
+
|
|
6
|
+
@Module({
|
|
7
|
+
imports: [
|
|
8
|
+
PassportModule.register({ defaultStrategy: 'jwt' }),
|
|
9
|
+
JwtModule.register({
|
|
10
|
+
secret: process.env.JWT_SECRET ?? 'change-me',
|
|
11
|
+
signOptions: { expiresIn: process.env.JWT_EXPIRES_IN ?? '7d' },
|
|
12
|
+
}),
|
|
13
|
+
],
|
|
14
|
+
providers: [JwtStrategy],
|
|
15
|
+
exports: [JwtModule, PassportModule],
|
|
16
|
+
})
|
|
17
|
+
export class AuthJwtModule {}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { PassportStrategy } from '@nestjs/passport';
|
|
3
|
+
import { ExtractJwt, Strategy } from 'passport-jwt';
|
|
4
|
+
|
|
5
|
+
@Injectable()
|
|
6
|
+
export class JwtStrategy extends PassportStrategy(Strategy) {
|
|
7
|
+
constructor() {
|
|
8
|
+
super({
|
|
9
|
+
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
|
10
|
+
ignoreExpiration: false,
|
|
11
|
+
secretOrKey: process.env.JWT_SECRET ?? 'change-me',
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
validate(payload: { sub: string; email: string }) {
|
|
16
|
+
return { userId: payload.sub, email: payload.email };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Injectable, OnModuleDestroy } from '@nestjs/common';
|
|
2
|
+
{{#if usePostgres}}
|
|
3
|
+
import { drizzle, NodePgDatabase } from 'drizzle-orm/node-postgres';
|
|
4
|
+
import pg from 'pg';
|
|
5
|
+
{{/if}}
|
|
6
|
+
{{#if useMysql}}
|
|
7
|
+
import { drizzle, MySql2Database } from 'drizzle-orm/mysql2';
|
|
8
|
+
import mysql from 'mysql2/promise';
|
|
9
|
+
{{/if}}
|
|
10
|
+
import * as schema from './schema';
|
|
11
|
+
|
|
12
|
+
@Injectable()
|
|
13
|
+
export class DrizzleService implements OnModuleDestroy {
|
|
14
|
+
private pool: {{#if usePostgres}}pg.Pool{{/if}}{{#if useMysql}}mysql.Pool{{/if}};
|
|
15
|
+
readonly db: {{#if usePostgres}}NodePgDatabase<typeof schema>{{/if}}{{#if useMysql}}MySql2Database<typeof schema>{{/if}};
|
|
16
|
+
|
|
17
|
+
constructor() {
|
|
18
|
+
{{#if usePostgres}}
|
|
19
|
+
this.pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
|
|
20
|
+
this.db = drizzle(this.pool, { schema });
|
|
21
|
+
{{/if}}
|
|
22
|
+
{{#if useMysql}}
|
|
23
|
+
this.pool = mysql.createPool(process.env.DATABASE_URL!);
|
|
24
|
+
this.db = drizzle(this.pool, { schema, mode: 'default' });
|
|
25
|
+
{{/if}}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async onModuleDestroy() {
|
|
29
|
+
await this.pool.end();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{{#if usePostgres}}
|
|
2
|
+
import { pgTable, timestamp, uuid, varchar } from 'drizzle-orm/pg-core';
|
|
3
|
+
|
|
4
|
+
export const users = pgTable('users', {
|
|
5
|
+
id: uuid('id').primaryKey().defaultRandom(),
|
|
6
|
+
email: varchar('email', { length: 255 }).notNull().unique(),
|
|
7
|
+
name: varchar('name', { length: 255 }),
|
|
8
|
+
createdAt: timestamp('created_at').defaultNow().notNull(),
|
|
9
|
+
updatedAt: timestamp('updated_at').defaultNow().notNull(),
|
|
10
|
+
});
|
|
11
|
+
{{/if}}
|
|
12
|
+
{{#if useMysql}}
|
|
13
|
+
import { mysqlTable, timestamp, varchar } from 'drizzle-orm/mysql-core';
|
|
14
|
+
|
|
15
|
+
export const users = mysqlTable('users', {
|
|
16
|
+
id: varchar('id', { length: 36 }).primaryKey(),
|
|
17
|
+
email: varchar('email', { length: 255 }).notNull().unique(),
|
|
18
|
+
name: varchar('name', { length: 255 }),
|
|
19
|
+
createdAt: timestamp('created_at').defaultNow().notNull(),
|
|
20
|
+
updatedAt: timestamp('updated_at').defaultNow().notNull(),
|
|
21
|
+
});
|
|
22
|
+
{{/if}}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Column,
|
|
3
|
+
DataType,
|
|
4
|
+
Default,
|
|
5
|
+
Model,
|
|
6
|
+
PrimaryKey,
|
|
7
|
+
Table,
|
|
8
|
+
} from 'sequelize-typescript';
|
|
9
|
+
|
|
10
|
+
@Table({ tableName: 'users' })
|
|
11
|
+
export class User extends Model {
|
|
12
|
+
@PrimaryKey
|
|
13
|
+
@Default(DataType.UUIDV4)
|
|
14
|
+
@Column(DataType.UUID)
|
|
15
|
+
declare id: string;
|
|
16
|
+
|
|
17
|
+
@Column({ unique: true })
|
|
18
|
+
declare email: string;
|
|
19
|
+
|
|
20
|
+
@Column({ allowNull: true })
|
|
21
|
+
declare name: string | null;
|
|
22
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { SequelizeModule as NestSequelizeModule } from '@nestjs/sequelize';
|
|
3
|
+
import { User } from './models/user.model';
|
|
4
|
+
|
|
5
|
+
@Module({
|
|
6
|
+
imports: [
|
|
7
|
+
NestSequelizeModule.forRoot({
|
|
8
|
+
dialect: '{{sequelizeDialect}}' as const,
|
|
9
|
+
uri: process.env.DATABASE_URL,
|
|
10
|
+
models: [User],
|
|
11
|
+
autoLoadModels: true,
|
|
12
|
+
synchronize: process.env.NODE_ENV !== 'production',
|
|
13
|
+
}),
|
|
14
|
+
NestSequelizeModule.forFeature([User]),
|
|
15
|
+
],
|
|
16
|
+
exports: [NestSequelizeModule],
|
|
17
|
+
})
|
|
18
|
+
export class SequelizeModule {}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Column,
|
|
3
|
+
CreateDateColumn,
|
|
4
|
+
Entity,
|
|
5
|
+
PrimaryGeneratedColumn,
|
|
6
|
+
UpdateDateColumn,
|
|
7
|
+
} from 'typeorm';
|
|
8
|
+
|
|
9
|
+
@Entity('users')
|
|
10
|
+
export class UserEntity {
|
|
11
|
+
@PrimaryGeneratedColumn('uuid')
|
|
12
|
+
id!: string;
|
|
13
|
+
|
|
14
|
+
@Column({ unique: true })
|
|
15
|
+
email!: string;
|
|
16
|
+
|
|
17
|
+
@Column({ nullable: true })
|
|
18
|
+
name!: string | null;
|
|
19
|
+
|
|
20
|
+
@CreateDateColumn()
|
|
21
|
+
createdAt!: Date;
|
|
22
|
+
|
|
23
|
+
@UpdateDateColumn()
|
|
24
|
+
updatedAt!: Date;
|
|
25
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
3
|
+
import { UserEntity } from './entities/user.entity';
|
|
4
|
+
|
|
5
|
+
@Module({
|
|
6
|
+
imports: [
|
|
7
|
+
TypeOrmModule.forRoot({
|
|
8
|
+
type: '{{typeormDriver}}' as const,
|
|
9
|
+
url: process.env.DATABASE_URL,
|
|
10
|
+
entities: [UserEntity],
|
|
11
|
+
synchronize: process.env.NODE_ENV !== 'production',
|
|
12
|
+
autoLoadEntities: true,
|
|
13
|
+
}),
|
|
14
|
+
TypeOrmModule.forFeature([UserEntity]),
|
|
15
|
+
],
|
|
16
|
+
exports: [TypeOrmModule],
|
|
17
|
+
})
|
|
18
|
+
export class TypeormModule {}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Injectable, OnModuleDestroy } from '@nestjs/common';
|
|
2
|
+
{{#if usePostgres}}
|
|
3
|
+
import { drizzle, NodePgDatabase } from 'drizzle-orm/node-postgres';
|
|
4
|
+
import pg from 'pg';
|
|
5
|
+
{{/if}}
|
|
6
|
+
{{#if useMysql}}
|
|
7
|
+
import { drizzle, MySql2Database } from 'drizzle-orm/mysql2';
|
|
8
|
+
import mysql from 'mysql2/promise';
|
|
9
|
+
{{/if}}
|
|
10
|
+
import * as schema from './schema';
|
|
11
|
+
|
|
12
|
+
@Injectable()
|
|
13
|
+
export class DrizzleService implements OnModuleDestroy {
|
|
14
|
+
private pool: {{#if usePostgres}}pg.Pool{{/if}}{{#if useMysql}}mysql.Pool{{/if}};
|
|
15
|
+
readonly db: {{#if usePostgres}}NodePgDatabase<typeof schema>{{/if}}{{#if useMysql}}MySql2Database<typeof schema>{{/if}};
|
|
16
|
+
|
|
17
|
+
constructor() {
|
|
18
|
+
{{#if usePostgres}}
|
|
19
|
+
this.pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
|
|
20
|
+
this.db = drizzle(this.pool, { schema });
|
|
21
|
+
{{/if}}
|
|
22
|
+
{{#if useMysql}}
|
|
23
|
+
this.pool = mysql.createPool(process.env.DATABASE_URL!);
|
|
24
|
+
this.db = drizzle(this.pool, { schema, mode: 'default' });
|
|
25
|
+
{{/if}}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async onModuleDestroy() {
|
|
29
|
+
await this.pool.end();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{{#if usePostgres}}
|
|
2
|
+
import { pgTable, timestamp, uuid, varchar } from 'drizzle-orm/pg-core';
|
|
3
|
+
|
|
4
|
+
export const users = pgTable('users', {
|
|
5
|
+
id: uuid('id').primaryKey().defaultRandom(),
|
|
6
|
+
email: varchar('email', { length: 255 }).notNull().unique(),
|
|
7
|
+
name: varchar('name', { length: 255 }),
|
|
8
|
+
createdAt: timestamp('created_at').defaultNow().notNull(),
|
|
9
|
+
updatedAt: timestamp('updated_at').defaultNow().notNull(),
|
|
10
|
+
});
|
|
11
|
+
{{/if}}
|
|
12
|
+
{{#if useMysql}}
|
|
13
|
+
import { mysqlTable, timestamp, varchar } from 'drizzle-orm/mysql-core';
|
|
14
|
+
|
|
15
|
+
export const users = mysqlTable('users', {
|
|
16
|
+
id: varchar('id', { length: 36 }).primaryKey(),
|
|
17
|
+
email: varchar('email', { length: 255 }).notNull().unique(),
|
|
18
|
+
name: varchar('name', { length: 255 }),
|
|
19
|
+
createdAt: timestamp('created_at').defaultNow().notNull(),
|
|
20
|
+
updatedAt: timestamp('updated_at').defaultNow().notNull(),
|
|
21
|
+
});
|
|
22
|
+
{{/if}}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Column,
|
|
3
|
+
DataType,
|
|
4
|
+
Default,
|
|
5
|
+
Model,
|
|
6
|
+
PrimaryKey,
|
|
7
|
+
Table,
|
|
8
|
+
} from 'sequelize-typescript';
|
|
9
|
+
|
|
10
|
+
@Table({ tableName: 'users' })
|
|
11
|
+
export class User extends Model {
|
|
12
|
+
@PrimaryKey
|
|
13
|
+
@Default(DataType.UUIDV4)
|
|
14
|
+
@Column(DataType.UUID)
|
|
15
|
+
declare id: string;
|
|
16
|
+
|
|
17
|
+
@Column({ unique: true })
|
|
18
|
+
declare email: string;
|
|
19
|
+
|
|
20
|
+
@Column({ allowNull: true })
|
|
21
|
+
declare name: string | null;
|
|
22
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { SequelizeModule as NestSequelizeModule } from '@nestjs/sequelize';
|
|
3
|
+
import { User } from './models/user.model';
|
|
4
|
+
|
|
5
|
+
@Module({
|
|
6
|
+
imports: [
|
|
7
|
+
NestSequelizeModule.forRoot({
|
|
8
|
+
dialect: '{{sequelizeDialect}}' as const,
|
|
9
|
+
uri: process.env.DATABASE_URL,
|
|
10
|
+
models: [User],
|
|
11
|
+
autoLoadModels: true,
|
|
12
|
+
synchronize: process.env.NODE_ENV !== 'production',
|
|
13
|
+
}),
|
|
14
|
+
NestSequelizeModule.forFeature([User]),
|
|
15
|
+
],
|
|
16
|
+
exports: [NestSequelizeModule],
|
|
17
|
+
})
|
|
18
|
+
export class SequelizeModule {}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Column,
|
|
3
|
+
CreateDateColumn,
|
|
4
|
+
Entity,
|
|
5
|
+
PrimaryGeneratedColumn,
|
|
6
|
+
UpdateDateColumn,
|
|
7
|
+
} from 'typeorm';
|
|
8
|
+
|
|
9
|
+
@Entity('users')
|
|
10
|
+
export class UserEntity {
|
|
11
|
+
@PrimaryGeneratedColumn('uuid')
|
|
12
|
+
id!: string;
|
|
13
|
+
|
|
14
|
+
@Column({ unique: true })
|
|
15
|
+
email!: string;
|
|
16
|
+
|
|
17
|
+
@Column({ nullable: true })
|
|
18
|
+
name!: string | null;
|
|
19
|
+
|
|
20
|
+
@CreateDateColumn()
|
|
21
|
+
createdAt!: Date;
|
|
22
|
+
|
|
23
|
+
@UpdateDateColumn()
|
|
24
|
+
updatedAt!: Date;
|
|
25
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
3
|
+
import { UserEntity } from './entities/user.entity';
|
|
4
|
+
|
|
5
|
+
@Module({
|
|
6
|
+
imports: [
|
|
7
|
+
TypeOrmModule.forRoot({
|
|
8
|
+
type: '{{typeormDriver}}' as const,
|
|
9
|
+
url: process.env.DATABASE_URL,
|
|
10
|
+
entities: [UserEntity],
|
|
11
|
+
synchronize: process.env.NODE_ENV !== 'production',
|
|
12
|
+
autoLoadEntities: true,
|
|
13
|
+
}),
|
|
14
|
+
TypeOrmModule.forFeature([UserEntity]),
|
|
15
|
+
],
|
|
16
|
+
exports: [TypeOrmModule],
|
|
17
|
+
})
|
|
18
|
+
export class TypeormModule {}
|
package/dist/validate.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateProjectConfig = validateProjectConfig;
|
|
4
|
+
const shared_1 = require("@node-initializr/shared");
|
|
5
|
+
const NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
6
|
+
function validateProjectConfig(config) {
|
|
7
|
+
const errors = [];
|
|
8
|
+
if (!config.name?.trim()) {
|
|
9
|
+
errors.push('name é obrigatório');
|
|
10
|
+
}
|
|
11
|
+
else if (config.name.length > 50) {
|
|
12
|
+
errors.push('name deve ter no máximo 50 caracteres');
|
|
13
|
+
}
|
|
14
|
+
else if (!NAME_PATTERN.test(config.name)) {
|
|
15
|
+
errors.push('name deve ser kebab-case (ex: my-api)');
|
|
16
|
+
}
|
|
17
|
+
if (!(0, shared_1.isOrmCompatibleWithDatabase)(config.orm, config.database)) {
|
|
18
|
+
if (config.orm === 'drizzle' && config.database === 'mongodb') {
|
|
19
|
+
errors.push('Drizzle não é compatível com MongoDB. Use PostgreSQL ou MySQL.');
|
|
20
|
+
}
|
|
21
|
+
else if (config.orm === 'sequelize' && config.database === 'mongodb') {
|
|
22
|
+
errors.push('Sequelize não é compatível com MongoDB. Use PostgreSQL ou MySQL.');
|
|
23
|
+
}
|
|
24
|
+
else if (config.database === 'none' &&
|
|
25
|
+
(config.orm === 'prisma' ||
|
|
26
|
+
config.orm === 'typeorm' ||
|
|
27
|
+
config.orm === 'sequelize')) {
|
|
28
|
+
errors.push(`${config.orm} requer um banco de dados configurado.`);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
errors.push('ORM incompatível com o banco selecionado.');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (!(0, shared_1.isMessageBrokerCompatible)(config.redis, config.messageBroker)) {
|
|
35
|
+
errors.push('BullMQ requer Redis habilitado.');
|
|
36
|
+
}
|
|
37
|
+
if (config.framework === 'nestjs' && config.language === 'javascript') {
|
|
38
|
+
errors.push('NestJS requer TypeScript.');
|
|
39
|
+
}
|
|
40
|
+
return errors;
|
|
41
|
+
}
|
package/dist/zip.d.ts
ADDED
package/dist/zip.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createZip = createZip;
|
|
7
|
+
const archiver_1 = __importDefault(require("archiver"));
|
|
8
|
+
function createZip(files) {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
const archive = (0, archiver_1.default)('zip', { zlib: { level: 9 } });
|
|
11
|
+
const chunks = [];
|
|
12
|
+
archive.on('data', (chunk) => chunks.push(chunk));
|
|
13
|
+
archive.on('error', reject);
|
|
14
|
+
archive.on('end', () => resolve(Buffer.concat(chunks)));
|
|
15
|
+
for (const file of files) {
|
|
16
|
+
archive.append(file.content, { name: file.path });
|
|
17
|
+
}
|
|
18
|
+
void archive.finalize();
|
|
19
|
+
});
|
|
20
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@node-initializr/generator",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Engine de geração de projetos Node.js para o Node Initializr",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/pietro-sdev/node-initializr.git",
|
|
9
|
+
"directory": "packages/generator"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc && node scripts/copy-templates.mjs",
|
|
21
|
+
"dev": "tsc --watch",
|
|
22
|
+
"prepack": "npm run build"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@node-initializr/shared": "*",
|
|
26
|
+
"archiver": "^7.0.1",
|
|
27
|
+
"handlebars": "^4.7.8"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=20"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/archiver": "^6.0.3",
|
|
34
|
+
"@types/node": "^22.10.0",
|
|
35
|
+
"typescript": "^5.7.3"
|
|
36
|
+
}
|
|
37
|
+
}
|