nestforge-generator 0.1.1 → 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 +28 -17
- package/README.pt-BR.md +28 -17
- 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,19 +2,19 @@
|
|
|
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.
|
|
6
|
-
|
|
7
|
-
Install the package locally:
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install nestforge-generator
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
Run the locally installed CLI:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npx nestforge
|
|
17
|
-
```
|
|
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:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx nestforge
|
|
17
|
+
```
|
|
18
18
|
|
|
19
19
|
For the testing guide, CLI prompts, and complete checklist, see [`TESTING.md`](TESTING.md).
|
|
20
20
|
|
|
@@ -22,7 +22,7 @@ For the testing guide, CLI prompts, and complete checklist, see [`TESTING.md`](T
|
|
|
22
22
|
|
|
23
23
|
- Interactive prompts using `@clack/prompts`;
|
|
24
24
|
- TypeScript or JavaScript generation;
|
|
25
|
-
- Prisma, TypeORM,
|
|
25
|
+
- Prisma, TypeORM, Drizzle ORM, or no ORM;
|
|
26
26
|
- PostgreSQL, MySQL, and SQLite;
|
|
27
27
|
- JWT, Session/Cookies, OAuth-only, or no authentication;
|
|
28
28
|
- optional Docker;
|
|
@@ -105,6 +105,16 @@ The Drizzle template includes:
|
|
|
105
105
|
|
|
106
106
|
After generation, only the schema and driver for the selected database remain in the project.
|
|
107
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
|
+
|
|
108
118
|
## Authentication strategies
|
|
109
119
|
|
|
110
120
|
### JWT
|
|
@@ -247,7 +257,7 @@ When requested, the CLI automatically creates `.env` from the already processed
|
|
|
247
257
|
| ORM: Prisma | ✅ Implemented |
|
|
248
258
|
| ORM: TypeORM | ✅ Implemented |
|
|
249
259
|
| ORM: Drizzle | ✅ Implemented |
|
|
250
|
-
| ORM: None |
|
|
260
|
+
| ORM: None | ✅ Implemented |
|
|
251
261
|
| Database: PostgreSQL | ✅ Implemented |
|
|
252
262
|
| Database: MySQL | ✅ Implemented |
|
|
253
263
|
| Database: SQLite | ✅ Implemented |
|
|
@@ -282,6 +292,8 @@ Coverage includes:
|
|
|
282
292
|
- Drizzle with PostgreSQL;
|
|
283
293
|
- Drizzle with MySQL;
|
|
284
294
|
- Drizzle with SQLite;
|
|
295
|
+
- no ORM with TypeScript;
|
|
296
|
+
- no ORM with JavaScript, Docker, and Redis;
|
|
285
297
|
- JWT;
|
|
286
298
|
- Session/Cookies;
|
|
287
299
|
- OAuth-only;
|
|
@@ -367,12 +379,11 @@ npm publish
|
|
|
367
379
|
The build:
|
|
368
380
|
|
|
369
381
|
1. compiles the CLI;
|
|
370
|
-
2. copies the
|
|
382
|
+
2. copies the source templates;
|
|
371
383
|
3. prepares the package published to npm.
|
|
372
384
|
|
|
373
385
|
## Next steps
|
|
374
386
|
|
|
375
|
-
- an option without an ORM;
|
|
376
387
|
- MongoDB;
|
|
377
388
|
- more complete project and package name validation;
|
|
378
389
|
- expand the smoke-test matrix with real PostgreSQL and MySQL services;
|
package/README.pt-BR.md
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
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.
|
|
6
|
-
|
|
7
|
-
Instale o pacote localmente:
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install nestforge-generator
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
Execute a CLI instalada localmente:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npx nestforge
|
|
17
|
-
```
|
|
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:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx nestforge
|
|
17
|
+
```
|
|
18
18
|
|
|
19
19
|
Para o guia de testes, perguntas da CLI e checklist completo, consulte [`TESTING.pt-BR.md`](TESTING.pt-BR.md).
|
|
20
20
|
|
|
@@ -22,7 +22,7 @@ Para o guia de testes, perguntas da CLI e checklist completo, consulte [`TESTING
|
|
|
22
22
|
|
|
23
23
|
* Prompts interativos usando @clack/prompts;
|
|
24
24
|
* geração em TypeScript ou JavaScript;
|
|
25
|
-
* Prisma, TypeORM
|
|
25
|
+
* Prisma, TypeORM, Drizzle ORM ou nenhum ORM;
|
|
26
26
|
* PostgreSQL, MySQL e SQLite;
|
|
27
27
|
* autenticação JWT, Session/Cookies, OAuth-only ou nenhuma;
|
|
28
28
|
* Docker opcional;
|
|
@@ -105,6 +105,16 @@ O template Drizzle inclui:
|
|
|
105
105
|
|
|
106
106
|
Depois da geração, somente o schema e o driver do banco selecionado permanecem no projeto.
|
|
107
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
|
+
|
|
108
118
|
## Estratégias de autenticação
|
|
109
119
|
|
|
110
120
|
### JWT
|
|
@@ -248,7 +258,7 @@ processado.
|
|
|
248
258
|
| ORM: Prisma | ✅ Implementado |
|
|
249
259
|
| ORM: TypeORM | ✅ Implementado |
|
|
250
260
|
| ORM: Drizzle | ✅ Implementado |
|
|
251
|
-
| ORM: Nenhum |
|
|
261
|
+
| ORM: Nenhum | ✅ Implementado |
|
|
252
262
|
| Banco: PostgreSQL | ✅ Implementado |
|
|
253
263
|
| Banco: MySQL | ✅ Implementado |
|
|
254
264
|
| Banco: SQLite | ✅ Implementado |
|
|
@@ -281,6 +291,8 @@ A cobertura inclui:
|
|
|
281
291
|
* Drizzle com PostgreSQL;
|
|
282
292
|
* Drizzle com MySQL;
|
|
283
293
|
* Drizzle com SQLite;
|
|
294
|
+
* sem ORM com TypeScript;
|
|
295
|
+
* sem ORM com JavaScript, Docker e Redis;
|
|
284
296
|
* JWT;
|
|
285
297
|
* Session/Cookies;
|
|
286
298
|
* OAuth-only;
|
|
@@ -366,12 +378,11 @@ npm publish
|
|
|
366
378
|
O build:
|
|
367
379
|
|
|
368
380
|
1. compila a CLI;
|
|
369
|
-
2. copia os templates
|
|
381
|
+
2. copia os templates-fonte;
|
|
370
382
|
3. prepara o pacote publicado no npm.
|
|
371
383
|
|
|
372
384
|
## Próximos itens
|
|
373
385
|
|
|
374
|
-
* opção sem ORM;
|
|
375
386
|
* MongoDB;
|
|
376
387
|
* validação mais completa do nome do projeto e do pacote;
|
|
377
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":"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"}
|
|
@@ -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":"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;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,sBAAsB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;AACvE,MAAM,uBAAuB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;AAE9E,2EAA2E;AAC3E,MAAM,gBAAgB,GAAG;IACrB,QAAQ;IACR,SAAS;IACT,SAAS;IACT,MAAM;CACT,CAAC;AACF,MAAM,qBAAqB,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;AAC3D,MAAM,qBAAqB,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC9D,MAAM,2BAA2B,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAExE,KAAK,UAAU,oBAAoB;IAC/B,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,CAAC;QAC9C,OAAO,sBAAsB,CAAC;IAClC,CAAC;IAED,OAAO,uBAAuB,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAuB;IACzD,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,GAC5F,OAAO,CAAC;IAEZ,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CACX,kBAAkB,QAAQ,6FAA6F,CAC1H,CAAC;IACN,CAAC;IAED,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACX,qBAAqB,GAAG,6CAA6C,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAE,8BAA8B,CAClI,CAAC;IACN,CAAC;IAED,IAAI,GAAG,KAAK,MAAM,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACzF,CAAC;IAED,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CACX,QAAQ,QAAQ,wDAAwD,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,CACzI,CAAC;IACN,CAAC;IAED,IAAI,GAAG,KAAK,MAAM,IAAI,YAAY,KAAK,MAAM,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAC;IAC1G,CAAC;IAED,IAAI,GAAG,KAAK,MAAM,IAAI,aAAa,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC;IACnG,CAAC;IAED,IAAI,CAAC,2BAA2B,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CACX,QAAQ,YAAY,uEAAuE,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,2EAA2E,CAC/M,CAAC;IACN,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,oBAAoB,EAAE,CAAC;IACnD,MAAM,YAAY,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;IACrD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;IAE3D,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,QAAQ,WAAW,0EAA0E,CAAC,CAAC;IACnH,CAAC;IAED,MAAM,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAEtC,MAAM,eAAe,GAAG,oBAAoB,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IAE9F,MAAM,iBAAiB,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IACpD,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACjB,MAAM,mBAAmB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACnD,CAAC;IACD,MAAM,wBAAwB,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAC3D,MAAM,mBAAmB,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IACtD,MAAM,0BAA0B,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAE7D,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACjB,MAAM,mBAAmB,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,sBAAsB,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,aAAa,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAE5C,IAAI,SAAS,EAAE,CAAC;QACZ,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,SAAS,oBAAoB,CACzB,QAAkB,EAClB,aAAsB,EACtB,QAAgB,EAChB,YAAoB;IAEpB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAElC,IAAI,aAAa,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,QAAQ,YAAY,EAAE,CAAC,CAAC;IAEpC,IAAI,YAAY,KAAK,MAAM,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,CAAC;IAED,IAAI,YAAY,KAAK,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,YAAY,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,SAAiB,EAAE,eAA4B;IAC5E,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,OAAO;IAE1C,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC;IACpD,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,WAAmB;IAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACvC,GAAG,CAAC,IAAI,GAAG,WAAW,CAAC;IACvB,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAEhD,MAAM,WAAW,GAAG;QAChB,WAAW;QACX,iBAAiB;KACpB,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACnC,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,OAAO,CACV,CAAC;QACF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAC1B,eAAe,EACf,KAAK,WAAW,EAAE,CACrB,CAAC;QAEF,MAAM,EAAE,CAAC,SAAS,CACd,UAAU,EACV,OAAO,EACP,OAAO,CACV,CAAC;IACN,CAAC;AACL,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,SAAiB;IAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAE7C,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;QACtC,OAAO;IACX,CAAC;IAED,MAAM,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AACxC,CAAC"}
|
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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"}
|