@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.
Files changed (152) hide show
  1. package/dist/generate.d.ts +12 -0
  2. package/dist/generate.js +77 -0
  3. package/dist/index.d.ts +4 -0
  4. package/dist/index.js +14 -0
  5. package/dist/template-engine.d.ts +24 -0
  6. package/dist/template-engine.js +472 -0
  7. package/dist/templates/arch-clean/express/src/application/use-cases/get-users.use-case.hbs +39 -0
  8. package/dist/templates/arch-clean/express/src/config/env.hbs +4 -0
  9. package/dist/templates/arch-clean/express/src/domain/entities/user.entity.hbs +7 -0
  10. package/dist/templates/arch-clean/express/src/index.hbs +66 -0
  11. package/dist/templates/arch-clean/express/src/infrastructure/http/health.routes.hbs +7 -0
  12. package/dist/templates/arch-clean/express/src/infrastructure/http/users.routes.hbs +9 -0
  13. package/dist/templates/arch-clean/express/src/shared/errors/app.error.hbs +5 -0
  14. package/dist/templates/arch-clean/fastify/src/application/use-cases/get-users.use-case.hbs +39 -0
  15. package/dist/templates/arch-clean/fastify/src/domain/entities/user.entity.hbs +7 -0
  16. package/dist/templates/arch-clean/fastify/src/index.hbs +53 -0
  17. package/dist/templates/arch-clean/fastify/src/infrastructure/http/routes.hbs +8 -0
  18. package/dist/templates/arch-clean/fastify/src/shared/errors/app.error.hbs +5 -0
  19. package/dist/templates/arch-clean/nestjs/src/app.module.ts.hbs +58 -0
  20. package/dist/templates/arch-clean/nestjs/src/application/use-cases/get-users.use-case.ts.hbs +14 -0
  21. package/dist/templates/arch-clean/nestjs/src/config/config.module.ts.hbs +4 -0
  22. package/dist/templates/arch-clean/nestjs/src/domain/entities/user.entity.ts.hbs +7 -0
  23. package/dist/templates/arch-clean/nestjs/src/domain/repositories/user.repository.ts.hbs +7 -0
  24. package/dist/templates/arch-clean/nestjs/src/infrastructure/http/health.controller.ts.hbs +11 -0
  25. package/dist/templates/arch-clean/nestjs/src/infrastructure/http/users.controller.ts.hbs +22 -0
  26. package/dist/templates/arch-clean/nestjs/src/infrastructure/persistence/drizzle-user.repository.ts.hbs +15 -0
  27. package/dist/templates/arch-clean/nestjs/src/infrastructure/persistence/in-memory-user.repository.ts.hbs +10 -0
  28. package/dist/templates/arch-clean/nestjs/src/infrastructure/persistence/prisma-user.repository.ts.hbs +14 -0
  29. package/dist/templates/arch-clean/nestjs/src/infrastructure/persistence/sequelize-user.repository.ts.hbs +18 -0
  30. package/dist/templates/arch-clean/nestjs/src/infrastructure/persistence/typeorm-user.repository.ts.hbs +19 -0
  31. package/dist/templates/arch-clean/nestjs/src/infrastructure/prisma/prisma.module.ts.hbs +6 -0
  32. package/dist/templates/arch-clean/nestjs/src/infrastructure/prisma/prisma.service.ts.hbs +8 -0
  33. package/dist/templates/arch-clean/nestjs/src/main.ts.hbs +21 -0
  34. package/dist/templates/arch-clean/nestjs/src/shared/errors/app.error.ts.hbs +9 -0
  35. package/dist/templates/arch-clean/nestjs/tests/health.spec.ts.hbs +17 -0
  36. package/dist/templates/arch-modular/express/src/index.hbs +46 -0
  37. package/dist/templates/arch-modular/express/src/infra/database.hbs +3 -0
  38. package/dist/templates/arch-modular/express/src/modules/health/health.routes.hbs +7 -0
  39. package/dist/templates/arch-modular/express/src/modules/users/users.routes.hbs +55 -0
  40. package/dist/templates/arch-modular/express/src/shared/constants.hbs +1 -0
  41. package/dist/templates/arch-modular/fastify/src/index.hbs +33 -0
  42. package/dist/templates/arch-modular/fastify/src/infra/database.hbs +3 -0
  43. package/dist/templates/arch-modular/fastify/src/modules/health/health.routes.hbs +9 -0
  44. package/dist/templates/arch-modular/fastify/src/modules/users/users.routes.hbs +48 -0
  45. package/dist/templates/arch-modular/fastify/src/shared/constants.hbs +1 -0
  46. package/dist/templates/arch-modular/nestjs/src/app.module.ts.hbs +63 -0
  47. package/dist/templates/arch-modular/nestjs/src/config/config.module.ts.hbs +4 -0
  48. package/dist/templates/arch-modular/nestjs/src/infra/prisma/prisma.module.ts.hbs +9 -0
  49. package/dist/templates/arch-modular/nestjs/src/infra/prisma/prisma.service.ts.hbs +13 -0
  50. package/dist/templates/arch-modular/nestjs/src/main.ts.hbs +28 -0
  51. package/dist/templates/arch-modular/nestjs/src/modules/health/health.controller.ts.hbs +17 -0
  52. package/dist/templates/arch-modular/nestjs/src/modules/health/health.module.ts.hbs +7 -0
  53. package/dist/templates/arch-modular/nestjs/src/modules/users/users.controller.ts.hbs +24 -0
  54. package/dist/templates/arch-modular/nestjs/src/modules/users/users.module.ts.hbs +10 -0
  55. package/dist/templates/arch-modular/nestjs/src/modules/users/users.service.ts.hbs +60 -0
  56. package/dist/templates/arch-modular/nestjs/src/shared/constants.ts.hbs +1 -0
  57. package/dist/templates/arch-modular/nestjs/tests/health.spec.ts.hbs +16 -0
  58. package/dist/templates/arch-mvc/express/src/controllers/health.controller.hbs +7 -0
  59. package/dist/templates/arch-mvc/express/src/controllers/users.controller.hbs +10 -0
  60. package/dist/templates/arch-mvc/express/src/index.hbs +60 -0
  61. package/dist/templates/arch-mvc/express/src/models/user.model.hbs +7 -0
  62. package/dist/templates/arch-mvc/express/src/services/users.service.hbs +39 -0
  63. package/dist/templates/arch-mvc/fastify/src/controllers/users.controller.hbs +9 -0
  64. package/dist/templates/arch-mvc/fastify/src/index.hbs +53 -0
  65. package/dist/templates/arch-mvc/fastify/src/models/user.model.hbs +7 -0
  66. package/dist/templates/arch-mvc/fastify/src/services/users.service.hbs +39 -0
  67. package/dist/templates/arch-mvc/nestjs/src/app.module.ts.hbs +44 -0
  68. package/dist/templates/arch-mvc/nestjs/src/config/config.module.ts.hbs +4 -0
  69. package/dist/templates/arch-mvc/nestjs/src/controllers/health.controller.ts.hbs +11 -0
  70. package/dist/templates/arch-mvc/nestjs/src/controllers/users.controller.ts.hbs +22 -0
  71. package/dist/templates/arch-mvc/nestjs/src/infra/prisma/prisma.module.ts.hbs +6 -0
  72. package/dist/templates/arch-mvc/nestjs/src/infra/prisma/prisma.service.ts.hbs +8 -0
  73. package/dist/templates/arch-mvc/nestjs/src/main.ts.hbs +21 -0
  74. package/dist/templates/arch-mvc/nestjs/src/models/user.model.ts.hbs +7 -0
  75. package/dist/templates/arch-mvc/nestjs/src/services/users.service.ts.hbs +61 -0
  76. package/dist/templates/arch-mvc/nestjs/tests/health.spec.ts.hbs +17 -0
  77. package/dist/templates/base-express/.env.example.hbs +21 -0
  78. package/dist/templates/base-express/.gitignore.hbs +6 -0
  79. package/dist/templates/base-express/README.md.hbs +10 -0
  80. package/dist/templates/base-express/docker/Dockerfile.hbs +21 -0
  81. package/dist/templates/base-express/docker/docker-compose.yml.hbs +61 -0
  82. package/dist/templates/base-express/drizzle/drizzle.config.hbs +10 -0
  83. package/dist/templates/base-express/github-actions/ci.yml.hbs +40 -0
  84. package/dist/templates/base-express/package.json.hbs +54 -0
  85. package/dist/templates/base-express/prisma/schema.prisma.hbs +16 -0
  86. package/dist/templates/base-express/tests/health.test.hbs +8 -0
  87. package/dist/templates/base-express/tsconfig.json.hbs +13 -0
  88. package/dist/templates/base-fastify/.env.example.hbs +21 -0
  89. package/dist/templates/base-fastify/.gitignore.hbs +6 -0
  90. package/dist/templates/base-fastify/README.md.hbs +10 -0
  91. package/dist/templates/base-fastify/docker/Dockerfile.hbs +21 -0
  92. package/dist/templates/base-fastify/docker/docker-compose.yml.hbs +61 -0
  93. package/dist/templates/base-fastify/drizzle/drizzle.config.hbs +10 -0
  94. package/dist/templates/base-fastify/github-actions/ci.yml.hbs +40 -0
  95. package/dist/templates/base-fastify/package.json.hbs +50 -0
  96. package/dist/templates/base-fastify/prisma/schema.prisma.hbs +16 -0
  97. package/dist/templates/base-fastify/tests/health.test.hbs +8 -0
  98. package/dist/templates/base-fastify/tsconfig.json.hbs +13 -0
  99. package/dist/templates/base-nestjs/.env.example.hbs +24 -0
  100. package/dist/templates/base-nestjs/.gitignore.hbs +10 -0
  101. package/dist/templates/base-nestjs/README.md.hbs +46 -0
  102. package/dist/templates/base-nestjs/docker/Dockerfile.hbs +21 -0
  103. package/dist/templates/base-nestjs/docker/docker-compose.yml.hbs +69 -0
  104. package/dist/templates/base-nestjs/drizzle/drizzle.config.ts.hbs +10 -0
  105. package/dist/templates/base-nestjs/github-actions/ci.yml.hbs +38 -0
  106. package/dist/templates/base-nestjs/nest-cli.json.hbs +8 -0
  107. package/dist/templates/base-nestjs/package.json.hbs +65 -0
  108. package/dist/templates/base-nestjs/prisma/schema.prisma.hbs +16 -0
  109. package/dist/templates/base-nestjs/tsconfig.json.hbs +19 -0
  110. package/dist/templates/shared-express/src/infra/auth/clerk.middleware.hbs +12 -0
  111. package/dist/templates/shared-express/src/infra/auth/jwt.middleware.hbs +18 -0
  112. package/dist/templates/shared-express/src/infra/drizzle/client.hbs +18 -0
  113. package/dist/templates/shared-express/src/infra/drizzle/schema.hbs +22 -0
  114. package/dist/templates/shared-express/src/infra/prisma/client.hbs +15 -0
  115. package/dist/templates/shared-express/src/infra/sequelize/models/user.model.ts.hbs +22 -0
  116. package/dist/templates/shared-express/src/infra/sequelize/sequelize.ts.hbs +16 -0
  117. package/dist/templates/shared-express/src/infra/swagger/setup.hbs +19 -0
  118. package/dist/templates/shared-express/src/infra/typeorm/data-source.hbs +17 -0
  119. package/dist/templates/shared-express/src/infra/typeorm/entities/user.entity.hbs +25 -0
  120. package/dist/templates/shared-fastify/src/infra/auth/clerk.middleware.hbs +16 -0
  121. package/dist/templates/shared-fastify/src/infra/auth/jwt.middleware.hbs +14 -0
  122. package/dist/templates/shared-fastify/src/infra/drizzle/client.hbs +18 -0
  123. package/dist/templates/shared-fastify/src/infra/drizzle/schema.hbs +22 -0
  124. package/dist/templates/shared-fastify/src/infra/prisma/client.hbs +15 -0
  125. package/dist/templates/shared-fastify/src/infra/sequelize/models/user.model.ts.hbs +22 -0
  126. package/dist/templates/shared-fastify/src/infra/sequelize/sequelize.ts.hbs +16 -0
  127. package/dist/templates/shared-fastify/src/infra/swagger/setup.hbs +16 -0
  128. package/dist/templates/shared-fastify/src/infra/typeorm/data-source.hbs +17 -0
  129. package/dist/templates/shared-fastify/src/infra/typeorm/entities/user.entity.hbs +25 -0
  130. package/dist/templates/shared-nestjs/src/infra/auth/clerk/clerk-auth.guard.ts.hbs +25 -0
  131. package/dist/templates/shared-nestjs/src/infra/auth/jwt/jwt-auth.guard.ts.hbs +5 -0
  132. package/dist/templates/shared-nestjs/src/infra/auth/jwt/jwt.module.ts.hbs +17 -0
  133. package/dist/templates/shared-nestjs/src/infra/auth/jwt/jwt.strategy.ts.hbs +18 -0
  134. package/dist/templates/shared-nestjs/src/infra/drizzle/drizzle.module.ts.hbs +9 -0
  135. package/dist/templates/shared-nestjs/src/infra/drizzle/drizzle.service.ts.hbs +31 -0
  136. package/dist/templates/shared-nestjs/src/infra/drizzle/schema.ts.hbs +22 -0
  137. package/dist/templates/shared-nestjs/src/infra/sequelize/models/user.model.ts.hbs +22 -0
  138. package/dist/templates/shared-nestjs/src/infra/sequelize/sequelize.module.ts.hbs +18 -0
  139. package/dist/templates/shared-nestjs/src/infra/typeorm/entities/user.entity.ts.hbs +25 -0
  140. package/dist/templates/shared-nestjs/src/infra/typeorm/typeorm.module.ts.hbs +18 -0
  141. package/dist/templates/shared-nestjs/src/infrastructure/drizzle/drizzle.module.ts.hbs +9 -0
  142. package/dist/templates/shared-nestjs/src/infrastructure/drizzle/drizzle.service.ts.hbs +31 -0
  143. package/dist/templates/shared-nestjs/src/infrastructure/drizzle/schema.ts.hbs +22 -0
  144. package/dist/templates/shared-nestjs/src/infrastructure/sequelize/models/user.model.ts.hbs +22 -0
  145. package/dist/templates/shared-nestjs/src/infrastructure/sequelize/sequelize.module.ts.hbs +18 -0
  146. package/dist/templates/shared-nestjs/src/infrastructure/typeorm/entities/user.entity.ts.hbs +25 -0
  147. package/dist/templates/shared-nestjs/src/infrastructure/typeorm/typeorm.module.ts.hbs +18 -0
  148. package/dist/validate.d.ts +2 -0
  149. package/dist/validate.js +41 -0
  150. package/dist/zip.d.ts +2 -0
  151. package/dist/zip.js +20 -0
  152. 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,5 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { AuthGuard } from '@nestjs/passport';
3
+
4
+ @Injectable()
5
+ export class JwtAuthGuard extends AuthGuard('jwt') {}
@@ -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,9 @@
1
+ import { Global, Module } from '@nestjs/common';
2
+ import { DrizzleService } from './drizzle.service';
3
+
4
+ @Global()
5
+ @Module({
6
+ providers: [DrizzleService],
7
+ exports: [DrizzleService],
8
+ })
9
+ export class DrizzleModule {}
@@ -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,9 @@
1
+ import { Global, Module } from '@nestjs/common';
2
+ import { DrizzleService } from './drizzle.service';
3
+
4
+ @Global()
5
+ @Module({
6
+ providers: [DrizzleService],
7
+ exports: [DrizzleService],
8
+ })
9
+ export class DrizzleModule {}
@@ -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,2 @@
1
+ import { type ProjectConfig } from '@node-initializr/shared';
2
+ export declare function validateProjectConfig(config: ProjectConfig): string[];
@@ -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
@@ -0,0 +1,2 @@
1
+ import type { GeneratedFile } from './template-engine.js';
2
+ export declare function createZip(files: GeneratedFile[]): Promise<Buffer>;
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
+ }