nestforge-generator 0.2.0 → 0.3.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/README.md +11 -6
- package/README.pt-BR.md +11 -6
- package/dist/features/database.js +35 -0
- package/dist/features/database.js.map +1 -1
- package/dist/generator.js +7 -1
- package/dist/generator.js.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/prompts.js +3 -1
- package/dist/prompts.js.map +1 -1
- package/package.json +2 -1
- package/templates/drizzle/README.md +2 -0
- package/templates/drizzle/README.pt-BR.md +2 -0
- package/templates/prisma/.github/workflows/ci.yml +24 -1
- package/templates/prisma/ARCHITECTURE.md +7 -1
- package/templates/prisma/ARCHITECTURE.pt-BR.md +7 -1
- package/templates/prisma/README.md +11 -7
- package/templates/prisma/README.pt-BR.md +11 -7
- package/templates/prisma/ROADMAP.md +5 -1
- package/templates/prisma/ROADMAP.pt-BR.md +5 -1
- package/templates/prisma/TESTING.md +25 -3
- package/templates/prisma/TESTING.pt-BR.md +25 -3
- package/templates/prisma/docker-compose.yml +29 -1
- package/templates/prisma/docs/adding-a-module.md +246 -230
- package/templates/prisma/docs/features-markers.md +11 -1
- package/templates/prisma/prisma/schema.prisma +4 -0
- package/templates/prisma/src/auth/token.service.ts +12 -3
- package/templates/prisma/src/health/indicators/prisma-health.indicator.spec.ts +39 -22
- package/templates/prisma/src/health/indicators/prisma-health.indicator.ts +24 -19
- package/templates/typeorm/README.md +2 -0
- package/templates/typeorm/README.pt-BR.md +2 -0
|
@@ -21,6 +21,16 @@ export class UsersController {
|
|
|
21
21
|
|
|
22
22
|
O nome depois de `nestforge:feature:` tem que ser exatamente o mesmo nas duas linhas (abertura e `:end`), e bater com o nome usado no array `features` da CLI (`docker`, `swagger`, `validation`, `redis`, `rbac`).
|
|
23
23
|
|
|
24
|
+
Marcadores de banco são adicionados automaticamente pelo gerador:
|
|
25
|
+
|
|
26
|
+
* `database:postgres`;
|
|
27
|
+
* `database:mysql`;
|
|
28
|
+
* `database:sqlite`;
|
|
29
|
+
* `database:mongodb`;
|
|
30
|
+
* `database:relational`, habilitado em PostgreSQL, MySQL e SQLite.
|
|
31
|
+
|
|
32
|
+
Use `database:relational` quando o mesmo trecho SQL serve para todos os bancos relacionais, como a etapa `prisma migrate deploy`. Use o marcador específico quando provider, URL, health check ou infraestrutura dependem do banco selecionado.
|
|
33
|
+
|
|
24
34
|
Funciona em qualquer arquivo cuja linguagem use `//` para comentário (`.ts`, `.js`). **Não funciona em JSON** (`package.json`) — pra dependências, ver a seção final deste documento.
|
|
25
35
|
|
|
26
36
|
## Marcador de arquivo inteiro
|
|
@@ -47,4 +57,4 @@ JSON não aceita comentário, então marcador não funciona ali. Em vez disso, o
|
|
|
47
57
|
- [ ] Todo trecho de código exclusivo do recurso está marcado (bloco ou arquivo inteiro)
|
|
48
58
|
- [ ] O nome do marcador bate com o valor usado em `features` na CLI (`packages/cli/src/prompts.ts`)
|
|
49
59
|
- [ ] Dependências novas do `package.json` estão em `FEATURE_DEPENDENCIES` (`packages/cli/src/features/dependencies.ts`)
|
|
50
|
-
- [ ] Testado gerando o projeto com o recurso ligado **e** desligado — o projeto tem que compilar/rodar dos dois jeitos
|
|
60
|
+
- [ ] Testado gerando o projeto com o recurso ligado **e** desligado — o projeto tem que compilar/rodar dos dois jeitos
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// nestforge:feature-file:auth:token
|
|
2
2
|
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
|
3
3
|
import { JwtService } from '@nestjs/jwt';
|
|
4
|
+
import type { JwtSignOptions } from '@nestjs/jwt';
|
|
4
5
|
import { createHash } from 'crypto';
|
|
5
6
|
import { PrismaService } from '../database/prisma.service';
|
|
6
7
|
|
|
@@ -14,14 +15,22 @@ export class TokenService {
|
|
|
14
15
|
async issueTokens(userId: string, email: string, role: string) {
|
|
15
16
|
const payload = { sub: userId, email, role };
|
|
16
17
|
|
|
18
|
+
const accessTokenExpiresIn = (
|
|
19
|
+
process.env.JWT_ACCESS_EXPIRES_IN ?? '15m'
|
|
20
|
+
) as JwtSignOptions['expiresIn'];
|
|
21
|
+
|
|
22
|
+
const refreshTokenExpiresIn = (
|
|
23
|
+
process.env.JWT_REFRESH_EXPIRES_IN ?? '7d'
|
|
24
|
+
) as JwtSignOptions['expiresIn'];
|
|
25
|
+
|
|
17
26
|
const accessToken = this.jwtService.sign(payload, {
|
|
18
27
|
secret: process.env.JWT_ACCESS_SECRET,
|
|
19
|
-
expiresIn:
|
|
28
|
+
expiresIn: accessTokenExpiresIn,
|
|
20
29
|
});
|
|
21
30
|
|
|
22
31
|
const refreshToken = this.jwtService.sign(payload, {
|
|
23
32
|
secret: process.env.JWT_REFRESH_SECRET,
|
|
24
|
-
expiresIn:
|
|
33
|
+
expiresIn: refreshTokenExpiresIn,
|
|
25
34
|
});
|
|
26
35
|
|
|
27
36
|
const expiresAt = new Date();
|
|
@@ -81,4 +90,4 @@ export class TokenService {
|
|
|
81
90
|
private hashToken(token: string): string {
|
|
82
91
|
return createHash('sha256').update(token).digest('hex');
|
|
83
92
|
}
|
|
84
|
-
}
|
|
93
|
+
}
|
|
@@ -1,22 +1,39 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { HealthCheckError } from '@nestjs/terminus';
|
|
3
|
-
import { PrismaHealthIndicator } from './prisma-health.indicator';
|
|
4
|
-
import { PrismaService } from '../../database/prisma.service';
|
|
5
|
-
|
|
6
|
-
describe('PrismaHealthIndicator', () => {
|
|
7
|
-
it('retorna status up quando a query executa com sucesso', async () => {
|
|
8
|
-
const prisma = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
});
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { HealthCheckError } from '@nestjs/terminus';
|
|
3
|
+
import { PrismaHealthIndicator } from './prisma-health.indicator';
|
|
4
|
+
import { PrismaService } from '../../database/prisma.service';
|
|
5
|
+
|
|
6
|
+
describe('PrismaHealthIndicator', () => {
|
|
7
|
+
it('retorna status up quando a query executa com sucesso', async () => {
|
|
8
|
+
const prisma = {
|
|
9
|
+
// nestforge:feature:database:relational
|
|
10
|
+
$queryRaw: vi.fn().mockResolvedValue([{ '?column?': 1 }]),
|
|
11
|
+
// nestforge:feature:database:relational:end
|
|
12
|
+
// nestforge:feature:database:mongodb
|
|
13
|
+
$runCommandRaw: vi.fn().mockResolvedValue({ ok: 1 }),
|
|
14
|
+
// nestforge:feature:database:mongodb:end
|
|
15
|
+
};
|
|
16
|
+
const indicator = new PrismaHealthIndicator(prisma as unknown as PrismaService);
|
|
17
|
+
|
|
18
|
+
const result = await indicator.isHealthy('database');
|
|
19
|
+
|
|
20
|
+
expect(result).toEqual({ database: { status: 'up' } });
|
|
21
|
+
// nestforge:feature:database:mongodb
|
|
22
|
+
expect(prisma.$runCommandRaw).toHaveBeenCalledWith({ ping: 1 });
|
|
23
|
+
// nestforge:feature:database:mongodb:end
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('lança HealthCheckError quando a query falha', async () => {
|
|
27
|
+
const prisma = {
|
|
28
|
+
// nestforge:feature:database:relational
|
|
29
|
+
$queryRaw: vi.fn().mockRejectedValue(new Error('conexão recusada')),
|
|
30
|
+
// nestforge:feature:database:relational:end
|
|
31
|
+
// nestforge:feature:database:mongodb
|
|
32
|
+
$runCommandRaw: vi.fn().mockRejectedValue(new Error('conexão recusada')),
|
|
33
|
+
// nestforge:feature:database:mongodb:end
|
|
34
|
+
};
|
|
35
|
+
const indicator = new PrismaHealthIndicator(prisma as unknown as PrismaService);
|
|
36
|
+
|
|
37
|
+
await expect(indicator.isHealthy('database')).rejects.toBeInstanceOf(HealthCheckError);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
import { Injectable } from '@nestjs/common';
|
|
2
|
-
import { HealthIndicatorResult, HealthCheckError } from '@nestjs/terminus';
|
|
3
|
-
import { PrismaService } from '../../database/prisma.service';
|
|
4
|
-
|
|
5
|
-
@Injectable()
|
|
6
|
-
export class PrismaHealthIndicator {
|
|
7
|
-
constructor(private readonly prisma: PrismaService) { }
|
|
8
|
-
|
|
9
|
-
async isHealthy(key: string): Promise<HealthIndicatorResult> {
|
|
10
|
-
try {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { HealthIndicatorResult, HealthCheckError } from '@nestjs/terminus';
|
|
3
|
+
import { PrismaService } from '../../database/prisma.service';
|
|
4
|
+
|
|
5
|
+
@Injectable()
|
|
6
|
+
export class PrismaHealthIndicator {
|
|
7
|
+
constructor(private readonly prisma: PrismaService) { }
|
|
8
|
+
|
|
9
|
+
async isHealthy(key: string): Promise<HealthIndicatorResult> {
|
|
10
|
+
try {
|
|
11
|
+
// nestforge:feature:database:relational
|
|
12
|
+
await this.prisma.$queryRaw`SELECT 1`;
|
|
13
|
+
// nestforge:feature:database:relational:end
|
|
14
|
+
// nestforge:feature:database:mongodb
|
|
15
|
+
await this.prisma.$runCommandRaw({ ping: 1 });
|
|
16
|
+
// nestforge:feature:database:mongodb:end
|
|
17
|
+
return { [key]: { status: 'up' } };
|
|
18
|
+
} catch (error) {
|
|
19
|
+
throw new HealthCheckError('Banco de dados indisponível', {
|
|
20
|
+
[key]: { status: 'down', message: (error as Error).message },
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -25,6 +25,8 @@ NestForge is a NestJS starter designed to accelerate the beginning of serious ba
|
|
|
25
25
|
- 🐳 **Docker** — complete environment with a single command
|
|
26
26
|
- ⚙️ **CI/CD** — GitHub Actions (build, lint, test)
|
|
27
27
|
|
|
28
|
+
> **MongoDB compatibility:** MongoDB is not available in this NestForge template. Although TypeORM provides basic MongoDB support, adopting it would require a separate document-oriented architecture for entities, repositories, relations, migrations, session persistence, and tests; it is not a direct database-driver substitution. MongoDB generation is currently available through the Prisma template.
|
|
29
|
+
|
|
28
30
|
## 🧱 Stack
|
|
29
31
|
|
|
30
32
|
| Layer | Technology |
|
|
@@ -25,6 +25,8 @@ NestForge é um boilerplate de NestJS pensado para acelerar o início de projeto
|
|
|
25
25
|
- 🐳 **Docker** — ambiente completo com um comando
|
|
26
26
|
- ⚙️ **CI/CD** — GitHub Actions (build, lint, test)
|
|
27
27
|
|
|
28
|
+
> **Compatibilidade com MongoDB:** o MongoDB não está disponível neste template do NestForge. Embora o TypeORM ofereça suporte básico a MongoDB, adotá-lo exigiria uma arquitetura separada e orientada a documentos para entidades, repositories, relações, migrations, persistência de sessões e testes; não se trata de uma troca direta do driver de banco. Atualmente, a geração com MongoDB está disponível por meio do template Prisma.
|
|
29
|
+
|
|
28
30
|
## 🧱 Stack
|
|
29
31
|
|
|
30
32
|
| Camada | Tecnologia |
|