nestforge-generator 0.1.0 → 0.2.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 +25 -6
- package/README.pt-BR.md +25 -6
- package/dist/features/language.js +19 -1
- package/dist/features/language.js.map +1 -1
- package/dist/features/no-orm.js +493 -0
- package/dist/features/no-orm.js.map +1 -0
- package/dist/generator.js +20 -6
- package/dist/generator.js.map +1 -1
- package/dist/index.js +17 -13
- package/dist/index.js.map +1 -1
- package/dist/prompts.js +30 -22
- package/dist/prompts.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,10 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
**English** | [Português](README.pt-BR.md)
|
|
4
4
|
|
|
5
|
-
Interactive CLI that generates NestJS projects from NestForge's [Prisma](../../templates/prisma), [TypeORM](../../templates/typeorm), and [Drizzle](../../templates/drizzle) templates.
|
|
5
|
+
Interactive CLI that generates NestJS projects from NestForge's [Prisma](../../templates/prisma), [TypeORM](../../templates/typeorm), and [Drizzle](../../templates/drizzle) templates, or without an ORM.
|
|
6
|
+
|
|
7
|
+
Install the package locally:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install nestforge-generator
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Run the locally installed CLI:
|
|
6
14
|
|
|
7
15
|
```bash
|
|
8
|
-
npx nestforge
|
|
16
|
+
npx nestforge
|
|
9
17
|
```
|
|
10
18
|
|
|
11
19
|
For the testing guide, CLI prompts, and complete checklist, see [`TESTING.md`](TESTING.md).
|
|
@@ -14,7 +22,7 @@ For the testing guide, CLI prompts, and complete checklist, see [`TESTING.md`](T
|
|
|
14
22
|
|
|
15
23
|
- Interactive prompts using `@clack/prompts`;
|
|
16
24
|
- TypeScript or JavaScript generation;
|
|
17
|
-
- Prisma, TypeORM,
|
|
25
|
+
- Prisma, TypeORM, Drizzle ORM, or no ORM;
|
|
18
26
|
- PostgreSQL, MySQL, and SQLite;
|
|
19
27
|
- JWT, Session/Cookies, OAuth-only, or no authentication;
|
|
20
28
|
- optional Docker;
|
|
@@ -97,6 +105,16 @@ The Drizzle template includes:
|
|
|
97
105
|
|
|
98
106
|
After generation, only the schema and driver for the selected database remain in the project.
|
|
99
107
|
|
|
108
|
+
### No ORM
|
|
109
|
+
|
|
110
|
+
The “None” option:
|
|
111
|
+
|
|
112
|
+
- skips the database and authentication prompts;
|
|
113
|
+
- generates no schema, migrations, seed, database driver, or ORM dependency;
|
|
114
|
+
- removes authentication, users, and access control;
|
|
115
|
+
- keeps independent optional features;
|
|
116
|
+
- works with TypeScript and JavaScript.
|
|
117
|
+
|
|
100
118
|
## Authentication strategies
|
|
101
119
|
|
|
102
120
|
### JWT
|
|
@@ -239,7 +257,7 @@ When requested, the CLI automatically creates `.env` from the already processed
|
|
|
239
257
|
| ORM: Prisma | ✅ Implemented |
|
|
240
258
|
| ORM: TypeORM | ✅ Implemented |
|
|
241
259
|
| ORM: Drizzle | ✅ Implemented |
|
|
242
|
-
| ORM: None |
|
|
260
|
+
| ORM: None | ✅ Implemented |
|
|
243
261
|
| Database: PostgreSQL | ✅ Implemented |
|
|
244
262
|
| Database: MySQL | ✅ Implemented |
|
|
245
263
|
| Database: SQLite | ✅ Implemented |
|
|
@@ -274,6 +292,8 @@ Coverage includes:
|
|
|
274
292
|
- Drizzle with PostgreSQL;
|
|
275
293
|
- Drizzle with MySQL;
|
|
276
294
|
- Drizzle with SQLite;
|
|
295
|
+
- no ORM with TypeScript;
|
|
296
|
+
- no ORM with JavaScript, Docker, and Redis;
|
|
277
297
|
- JWT;
|
|
278
298
|
- Session/Cookies;
|
|
279
299
|
- OAuth-only;
|
|
@@ -359,12 +379,11 @@ npm publish
|
|
|
359
379
|
The build:
|
|
360
380
|
|
|
361
381
|
1. compiles the CLI;
|
|
362
|
-
2. copies the
|
|
382
|
+
2. copies the source templates;
|
|
363
383
|
3. prepares the package published to npm.
|
|
364
384
|
|
|
365
385
|
## Next steps
|
|
366
386
|
|
|
367
|
-
- an option without an ORM;
|
|
368
387
|
- MongoDB;
|
|
369
388
|
- more complete project and package name validation;
|
|
370
389
|
- expand the smoke-test matrix with real PostgreSQL and MySQL services;
|
package/README.pt-BR.md
CHANGED
|
@@ -2,10 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) | **Português**
|
|
4
4
|
|
|
5
|
-
CLI interativa que gera projetos NestJS a partir dos templates `../../templates/prisma`, `../../templates/typeorm` e `../../templates/drizzle` do NestForge.
|
|
5
|
+
CLI interativa que gera projetos NestJS a partir dos templates `../../templates/prisma`, `../../templates/typeorm` e `../../templates/drizzle` do NestForge, ou sem ORM.
|
|
6
|
+
|
|
7
|
+
Instale o pacote localmente:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install nestforge-generator
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Execute a CLI instalada localmente:
|
|
6
14
|
|
|
7
15
|
```bash
|
|
8
|
-
npx nestforge
|
|
16
|
+
npx nestforge
|
|
9
17
|
```
|
|
10
18
|
|
|
11
19
|
Para o guia de testes, perguntas da CLI e checklist completo, consulte [`TESTING.pt-BR.md`](TESTING.pt-BR.md).
|
|
@@ -14,7 +22,7 @@ Para o guia de testes, perguntas da CLI e checklist completo, consulte [`TESTING
|
|
|
14
22
|
|
|
15
23
|
* Prompts interativos usando @clack/prompts;
|
|
16
24
|
* geração em TypeScript ou JavaScript;
|
|
17
|
-
* Prisma, TypeORM
|
|
25
|
+
* Prisma, TypeORM, Drizzle ORM ou nenhum ORM;
|
|
18
26
|
* PostgreSQL, MySQL e SQLite;
|
|
19
27
|
* autenticação JWT, Session/Cookies, OAuth-only ou nenhuma;
|
|
20
28
|
* Docker opcional;
|
|
@@ -97,6 +105,16 @@ O template Drizzle inclui:
|
|
|
97
105
|
|
|
98
106
|
Depois da geração, somente o schema e o driver do banco selecionado permanecem no projeto.
|
|
99
107
|
|
|
108
|
+
### Sem ORM
|
|
109
|
+
|
|
110
|
+
A opção “Nenhum”:
|
|
111
|
+
|
|
112
|
+
* pula as perguntas de banco de dados e autenticação;
|
|
113
|
+
* não gera schema, migrations, seed, driver de banco ou dependência de ORM;
|
|
114
|
+
* remove autenticação, usuários e controle de acesso;
|
|
115
|
+
* mantém os recursos opcionais independentes;
|
|
116
|
+
* funciona com TypeScript e JavaScript.
|
|
117
|
+
|
|
100
118
|
## Estratégias de autenticação
|
|
101
119
|
|
|
102
120
|
### JWT
|
|
@@ -240,7 +258,7 @@ processado.
|
|
|
240
258
|
| ORM: Prisma | ✅ Implementado |
|
|
241
259
|
| ORM: TypeORM | ✅ Implementado |
|
|
242
260
|
| ORM: Drizzle | ✅ Implementado |
|
|
243
|
-
| ORM: Nenhum |
|
|
261
|
+
| ORM: Nenhum | ✅ Implementado |
|
|
244
262
|
| Banco: PostgreSQL | ✅ Implementado |
|
|
245
263
|
| Banco: MySQL | ✅ Implementado |
|
|
246
264
|
| Banco: SQLite | ✅ Implementado |
|
|
@@ -273,6 +291,8 @@ A cobertura inclui:
|
|
|
273
291
|
* Drizzle com PostgreSQL;
|
|
274
292
|
* Drizzle com MySQL;
|
|
275
293
|
* Drizzle com SQLite;
|
|
294
|
+
* sem ORM com TypeScript;
|
|
295
|
+
* sem ORM com JavaScript, Docker e Redis;
|
|
276
296
|
* JWT;
|
|
277
297
|
* Session/Cookies;
|
|
278
298
|
* OAuth-only;
|
|
@@ -358,12 +378,11 @@ npm publish
|
|
|
358
378
|
O build:
|
|
359
379
|
|
|
360
380
|
1. compila a CLI;
|
|
361
|
-
2. copia os templates
|
|
381
|
+
2. copia os templates-fonte;
|
|
362
382
|
3. prepara o pacote publicado no npm.
|
|
363
383
|
|
|
364
384
|
## Próximos itens
|
|
365
385
|
|
|
366
|
-
* opção sem ORM;
|
|
367
386
|
* MongoDB;
|
|
368
387
|
* validação mais completa do nome do projeto e do pacote;
|
|
369
388
|
* ampliação da matriz de smoke tests com PostgreSQL e MySQL reais;
|
|
@@ -34,10 +34,24 @@ export async function applyLanguageTransform(targetDir, language, orm) {
|
|
|
34
34
|
await fs.remove(path.join(targetDir, 'tsconfig.build.json'));
|
|
35
35
|
await fs.remove(path.join(targetDir, 'nest-cli.json'));
|
|
36
36
|
await updatePackageJson(targetDir, orm);
|
|
37
|
+
await updateVitestConfigs(targetDir);
|
|
37
38
|
if (orm === 'drizzle') {
|
|
38
39
|
await updateDrizzleWorkflow(targetDir);
|
|
39
40
|
}
|
|
40
41
|
}
|
|
42
|
+
async function updateVitestConfigs(targetDir) {
|
|
43
|
+
for (const configName of [
|
|
44
|
+
'vitest.config.js',
|
|
45
|
+
'vitest.e2e.config.js',
|
|
46
|
+
]) {
|
|
47
|
+
const configPath = path.join(targetDir, configName);
|
|
48
|
+
if (!(await fs.pathExists(configPath))) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const config = await fs.readFile(configPath, 'utf8');
|
|
52
|
+
await fs.writeFile(configPath, config.replaceAll('.ts', '.js'), 'utf8');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
41
55
|
async function collectTypeScriptFiles(dir) {
|
|
42
56
|
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
43
57
|
const files = [];
|
|
@@ -74,10 +88,14 @@ async function removeTypeDeclarationFiles(dir) {
|
|
|
74
88
|
}
|
|
75
89
|
async function transpileFile(filePath) {
|
|
76
90
|
const source = await fs.readFile(filePath, 'utf8');
|
|
91
|
+
const isTestFile = filePath.split(path.sep).includes('test') ||
|
|
92
|
+
filePath.endsWith('.spec.ts');
|
|
77
93
|
const result = ts.transpileModule(source, {
|
|
78
94
|
compilerOptions: {
|
|
79
95
|
target: ts.ScriptTarget.ES2022,
|
|
80
|
-
module:
|
|
96
|
+
module: isTestFile
|
|
97
|
+
? ts.ModuleKind.ESNext
|
|
98
|
+
: ts.ModuleKind.CommonJS,
|
|
81
99
|
experimentalDecorators: true,
|
|
82
100
|
emitDecoratorMetadata: true,
|
|
83
101
|
esModuleInterop: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"language.js","sourceRoot":"","sources":["../../src/features/language.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;AAE3E,MAAM,2BAA2B,GAAG;IAChC,aAAa;IACb,oBAAoB;IACpB,iBAAiB;IACjB,wBAAwB;IACxB,eAAe;IACf,aAAa;IACb,mBAAmB;IACnB,yBAAyB;IACzB,gCAAgC;IAChC,qBAAqB;IACrB,kBAAkB;IAClB,kCAAkC;IAClC,2BAA2B;IAC3B,SAAS;IACT,YAAY;IACZ,uBAAuB;IACvB,WAAW;CACd,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,sBAAsB,CACxC,SAAiB,EACjB,QAAgB,EAChB,GAAW;IAEX,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC5B,OAAO;IACX,CAAC;IAED,MAAM,eAAe,GAAG,MAAM,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAEhE,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,0BAA0B,CAAC,SAAS,CAAC,CAAC;IAE5C,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;IACvD,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAC7D,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;IAEvD,MAAM,iBAAiB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"language.js","sourceRoot":"","sources":["../../src/features/language.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;AAE3E,MAAM,2BAA2B,GAAG;IAChC,aAAa;IACb,oBAAoB;IACpB,iBAAiB;IACjB,wBAAwB;IACxB,eAAe;IACf,aAAa;IACb,mBAAmB;IACnB,yBAAyB;IACzB,gCAAgC;IAChC,qBAAqB;IACrB,kBAAkB;IAClB,kCAAkC;IAClC,2BAA2B;IAC3B,SAAS;IACT,YAAY;IACZ,uBAAuB;IACvB,WAAW;CACd,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,sBAAsB,CACxC,SAAiB,EACjB,QAAgB,EAChB,GAAW;IAEX,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC5B,OAAO;IACX,CAAC;IAED,MAAM,eAAe,GAAG,MAAM,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAEhE,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,0BAA0B,CAAC,SAAS,CAAC,CAAC;IAE5C,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;IACvD,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAC7D,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;IAEvD,MAAM,iBAAiB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACxC,MAAM,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAErC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACpB,MAAM,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC;AACL,CAAC;AAED,KAAK,UAAU,mBAAmB,CAC9B,SAAiB;IAEjB,KAAK,MAAM,UAAU,IAAI;QACrB,kBAAkB;QAClB,sBAAsB;KACzB,EAAE,CAAC;QACA,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CACxB,SAAS,EACT,UAAU,CACb,CAAC;QAEF,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YACrC,SAAS;QACb,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC5B,UAAU,EACV,MAAM,CACT,CAAC;QAEF,MAAM,EAAE,CAAC,SAAS,CACd,UAAU,EACV,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,EAC/B,MAAM,CACT,CAAC;IACN,CAAC;AACL,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,GAAW;IAC7C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,SAAS;QACb,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE5C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACtB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,sBAAsB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACxD,SAAS;QACb,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAChF,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,0BAA0B,CAAC,GAAW;IACjD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,SAAS;QACb,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE5C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACtB,MAAM,0BAA0B,CAAC,QAAQ,CAAC,CAAC;YAC3C,SAAS;QACb,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACjD,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC;IACL,CAAC;AACL,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,QAAgB;IACzC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,UAAU,GACZ,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QACzC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAElC,MAAM,MAAM,GAAG,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE;QACtC,eAAe,EAAE;YACb,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM;YAC9B,MAAM,EAAE,UAAU;gBACd,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM;gBACtB,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ;YAC5B,sBAAsB,EAAE,IAAI;YAC5B,qBAAqB,EAAE,IAAI;YAC3B,eAAe,EAAE,IAAI;YACrB,SAAS,EAAE,KAAK;SACnB;QACD,QAAQ,EAAE,QAAQ;QAClB,iBAAiB,EAAE,IAAI;KAC1B,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,MAAM,CAC5C,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,KAAK,EAAE,CAAC,kBAAkB,CAAC,KAAK,CACtE,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,MAAM;aACjB,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,4BAA4B,CAAC,UAAU,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;aAClF,IAAI,CAAC,IAAI,CAAC,CAAC;QAEhB,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,uBAAuB,OAAO,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAExD,MAAM,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC9D,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC5B,SAAiB,EACjB,GAAW;IAEX,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAC7B,SAAS,EACT,cAAc,CACjB,CAAC;IAEF,MAAM,WAAW,GACb,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IAEvC,WAAW,CAAC,OAAO,GAAG;QAClB,GAAG,WAAW,CAAC,OAAO;QACtB,KAAK,EAAE,0BAA0B;QACjC,KAAK,EAAE,kBAAkB;QACzB,WAAW,EAAE,0BAA0B;QACvC,aAAa,EACT,oCAAoC;QACxC,YAAY,EAAE,kBAAkB;QAChC,IAAI,EAAE,mCAAmC;QACzC,MAAM,EACF,+CAA+C;QACnD,UAAU,EACN,mEAAmE;KAC1E,CAAC;IAEF,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;QACnB,WAAW,CAAC,OAAO,CAAC,aAAa,CAAC;YAC9B,qBAAqB,CAAC;QAE1B,WAAW,CAAC,MAAM,GAAG;YACjB,GAAG,WAAW,CAAC,MAAM;YACrB,IAAI,EAAE,qBAAqB;SAC9B,CAAC;IACN,CAAC;IAED,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACpB,WAAW,CAAC,OAAO,CAAC,OAAO;YACvB,0DAA0D,CAAC;QAE/D,WAAW,CAAC,OAAO,CACf,oBAAoB,CACvB;YACG,uCAAuC,CAAC;QAE5C,WAAW,CAAC,OAAO,CACf,kBAAkB,CACrB,GAAG,0BAA0B,CAAC;QAE/B,WAAW,CAAC,OAAO,CAAC,eAAe,CAAC;YAChC,kCAAkC,CAAC;QAEvC,WAAW,CAAC,OAAO,CACf,kBAAkB,CACrB;YACG,qCAAqC,CAAC;QAE1C,WAAW,CAAC,OAAO,CAAC,aAAa,CAAC;YAC9B,6EAA6E,CAAC;QAElF,WAAW,CAAC,OAAO,CAAC,IAAI;YACpB,6CAA6C,CAAC;QAElD,OAAO,WAAW,CAAC,MAAM,CAAC;QAC1B,OAAO,WAAW,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACpB,WAAW,CAAC,OAAO,CACf,kBAAkB,CACrB;YACG,mEAAmE,CAAC;QAExE,WAAW,CAAC,OAAO,CACf,iBAAiB,CACpB;YACG,kEAAkE,CAAC;QAEvE,WAAW,CAAC,OAAO,CACf,cAAc,CACjB;YACG,+DAA+D,CAAC;QAEpE,WAAW,CAAC,OAAO,CACf,gBAAgB,CACnB;YACG,iEAAiE,CAAC;QAEtE,WAAW,CAAC,OAAO,CACf,aAAa,CAChB;YACG,uEAAuE,CAAC;QAE5E,WAAW,CAAC,OAAO,CAAC,IAAI;YACpB,6CAA6C,CAAC;QAElD,OAAO,WAAW,CAAC,MAAM,CAAC;QAC1B,OAAO,WAAW,CAAC,OAAO,CACtB,aAAa,CAChB,CAAC;IACN,CAAC;IAED,KAAK,MAAM,UAAU,IAAI,2BAA2B,EAAE,CAAC;QACnD,OAAO,WAAW,CAAC,YAAY,EAAE,CAAC,UAAU,CAAC,CAAC;QAC9C,OAAO,WAAW,CAAC,eAAe,EAAE,CAAC,UAAU,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,EAAE,CAAC,SAAS,CACd,eAAe,EACf,WAAW,EACX,EAAE,MAAM,EAAE,CAAC,EAAE,CAChB,CAAC;AACN,CAAC;AAED,KAAK,UAAU,qBAAqB,CAChC,SAAiB;IAEjB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAC1B,SAAS,EACT,SAAS,EACT,WAAW,EACX,QAAQ,CACX,CAAC;IAEF,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QACvC,OAAO;IACX,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC9B,YAAY,EACZ,MAAM,CACT,CAAC;IAEF,MAAM,OAAO,GAAG,QAAQ;SACnB,OAAO,CACJ,0BAA0B,EAC1B,qDAAqD,CACxD;SACA,OAAO,CACJ,yBAAyB,EACzB,oDAAoD,CACvD,CAAC;IAEN,MAAM,EAAE,CAAC,SAAS,CACd,YAAY,EACZ,OAAO,EACP,MAAM,CACT,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const ORM_PATHS = [
|
|
4
|
+
'prisma',
|
|
5
|
+
'src/database',
|
|
6
|
+
'src/health/indicators/prisma-health.indicator.ts',
|
|
7
|
+
'src/health/indicators/prisma-health.indicator.spec.ts',
|
|
8
|
+
'src/common/utils/avatar-storage.util.ts',
|
|
9
|
+
'src/common/utils/hash.util.ts',
|
|
10
|
+
'test/utils/clean-database.ts',
|
|
11
|
+
'docs',
|
|
12
|
+
'ARCHITECTURE.md',
|
|
13
|
+
'ARCHITECTURE.pt-BR.md',
|
|
14
|
+
'ROADMAP.md',
|
|
15
|
+
'ROADMAP.pt-BR.md',
|
|
16
|
+
'TESTING.md',
|
|
17
|
+
'TESTING.pt-BR.md',
|
|
18
|
+
];
|
|
19
|
+
const AUTH_PACKAGES = [
|
|
20
|
+
'@nestjs/jwt',
|
|
21
|
+
'@nestjs/passport',
|
|
22
|
+
'@quixo3/prisma-session-store',
|
|
23
|
+
'@prisma/client',
|
|
24
|
+
'bcryptjs',
|
|
25
|
+
'express-session',
|
|
26
|
+
'multer',
|
|
27
|
+
'passport',
|
|
28
|
+
'passport-github2',
|
|
29
|
+
'passport-google-oauth20',
|
|
30
|
+
'passport-jwt',
|
|
31
|
+
'@types/bcryptjs',
|
|
32
|
+
'@types/express-session',
|
|
33
|
+
'@types/multer',
|
|
34
|
+
'@types/passport-github2',
|
|
35
|
+
'@types/passport-google-oauth20',
|
|
36
|
+
'@types/passport-jwt',
|
|
37
|
+
'prisma',
|
|
38
|
+
'ts-node',
|
|
39
|
+
];
|
|
40
|
+
export async function applyNoOrmTransform(targetDir, enabledFeatures) {
|
|
41
|
+
for (const relativePath of ORM_PATHS) {
|
|
42
|
+
await fs.remove(path.join(targetDir, relativePath));
|
|
43
|
+
}
|
|
44
|
+
await updatePackageJson(targetDir);
|
|
45
|
+
await writeApplicationModule(targetDir, enabledFeatures);
|
|
46
|
+
await writeHealthFiles(targetDir, enabledFeatures);
|
|
47
|
+
await writeEnvironmentFiles(targetDir);
|
|
48
|
+
await writeDockerFiles(targetDir, enabledFeatures);
|
|
49
|
+
await writeCiWorkflow(targetDir, enabledFeatures);
|
|
50
|
+
await writeReadmes(targetDir, enabledFeatures);
|
|
51
|
+
await writeDatabaseFreeTests(targetDir);
|
|
52
|
+
}
|
|
53
|
+
async function updatePackageJson(targetDir) {
|
|
54
|
+
const packagePath = path.join(targetDir, 'package.json');
|
|
55
|
+
const packageJson = await fs.readJson(packagePath);
|
|
56
|
+
packageJson.description =
|
|
57
|
+
'Production-ready NestJS starter without an ORM or database integration.';
|
|
58
|
+
delete packageJson.prisma;
|
|
59
|
+
delete packageJson.scripts['pretest:e2e'];
|
|
60
|
+
for (const scriptName of Object.keys(packageJson.scripts)) {
|
|
61
|
+
if (scriptName.startsWith('prisma:')) {
|
|
62
|
+
delete packageJson.scripts[scriptName];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
for (const packageName of AUTH_PACKAGES) {
|
|
66
|
+
delete packageJson.dependencies?.[packageName];
|
|
67
|
+
delete packageJson.devDependencies?.[packageName];
|
|
68
|
+
}
|
|
69
|
+
packageJson.devDependencies['@types/express'] ??= '^5.0.0';
|
|
70
|
+
await fs.writeJson(packagePath, packageJson, { spaces: 2 });
|
|
71
|
+
}
|
|
72
|
+
async function writeApplicationModule(targetDir, enabledFeatures) {
|
|
73
|
+
const redisEnabled = enabledFeatures.has('redis');
|
|
74
|
+
const redisImport = redisEnabled
|
|
75
|
+
? "import { BullModule } from '@nestjs/bullmq';\nimport { MailModule } from './mail/mail.module';\n"
|
|
76
|
+
: '';
|
|
77
|
+
const redisModules = redisEnabled
|
|
78
|
+
? `
|
|
79
|
+
BullModule.forRoot({
|
|
80
|
+
connection: {
|
|
81
|
+
host: process.env.REDIS_HOST ?? 'localhost',
|
|
82
|
+
port: Number(process.env.REDIS_PORT ?? 6379),
|
|
83
|
+
},
|
|
84
|
+
}),
|
|
85
|
+
MailModule,`
|
|
86
|
+
: '';
|
|
87
|
+
await writeText(targetDir, 'src/app.module.ts', `import { Module } from '@nestjs/common';
|
|
88
|
+
import { ConfigModule } from '@nestjs/config';
|
|
89
|
+
import { ThrottlerModule } from '@nestjs/throttler';
|
|
90
|
+
${redisImport}import { LoggerModule } from 'nestjs-pino';
|
|
91
|
+
import { HealthModule } from './health/health.module';
|
|
92
|
+
import { MetricsModule } from './metrics/metrics.module';
|
|
93
|
+
import { validateEnv } from './config/env.validation';
|
|
94
|
+
|
|
95
|
+
@Module({
|
|
96
|
+
imports: [
|
|
97
|
+
ConfigModule.forRoot({
|
|
98
|
+
isGlobal: true,
|
|
99
|
+
validate: validateEnv,
|
|
100
|
+
}),
|
|
101
|
+
LoggerModule.forRoot({
|
|
102
|
+
pinoHttp: {
|
|
103
|
+
level: process.env.NODE_ENV === 'production' ? 'info' : 'debug',
|
|
104
|
+
transport:
|
|
105
|
+
process.env.NODE_ENV === 'development'
|
|
106
|
+
? { target: 'pino-pretty', options: { singleLine: true } }
|
|
107
|
+
: undefined,
|
|
108
|
+
},
|
|
109
|
+
}),
|
|
110
|
+
ThrottlerModule.forRoot([
|
|
111
|
+
{
|
|
112
|
+
ttl: Number(process.env.THROTTLE_TTL ?? 60) * 1000,
|
|
113
|
+
limit: Number(process.env.THROTTLE_LIMIT ?? 100),
|
|
114
|
+
},
|
|
115
|
+
]),${redisModules}
|
|
116
|
+
HealthModule,
|
|
117
|
+
MetricsModule,
|
|
118
|
+
],
|
|
119
|
+
})
|
|
120
|
+
export class AppModule {}
|
|
121
|
+
`);
|
|
122
|
+
}
|
|
123
|
+
async function writeHealthFiles(targetDir, enabledFeatures) {
|
|
124
|
+
const redisEnabled = enabledFeatures.has('redis');
|
|
125
|
+
const redisImport = redisEnabled
|
|
126
|
+
? "import { RedisHealthIndicator } from './indicators/redis-health.indicator';\n"
|
|
127
|
+
: '';
|
|
128
|
+
const redisConstructor = redisEnabled
|
|
129
|
+
? ' private readonly redisIndicator: RedisHealthIndicator,\n'
|
|
130
|
+
: '';
|
|
131
|
+
const redisCheck = redisEnabled
|
|
132
|
+
? " () => this.redisIndicator.isHealthy('redis'),\n"
|
|
133
|
+
: '';
|
|
134
|
+
const redisProvider = redisEnabled ? ' RedisHealthIndicator,\n' : '';
|
|
135
|
+
await writeText(targetDir, 'src/health/health.controller.ts', `import { Controller, Get } from '@nestjs/common';
|
|
136
|
+
import {
|
|
137
|
+
DiskHealthIndicator,
|
|
138
|
+
HealthCheck,
|
|
139
|
+
HealthCheckService,
|
|
140
|
+
MemoryHealthIndicator,
|
|
141
|
+
} from '@nestjs/terminus';
|
|
142
|
+
${redisImport}import { Public } from '../common/decorators/public.decorator';
|
|
143
|
+
|
|
144
|
+
@Controller('health')
|
|
145
|
+
export class HealthController {
|
|
146
|
+
constructor(
|
|
147
|
+
private readonly health: HealthCheckService,
|
|
148
|
+
${redisConstructor} private readonly memory: MemoryHealthIndicator,
|
|
149
|
+
private readonly disk: DiskHealthIndicator,
|
|
150
|
+
) {}
|
|
151
|
+
|
|
152
|
+
@Public()
|
|
153
|
+
@Get()
|
|
154
|
+
@HealthCheck()
|
|
155
|
+
check() {
|
|
156
|
+
return this.health.check([
|
|
157
|
+
${redisCheck} () => this.memory.checkHeap('memory_heap', 300 * 1024 * 1024),
|
|
158
|
+
() => this.memory.checkRSS('memory_rss', 300 * 1024 * 1024),
|
|
159
|
+
() => this.disk.checkStorage('disk', { path: '/', thresholdPercent: 0.9 }),
|
|
160
|
+
]);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
`);
|
|
164
|
+
await writeText(targetDir, 'src/health/health.module.ts', `import { Module } from '@nestjs/common';
|
|
165
|
+
import { TerminusModule } from '@nestjs/terminus';
|
|
166
|
+
import { HealthController } from './health.controller';
|
|
167
|
+
${redisImport}
|
|
168
|
+
@Module({
|
|
169
|
+
imports: [TerminusModule],
|
|
170
|
+
controllers: [HealthController],
|
|
171
|
+
providers: [
|
|
172
|
+
${redisProvider} ],
|
|
173
|
+
})
|
|
174
|
+
export class HealthModule {}
|
|
175
|
+
`);
|
|
176
|
+
}
|
|
177
|
+
async function writeEnvironmentFiles(targetDir) {
|
|
178
|
+
await writeText(targetDir, '.env.example', `# App
|
|
179
|
+
NODE_ENV=development
|
|
180
|
+
PORT=3000
|
|
181
|
+
APP_URL=http://localhost:3000
|
|
182
|
+
CORS_ORIGINS=http://localhost:5173
|
|
183
|
+
|
|
184
|
+
# Redis
|
|
185
|
+
REDIS_HOST=localhost
|
|
186
|
+
REDIS_PORT=6379
|
|
187
|
+
|
|
188
|
+
# Mail (Mailpit in development)
|
|
189
|
+
MAIL_HOST=localhost
|
|
190
|
+
MAIL_PORT=1025
|
|
191
|
+
MAIL_FROM="NestForge <no-reply@nestforge.dev>"
|
|
192
|
+
|
|
193
|
+
# Rate limit
|
|
194
|
+
THROTTLE_TTL=60
|
|
195
|
+
THROTTLE_LIMIT=100
|
|
196
|
+
`);
|
|
197
|
+
await writeText(targetDir, '.env.test', `NODE_ENV=test
|
|
198
|
+
PORT=3000
|
|
199
|
+
APP_URL=http://localhost:3000
|
|
200
|
+
CORS_ORIGINS=http://localhost:5173
|
|
201
|
+
|
|
202
|
+
REDIS_HOST=localhost
|
|
203
|
+
REDIS_PORT=6379
|
|
204
|
+
|
|
205
|
+
MAIL_HOST=localhost
|
|
206
|
+
MAIL_PORT=1025
|
|
207
|
+
MAIL_FROM="NestForge <no-reply@nestforge.dev>"
|
|
208
|
+
|
|
209
|
+
THROTTLE_TTL=60
|
|
210
|
+
THROTTLE_LIMIT=1000
|
|
211
|
+
`);
|
|
212
|
+
await writeText(targetDir, 'src/config/env.validation.ts', `import { z } from 'zod';
|
|
213
|
+
|
|
214
|
+
const envSchema = z.object({
|
|
215
|
+
NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
|
|
216
|
+
PORT: z.coerce.number().default(3000),
|
|
217
|
+
APP_URL: z.string().url().default('http://localhost:3000'),
|
|
218
|
+
CORS_ORIGINS: z.string().min(1).default('http://localhost:5173'),
|
|
219
|
+
REDIS_HOST: z.string().default('localhost'),
|
|
220
|
+
REDIS_PORT: z.coerce.number().default(6379),
|
|
221
|
+
MAIL_HOST: z.string().default('localhost'),
|
|
222
|
+
MAIL_PORT: z.coerce.number().default(1025),
|
|
223
|
+
MAIL_FROM: z.string().default('NestForge <no-reply@nestforge.dev>'),
|
|
224
|
+
THROTTLE_TTL: z.coerce.number().default(60),
|
|
225
|
+
THROTTLE_LIMIT: z.coerce.number().default(100),
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
export type EnvConfig = z.infer<typeof envSchema>;
|
|
229
|
+
|
|
230
|
+
export function validateEnv(config: Record<string, unknown>): EnvConfig {
|
|
231
|
+
const parsed = envSchema.safeParse(config);
|
|
232
|
+
|
|
233
|
+
if (!parsed.success) {
|
|
234
|
+
const issues = parsed.error.issues
|
|
235
|
+
.map((issue) => \`${'${issue.path.join(\'.\')}: ${issue.message}'}\`)
|
|
236
|
+
.join('\\n');
|
|
237
|
+
throw new Error(\`Invalid environment variables:\\n${'${issues}'}\`);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return parsed.data;
|
|
241
|
+
}
|
|
242
|
+
`);
|
|
243
|
+
}
|
|
244
|
+
async function writeDockerFiles(targetDir, enabledFeatures) {
|
|
245
|
+
const dockerfilePath = path.join(targetDir, 'Dockerfile');
|
|
246
|
+
if (!(await fs.pathExists(dockerfilePath)))
|
|
247
|
+
return;
|
|
248
|
+
await fs.writeFile(dockerfilePath, `# --- Base ---
|
|
249
|
+
FROM node:20-alpine AS base
|
|
250
|
+
WORKDIR /app
|
|
251
|
+
COPY package*.json ./
|
|
252
|
+
|
|
253
|
+
# --- Dependencies ---
|
|
254
|
+
FROM base AS deps
|
|
255
|
+
RUN npm ci
|
|
256
|
+
|
|
257
|
+
# --- Development ---
|
|
258
|
+
FROM deps AS development
|
|
259
|
+
COPY . .
|
|
260
|
+
EXPOSE 3000
|
|
261
|
+
CMD ["npm", "run", "start:dev"]
|
|
262
|
+
|
|
263
|
+
# --- Build ---
|
|
264
|
+
FROM deps AS build
|
|
265
|
+
COPY . .
|
|
266
|
+
RUN npm run build
|
|
267
|
+
RUN npm prune --production
|
|
268
|
+
|
|
269
|
+
# --- Production ---
|
|
270
|
+
FROM node:20-alpine AS production
|
|
271
|
+
WORKDIR /app
|
|
272
|
+
ENV NODE_ENV=production
|
|
273
|
+
COPY --from=build /app/node_modules ./node_modules
|
|
274
|
+
COPY --from=build /app/dist ./dist
|
|
275
|
+
EXPOSE 3000
|
|
276
|
+
CMD ["node", "dist/main.js"]
|
|
277
|
+
`, 'utf-8');
|
|
278
|
+
const redisEnabled = enabledFeatures.has('redis');
|
|
279
|
+
const dependsOn = redisEnabled
|
|
280
|
+
? ` depends_on:
|
|
281
|
+
- redis
|
|
282
|
+
`
|
|
283
|
+
: '';
|
|
284
|
+
const redisServices = redisEnabled
|
|
285
|
+
? `
|
|
286
|
+
redis:
|
|
287
|
+
image: redis:7-alpine
|
|
288
|
+
container_name: nestforge-redis
|
|
289
|
+
restart: unless-stopped
|
|
290
|
+
ports:
|
|
291
|
+
- "6379:6379"
|
|
292
|
+
|
|
293
|
+
mailpit:
|
|
294
|
+
image: axllent/mailpit:latest
|
|
295
|
+
container_name: nestforge-mailpit
|
|
296
|
+
restart: unless-stopped
|
|
297
|
+
ports:
|
|
298
|
+
- "8025:8025"
|
|
299
|
+
- "1025:1025"
|
|
300
|
+
`
|
|
301
|
+
: '';
|
|
302
|
+
await writeText(targetDir, 'docker-compose.yml', `services:
|
|
303
|
+
api:
|
|
304
|
+
build:
|
|
305
|
+
context: .
|
|
306
|
+
dockerfile: Dockerfile
|
|
307
|
+
container_name: nestforge-api
|
|
308
|
+
ports:
|
|
309
|
+
- "3000:3000"
|
|
310
|
+
env_file:
|
|
311
|
+
- .env
|
|
312
|
+
${dependsOn} volumes:
|
|
313
|
+
- ./src:/app/src
|
|
314
|
+
command: npm run start:dev
|
|
315
|
+
${redisServices}`);
|
|
316
|
+
}
|
|
317
|
+
async function writeCiWorkflow(targetDir, enabledFeatures) {
|
|
318
|
+
const redisEnabled = enabledFeatures.has('redis');
|
|
319
|
+
const redisService = redisEnabled
|
|
320
|
+
? `
|
|
321
|
+
services:
|
|
322
|
+
redis:
|
|
323
|
+
image: redis:7-alpine
|
|
324
|
+
ports:
|
|
325
|
+
- 6379:6379
|
|
326
|
+
options: >-
|
|
327
|
+
--health-cmd "redis-cli ping"
|
|
328
|
+
--health-interval 10s
|
|
329
|
+
--health-timeout 5s
|
|
330
|
+
--health-retries 5
|
|
331
|
+
`
|
|
332
|
+
: '';
|
|
333
|
+
await writeText(targetDir, '.github/workflows/ci.yml', `name: CI
|
|
334
|
+
|
|
335
|
+
on:
|
|
336
|
+
push:
|
|
337
|
+
branches: [main]
|
|
338
|
+
pull_request:
|
|
339
|
+
branches: [main]
|
|
340
|
+
|
|
341
|
+
jobs:
|
|
342
|
+
build-test-lint:
|
|
343
|
+
runs-on: ubuntu-latest
|
|
344
|
+
${redisService}
|
|
345
|
+
steps:
|
|
346
|
+
- name: Checkout
|
|
347
|
+
uses: actions/checkout@v4
|
|
348
|
+
|
|
349
|
+
- name: Setup Node
|
|
350
|
+
uses: actions/setup-node@v4
|
|
351
|
+
with:
|
|
352
|
+
node-version: 20
|
|
353
|
+
cache: npm
|
|
354
|
+
|
|
355
|
+
- name: Install dependencies
|
|
356
|
+
run: npm ci
|
|
357
|
+
|
|
358
|
+
- name: Lint
|
|
359
|
+
run: npm run lint
|
|
360
|
+
|
|
361
|
+
- name: Build
|
|
362
|
+
run: npm run build
|
|
363
|
+
|
|
364
|
+
- name: Unit tests
|
|
365
|
+
run: npm test
|
|
366
|
+
|
|
367
|
+
- name: End-to-end tests
|
|
368
|
+
run: npm run test:e2e
|
|
369
|
+
`);
|
|
370
|
+
}
|
|
371
|
+
async function writeReadmes(targetDir, enabledFeatures) {
|
|
372
|
+
const english = ['health checks', 'metrics', 'structured logging', 'rate limiting'];
|
|
373
|
+
const portuguese = [
|
|
374
|
+
'verificações de saúde',
|
|
375
|
+
'métricas',
|
|
376
|
+
'logs estruturados',
|
|
377
|
+
'limitação de requisições',
|
|
378
|
+
];
|
|
379
|
+
if (enabledFeatures.has('docker')) {
|
|
380
|
+
english.push('Docker');
|
|
381
|
+
portuguese.push('Docker');
|
|
382
|
+
}
|
|
383
|
+
if (enabledFeatures.has('swagger')) {
|
|
384
|
+
english.push('Swagger/OpenAPI');
|
|
385
|
+
portuguese.push('Swagger/OpenAPI');
|
|
386
|
+
}
|
|
387
|
+
if (enabledFeatures.has('validation')) {
|
|
388
|
+
english.push('global Zod validation');
|
|
389
|
+
portuguese.push('validação global com Zod');
|
|
390
|
+
}
|
|
391
|
+
if (enabledFeatures.has('redis')) {
|
|
392
|
+
english.push('Redis, BullMQ, and email');
|
|
393
|
+
portuguese.push('Redis, BullMQ e e-mail');
|
|
394
|
+
}
|
|
395
|
+
const englishFeatures = english.map((feature) => `- ${feature}`).join('\n');
|
|
396
|
+
const portugueseFeatures = portuguese.map((feature) => `- ${feature}`).join('\n');
|
|
397
|
+
await writeText(targetDir, 'README.md', `# NestForge
|
|
398
|
+
|
|
399
|
+
**English** | [Português](README.pt-BR.md)
|
|
400
|
+
|
|
401
|
+
NestJS starter generated without an ORM, database integration, or authentication.
|
|
402
|
+
|
|
403
|
+
## Included features
|
|
404
|
+
|
|
405
|
+
${englishFeatures}
|
|
406
|
+
|
|
407
|
+
## Getting started
|
|
408
|
+
|
|
409
|
+
\`\`\`bash
|
|
410
|
+
npm install
|
|
411
|
+
cp .env.example .env
|
|
412
|
+
npm run start:dev
|
|
413
|
+
\`\`\`
|
|
414
|
+
|
|
415
|
+
## Tests
|
|
416
|
+
|
|
417
|
+
\`\`\`bash
|
|
418
|
+
npm test
|
|
419
|
+
npm run test:e2e
|
|
420
|
+
\`\`\`
|
|
421
|
+
`);
|
|
422
|
+
await writeText(targetDir, 'README.pt-BR.md', `# NestForge
|
|
423
|
+
|
|
424
|
+
[English](README.md) | **Português**
|
|
425
|
+
|
|
426
|
+
Starter NestJS gerado sem ORM, integração com banco de dados ou autenticação.
|
|
427
|
+
|
|
428
|
+
## Recursos incluídos
|
|
429
|
+
|
|
430
|
+
${portugueseFeatures}
|
|
431
|
+
|
|
432
|
+
## Primeiros passos
|
|
433
|
+
|
|
434
|
+
\`\`\`bash
|
|
435
|
+
npm install
|
|
436
|
+
cp .env.example .env
|
|
437
|
+
npm run start:dev
|
|
438
|
+
\`\`\`
|
|
439
|
+
|
|
440
|
+
## Testes
|
|
441
|
+
|
|
442
|
+
\`\`\`bash
|
|
443
|
+
npm test
|
|
444
|
+
npm run test:e2e
|
|
445
|
+
\`\`\`
|
|
446
|
+
`);
|
|
447
|
+
}
|
|
448
|
+
async function writeDatabaseFreeTests(targetDir) {
|
|
449
|
+
await writeText(targetDir, 'src/config/env.validation.spec.ts', `import { describe, expect, it } from 'vitest';
|
|
450
|
+
import { validateEnv } from './env.validation';
|
|
451
|
+
|
|
452
|
+
describe('validateEnv', () => {
|
|
453
|
+
it('uses safe defaults without requiring database variables', () => {
|
|
454
|
+
const config = validateEnv({ NODE_ENV: 'test' });
|
|
455
|
+
|
|
456
|
+
expect(config.NODE_ENV).toBe('test');
|
|
457
|
+
expect(config.PORT).toBe(3000);
|
|
458
|
+
expect(config).not.toHaveProperty('DATABASE_URL');
|
|
459
|
+
});
|
|
460
|
+
});
|
|
461
|
+
`);
|
|
462
|
+
await writeText(targetDir, 'test/app.e2e-spec.ts', `import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
463
|
+
import request from 'supertest';
|
|
464
|
+
import type { INestApplication } from '@nestjs/common';
|
|
465
|
+
import { createTestApp } from './utils/e2e-setup';
|
|
466
|
+
|
|
467
|
+
describe('Application (e2e)', () => {
|
|
468
|
+
let app: INestApplication;
|
|
469
|
+
|
|
470
|
+
beforeAll(async () => {
|
|
471
|
+
app = await createTestApp();
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
afterAll(async () => {
|
|
475
|
+
await app.close();
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
it('exposes application metrics without a database', async () => {
|
|
479
|
+
const response = await request(app.getHttpServer())
|
|
480
|
+
.get('/metrics')
|
|
481
|
+
.expect(200);
|
|
482
|
+
|
|
483
|
+
expect(response.text).toContain('# HELP');
|
|
484
|
+
});
|
|
485
|
+
});
|
|
486
|
+
`);
|
|
487
|
+
}
|
|
488
|
+
async function writeText(targetDir, relativePath, content) {
|
|
489
|
+
const filePath = path.join(targetDir, relativePath);
|
|
490
|
+
await fs.ensureDir(path.dirname(filePath));
|
|
491
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
492
|
+
}
|
|
493
|
+
//# sourceMappingURL=no-orm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-orm.js","sourceRoot":"","sources":["../../src/features/no-orm.ts"],"names":[],"mappings":"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"}
|
package/dist/generator.js
CHANGED
|
@@ -6,6 +6,7 @@ import { removeDisabledDependencies } from './features/dependencies.js';
|
|
|
6
6
|
import { applyDatabaseConfig } from './features/database.js';
|
|
7
7
|
import { applyAuthStrategyRemoval } from './features/auth-strategy.js';
|
|
8
8
|
import { applyLanguageTransform } from './features/language.js';
|
|
9
|
+
import { applyNoOrmTransform } from './features/no-orm.js';
|
|
9
10
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
11
|
const PACKAGE_TEMPLATES_ROOT = path.resolve(__dirname, '../templates');
|
|
11
12
|
const MONOREPO_TEMPLATES_ROOT = path.resolve(__dirname, '../../../templates');
|
|
@@ -14,6 +15,7 @@ const IMPLEMENTED_ORMS = [
|
|
|
14
15
|
'prisma',
|
|
15
16
|
'typeorm',
|
|
16
17
|
'drizzle',
|
|
18
|
+
'none',
|
|
17
19
|
];
|
|
18
20
|
const IMPLEMENTED_LANGUAGES = ['typescript', 'javascript'];
|
|
19
21
|
const IMPLEMENTED_DATABASES = ['postgres', 'mysql', 'sqlite'];
|
|
@@ -29,20 +31,27 @@ export async function generateProject(options) {
|
|
|
29
31
|
if (!IMPLEMENTED_LANGUAGES.includes(language)) {
|
|
30
32
|
throw new Error(`Generation in "${language}" is not ready yet — only "typescript" is currently implemented. Contributions are welcome!`);
|
|
31
33
|
}
|
|
32
|
-
if (orm === 'none') {
|
|
33
|
-
throw new Error('A template without an ORM is not available yet. Choose "prisma", "typeorm", or "drizzle".');
|
|
34
|
-
}
|
|
35
34
|
if (!IMPLEMENTED_ORMS.includes(orm)) {
|
|
36
35
|
throw new Error(`The template for "${orm}" is not ready yet — currently available: ${IMPLEMENTED_ORMS.join(', ')}. Contributions are welcome!`);
|
|
37
36
|
}
|
|
38
|
-
if (
|
|
37
|
+
if (orm === 'none' && database !== 'none') {
|
|
38
|
+
throw new Error('Projects without an ORM must use "none" as their database option.');
|
|
39
|
+
}
|
|
40
|
+
if (orm !== 'none' && !IMPLEMENTED_DATABASES.includes(database)) {
|
|
39
41
|
throw new Error(`The "${database}" database is not ready yet — currently implemented: ${IMPLEMENTED_DATABASES.join(', ')}. Contributions are welcome!`);
|
|
40
42
|
}
|
|
43
|
+
if (orm === 'none' && authStrategy !== 'none') {
|
|
44
|
+
throw new Error('Projects without an ORM currently support only the "none" authentication strategy.');
|
|
45
|
+
}
|
|
46
|
+
if (orm === 'none' && accessControl) {
|
|
47
|
+
throw new Error('Access control requires authentication and is not available without an ORM.');
|
|
48
|
+
}
|
|
41
49
|
if (!IMPLEMENTED_AUTH_STRATEGIES.includes(authStrategy)) {
|
|
42
50
|
throw new Error(`The "${authStrategy}" authentication strategy is not ready yet — currently implemented: ${IMPLEMENTED_AUTH_STRATEGIES.join(', ')} ("jwt" already includes Google/GitHub OAuth). Contributions are welcome!`);
|
|
43
51
|
}
|
|
44
52
|
const templatesRoot = await resolveTemplatesRoot();
|
|
45
|
-
const
|
|
53
|
+
const templateName = orm === 'none' ? 'prisma' : orm;
|
|
54
|
+
const templateDir = path.join(templatesRoot, templateName);
|
|
46
55
|
const targetDir = path.resolve(process.cwd(), projectName);
|
|
47
56
|
if (await fs.pathExists(targetDir)) {
|
|
48
57
|
throw new Error(`The "${projectName}" directory already exists. Choose another name or remove the directory.`);
|
|
@@ -50,10 +59,15 @@ export async function generateProject(options) {
|
|
|
50
59
|
await fs.copy(templateDir, targetDir);
|
|
51
60
|
const enabledFeatures = buildEnabledFeatures(features, accessControl, database, authStrategy);
|
|
52
61
|
await applyDockerToggle(targetDir, enabledFeatures);
|
|
53
|
-
|
|
62
|
+
if (orm !== 'none') {
|
|
63
|
+
await applyDatabaseConfig(targetDir, database);
|
|
64
|
+
}
|
|
54
65
|
await applyAuthStrategyRemoval(targetDir, enabledFeatures);
|
|
55
66
|
await applyFeatureMarkers(targetDir, enabledFeatures);
|
|
56
67
|
await removeDisabledDependencies(targetDir, enabledFeatures);
|
|
68
|
+
if (orm === 'none') {
|
|
69
|
+
await applyNoOrmTransform(targetDir, enabledFeatures);
|
|
70
|
+
}
|
|
57
71
|
await applyLanguageTransform(targetDir, language, orm);
|
|
58
72
|
await renameProject(targetDir, projectName);
|
|
59
73
|
if (createEnv) {
|
package/dist/generator.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,9 @@ async function main() {
|
|
|
10
10
|
const targetDir = await generateProject(options);
|
|
11
11
|
const relativeDir = path.relative(process.cwd(), targetDir) || '.';
|
|
12
12
|
const dockerServices = [
|
|
13
|
-
|
|
13
|
+
!['sqlite', 'none'].includes(options.database)
|
|
14
|
+
? options.database
|
|
15
|
+
: null,
|
|
14
16
|
options.features.includes('redis') ? 'redis' : null,
|
|
15
17
|
]
|
|
16
18
|
.filter(Boolean)
|
|
@@ -22,21 +24,23 @@ async function main() {
|
|
|
22
24
|
const seedSteps = shouldRunSeed
|
|
23
25
|
? ['npm run seed']
|
|
24
26
|
: [];
|
|
25
|
-
const databaseSteps = options.orm === '
|
|
26
|
-
? [
|
|
27
|
-
|
|
28
|
-
'npm run migration:run',
|
|
29
|
-
...seedSteps,
|
|
30
|
-
]
|
|
31
|
-
: options.orm === 'drizzle'
|
|
27
|
+
const databaseSteps = options.orm === 'none'
|
|
28
|
+
? []
|
|
29
|
+
: options.orm === 'typeorm'
|
|
32
30
|
? [
|
|
33
|
-
'npm run
|
|
34
|
-
'npm run
|
|
31
|
+
'npm run migration:generate -- src/database/migrations/InitialSchema',
|
|
32
|
+
'npm run migration:run',
|
|
35
33
|
...seedSteps,
|
|
36
34
|
]
|
|
37
|
-
:
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
: options.orm === 'drizzle'
|
|
36
|
+
? [
|
|
37
|
+
'npm run drizzle:generate',
|
|
38
|
+
'npm run drizzle:migrate',
|
|
39
|
+
...seedSteps,
|
|
40
|
+
]
|
|
41
|
+
: [
|
|
42
|
+
'npx prisma migrate dev',
|
|
43
|
+
];
|
|
40
44
|
const steps = [
|
|
41
45
|
`cd ${relativeDir}`,
|
|
42
46
|
...(options.createEnv ? [] : ['cp .env.example .env']),
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,KAAK,UAAU,IAAI;IACf,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IAEnC,IAAI,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,IAAI,GAAG,CAAC;QACnE,MAAM,cAAc,GAAG;YACnB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,KAAK,UAAU,IAAI;IACf,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IAEnC,IAAI,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,IAAI,GAAG,CAAC;QACnE,MAAM,cAAc,GAAG;YACnB,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAC1C,CAAC,CAAC,OAAO,CAAC,QAAQ;gBAClB,CAAC,CAAC,IAAI;YACV,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;SACtD;aACI,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,CAAC;QAEf,MAAM,aAAa,GAAG;YAClB,KAAK;YACL,SAAS;SACZ,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAEjC,MAAM,SAAS,GAAG,aAAa;YAC3B,CAAC,CAAC,CAAC,cAAc,CAAC;YAClB,CAAC,CAAC,EAAE,CAAC;QAET,MAAM,aAAa,GACf,OAAO,CAAC,GAAG,KAAK,MAAM;YAClB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,OAAO,CAAC,GAAG,KAAK,SAAS;gBAC3B,CAAC,CAAC;oBACE,qEAAqE;oBACrE,uBAAuB;oBACvB,GAAG,SAAS;iBACf;gBACD,CAAC,CAAC,OAAO,CAAC,GAAG,KAAK,SAAS;oBACvB,CAAC,CAAC;wBACE,0BAA0B;wBAC1B,yBAAyB;wBACzB,GAAG,SAAS;qBACf;oBACD,CAAC,CAAC;wBACE,wBAAwB;qBAC3B,CAAC;QAEd,MAAM,KAAK,GAAG;YACV,MAAM,WAAW,EAAE;YACnB,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC;YACtD,aAAa;YACb,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,cAAc;gBACrD,CAAC,CAAC,CAAC,wBAAwB,cAAc,EAAE,CAAC;gBAC5C,CAAC,CAAC,EAAE,CAAC;YACT,GAAG,aAAa;YAChB,mBAAmB;SACtB,CAAC;QAEF,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;QAErC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,OAAO,CAAC,WAAW,yBAAyB,CAAC,CAAC,CAAC;IAChF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC"}
|
package/dist/prompts.js
CHANGED
|
@@ -55,16 +55,20 @@ export async function runPrompts() {
|
|
|
55
55
|
});
|
|
56
56
|
handleCancel(orm);
|
|
57
57
|
// 4. Database
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
58
|
+
let database = 'none';
|
|
59
|
+
if (orm !== 'none') {
|
|
60
|
+
const databaseSelection = await select({
|
|
61
|
+
message: 'Which database do you want to use?',
|
|
62
|
+
options: [
|
|
63
|
+
{ value: 'postgres', label: 'PostgreSQL', hint: 'Recommended' },
|
|
64
|
+
{ value: 'mysql', label: 'MySQL' },
|
|
65
|
+
{ value: 'sqlite', label: 'SQLite' },
|
|
66
|
+
{ value: 'mongodb', label: 'MongoDB', hint: 'coming soon' },
|
|
67
|
+
],
|
|
68
|
+
});
|
|
69
|
+
handleCancel(databaseSelection);
|
|
70
|
+
database = databaseSelection;
|
|
71
|
+
}
|
|
68
72
|
// 5. Additional features (one yes/no prompt at a time)
|
|
69
73
|
const features = [];
|
|
70
74
|
const wantsDocker = await confirm({
|
|
@@ -96,16 +100,20 @@ export async function runPrompts() {
|
|
|
96
100
|
if (wantsRedis)
|
|
97
101
|
features.push('redis');
|
|
98
102
|
// 6. Authentication strategy
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
let authStrategy = 'none';
|
|
104
|
+
if (orm !== 'none') {
|
|
105
|
+
const authStrategySelection = await select({
|
|
106
|
+
message: 'Which authentication strategy do you want to use?',
|
|
107
|
+
options: [
|
|
108
|
+
{ value: 'jwt', label: 'JWT', hint: 'Recommended — includes Google/GitHub OAuth' },
|
|
109
|
+
{ value: 'session', label: 'Session/Cookies', hint: 'persistent database-backed session' },
|
|
110
|
+
{ value: 'oauth', label: 'OAuth (Google/GitHub) only', hint: 'no password login' },
|
|
111
|
+
{ value: 'none', label: 'None' },
|
|
112
|
+
],
|
|
113
|
+
});
|
|
114
|
+
handleCancel(authStrategySelection);
|
|
115
|
+
authStrategy = authStrategySelection;
|
|
116
|
+
}
|
|
109
117
|
// 7. Access control (only applicable when authentication is enabled)
|
|
110
118
|
let accessControl = false;
|
|
111
119
|
if (authStrategy !== 'none') {
|
|
@@ -127,9 +135,9 @@ export async function runPrompts() {
|
|
|
127
135
|
projectName: projectName,
|
|
128
136
|
language: language,
|
|
129
137
|
orm: orm,
|
|
130
|
-
database
|
|
138
|
+
database,
|
|
131
139
|
features,
|
|
132
|
-
authStrategy
|
|
140
|
+
authStrategy,
|
|
133
141
|
accessControl,
|
|
134
142
|
createEnv: createEnv,
|
|
135
143
|
};
|
package/dist/prompts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACvF,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,MAAM,YAAY,CAAC;AAkB5B,mCAAmC;AACnC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;AAE3D,MAAM,IAAI,GAAG;;;;;;;;;CASZ,CAAC;AAEF,SAAS,UAAU;IACf,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC,CAAC;AACrF,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAChC,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAClB,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC5B,UAAU,EAAE,CAAC;IACb,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAE7C,kBAAkB;IAClB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;QAC3B,OAAO,EAAE,4BAA4B;QACrC,WAAW,EAAE,aAAa;QAC1B,YAAY,EAAE,aAAa;KAC9B,CAAC,CAAC;IACH,YAAY,CAAC,WAAW,CAAC,CAAC;IAE1B,cAAc;IACd,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC;QAC1B,OAAO,EAAE,2BAA2B;QACpC,OAAO,EAAE;YACL,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE;YACjE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE;SAC/C;KACJ,CAAC,CAAC;IACH,YAAY,CAAC,QAAQ,CAAC,CAAC;IAEvB,mBAAmB;IACnB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC;QACrB,OAAO,EAAE,+BAA+B;QACxC,OAAO,EAAE;YACL,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE;YACzD,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;YACtC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE;YAC1C,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;SACnC;KACJ,CAAC,CAAC;IACH,YAAY,CAAC,GAAG,CAAC,CAAC;IAElB,cAAc;IACd,
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"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"}
|