@exanderal/stackcraft 0.4.2 → 0.6.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 +90 -9
- package/dist/create/config.d.ts +13 -0
- package/dist/create/config.d.ts.map +1 -0
- package/dist/create/config.js +50 -0
- package/dist/create/config.js.map +1 -0
- package/dist/create/index.d.ts +6 -1
- package/dist/create/index.d.ts.map +1 -1
- package/dist/create/index.js +56 -20
- package/dist/create/index.js.map +1 -1
- package/dist/create/scaffolders/__tests__/web-vite.test.js +1 -0
- package/dist/create/scaffolders/__tests__/web-vite.test.js.map +1 -1
- package/dist/create/scaffolders/api-nestjs-graphql.d.ts.map +1 -1
- package/dist/create/scaffolders/api-nestjs-graphql.js +14 -17
- package/dist/create/scaffolders/api-nestjs-graphql.js.map +1 -1
- package/dist/create/scaffolders/api-nestjs-rest.d.ts.map +1 -1
- package/dist/create/scaffolders/api-nestjs-rest.js +14 -17
- package/dist/create/scaffolders/api-nestjs-rest.js.map +1 -1
- package/dist/create/scaffolders/orm.d.ts +6 -0
- package/dist/create/scaffolders/orm.d.ts.map +1 -0
- package/dist/create/scaffolders/orm.js +271 -0
- package/dist/create/scaffolders/orm.js.map +1 -0
- package/dist/create/scaffolders/setup-docker.js +33 -6
- package/dist/create/scaffolders/setup-docker.js.map +1 -1
- package/dist/create/scaffolders/utils/copy.d.ts.map +1 -1
- package/dist/create/scaffolders/utils/copy.js +1 -0
- package/dist/create/scaffolders/utils/copy.js.map +1 -1
- package/dist/create/types.d.ts +2 -0
- package/dist/create/types.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/init/index.d.ts +2 -0
- package/dist/init/index.d.ts.map +1 -0
- package/dist/init/index.js +38 -0
- package/dist/init/index.js.map +1 -0
- package/package.json +3 -2
- package/schema.json +60 -0
- package/templates/api-nestjs-graphql/package.json +1 -3
- package/templates/api-nestjs-rest/package.json +1 -3
- package/templates/base/tools/generators/module/graphql-files/__fileName__.model.ts__tmpl__ +10 -8
- package/templates/base/tools/generators/module/index.js +0 -4
- package/templates/base/tools/generators/module/schema.json +0 -6
- package/templates/orm-kysely/scripts/migration-create.ts +30 -0
- package/templates/orm-kysely/src/common/repositories/entity.repository.ts +33 -0
- package/templates/orm-kysely/src/common/repositories/readonly-entity.repository.ts +46 -0
- package/templates/orm-kysely/src/database/database.types.ts +17 -0
- package/templates/orm-kysely/src/database/migrations/.gitkeep +0 -0
- package/templates/orm-kysely/src/database/seeds/seed.ts +12 -0
- package/templates/orm-kysely/src/database/utils/columns.ts +32 -0
- package/templates/orm-kysely/src/database/utils/index.ts +3 -0
- package/templates/orm-kysely/src/database/utils/indexes.ts +20 -0
- package/templates/orm-kysely/src/database/utils/tables.ts +7 -0
- package/templates/orm-kysely/src/modules/database/database.module.ts +9 -0
- package/templates/orm-kysely/tools/generators/module/files/__fileName__.model.ts__tmpl__ +16 -0
- package/templates/orm-kysely/tools/generators/module/files/__fileName__.module.ts__tmpl__ +9 -0
- package/templates/orm-kysely/tools/generators/module/files/__fileName__.repository.ts__tmpl__ +26 -0
- package/templates/orm-kysely/tools/generators/module/files/__fileName__.service.ts__tmpl__ +28 -0
- package/templates/orm-kysely/tools/generators/module/files/__tests__/__fileName__.integration.spec.ts__tmpl__ +23 -0
- package/templates/orm-kysely/tools/generators/module/graphql-files/__fileName__.model.ts__tmpl__ +24 -0
- package/templates/orm-prisma/prisma/schema.prisma +8 -0
- package/templates/orm-prisma/prisma/seeds/seed.ts +16 -0
- package/templates/orm-prisma/src/modules/database/database.module.ts +8 -0
- package/templates/orm-prisma/src/modules/prisma/prisma.module.ts +9 -0
- package/templates/orm-prisma/src/modules/prisma/prisma.service.ts +9 -0
- package/templates/orm-prisma/tools/generators/module/files/__fileName__.model.ts__tmpl__ +15 -0
- package/templates/orm-prisma/tools/generators/module/files/__fileName__.module.ts__tmpl__ +9 -0
- package/templates/orm-prisma/tools/generators/module/files/__fileName__.repository.ts__tmpl__ +28 -0
- package/templates/orm-prisma/tools/generators/module/files/__fileName__.service.ts__tmpl__ +28 -0
- package/templates/orm-prisma/tools/generators/module/files/__tests__/__fileName__.integration.spec.ts__tmpl__ +23 -0
- package/templates/orm-prisma/tools/generators/module/graphql-files/__fileName__.model.ts__tmpl__ +23 -0
- package/templates/api-nestjs-graphql/src/common/entities/base.entity.ts +0 -21
- package/templates/api-nestjs-graphql/src/common/repositories/entity.repository.ts +0 -21
- package/templates/api-nestjs-graphql/src/common/repositories/readonly-entity.repository.ts +0 -22
- package/templates/api-nestjs-graphql/src/common/services/entity.service.ts +0 -24
- package/templates/api-nestjs-graphql/src/common/services/readonly-entity.service.ts +0 -23
- package/templates/api-nestjs-graphql/src/modules/database/database.module.ts +0 -18
- package/templates/api-nestjs-rest/src/common/entities/base.entity.ts +0 -16
- package/templates/api-nestjs-rest/src/common/repositories/entity.repository.ts +0 -21
- package/templates/api-nestjs-rest/src/common/repositories/readonly-entity.repository.ts +0 -22
- package/templates/api-nestjs-rest/src/common/services/entity.service.ts +0 -24
- package/templates/api-nestjs-rest/src/common/services/readonly-entity.service.ts +0 -23
- package/templates/api-nestjs-rest/src/modules/database/database.module.ts +0 -18
package/README.md
CHANGED
|
@@ -12,6 +12,44 @@ npx @exanderal/stackcraft
|
|
|
12
12
|
|
|
13
13
|
Follow the prompts — you'll have an Nx monorepo with deps installed and ready to run.
|
|
14
14
|
|
|
15
|
+
Add `--full` to unlock ORM and linter selection:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
npx @exanderal/stackcraft --full
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Non-interactive mode
|
|
22
|
+
|
|
23
|
+
Generate a config file with all defaults:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
npx @exanderal/stackcraft init
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This writes `stackcraft.config.json` to the current directory:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"$schema": "https://unpkg.com/@exanderal/stackcraft/schema.json",
|
|
34
|
+
"name": "my-app",
|
|
35
|
+
"backend": "nestjs-rest",
|
|
36
|
+
"orm": "prisma",
|
|
37
|
+
"frontend": "vite",
|
|
38
|
+
"mobile": "none",
|
|
39
|
+
"database": "postgres",
|
|
40
|
+
"packageManager": "pnpm",
|
|
41
|
+
"linter": "eslint"
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Edit the fields you want, then scaffold:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
npx @exanderal/stackcraft --config stackcraft.config.json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Any field omitted from the config will be prompted interactively. The `$schema` enables autocomplete and validation in VS Code — hover over any field to see valid values.
|
|
52
|
+
|
|
15
53
|
## What you get
|
|
16
54
|
|
|
17
55
|
```
|
|
@@ -35,18 +73,32 @@ Choose between REST or GraphQL at setup — both share the same structure:
|
|
|
35
73
|
src/
|
|
36
74
|
├── modules/ # domain layer — model, repository, service, module
|
|
37
75
|
├── api/ # REST controllers
|
|
38
|
-
|
|
39
|
-
└── common/ # shared base classes (EntityRepository, EntityService)
|
|
76
|
+
└── resolvers/ # GraphQL resolvers
|
|
40
77
|
```
|
|
41
78
|
|
|
42
|
-
- NestJS
|
|
79
|
+
- NestJS
|
|
43
80
|
- PostgreSQL or MySQL
|
|
44
|
-
-
|
|
45
|
-
- UUID primary keys
|
|
81
|
+
- **Prisma** (default) or **Kysely** (power user, use `--full` to select)
|
|
46
82
|
- REST: Swagger UI at `/api`, spec written to `swagger.json` on startup
|
|
47
83
|
- GraphQL: schema auto-generated to `schema.gql` on startup (code-first)
|
|
48
84
|
- `.env` pre-configured with local database credentials
|
|
49
85
|
|
|
86
|
+
#### Prisma (default)
|
|
87
|
+
|
|
88
|
+
- `prisma/schema.prisma` with your chosen database provider
|
|
89
|
+
- `PrismaService` as a global NestJS provider
|
|
90
|
+
- Generator templates: `generate:module` outputs a Prisma-based repository
|
|
91
|
+
- Single `DATABASE_URL` connection string in `.env`
|
|
92
|
+
|
|
93
|
+
#### Kysely (`--full` only)
|
|
94
|
+
|
|
95
|
+
- `src/database/` — `database.types.ts`, `migrations/`, `seeds/`, `utils/`
|
|
96
|
+
- `ReadonlyEntityRepository` and `EntityRepository` base classes
|
|
97
|
+
- `KyselyService` as a global NestJS provider
|
|
98
|
+
- `scripts/migrate.ts` — run/revert migrations; `scripts/migration-create.ts` — generate timestamped migration files
|
|
99
|
+
- Generator templates: `generate:module` outputs a Kysely-based repository
|
|
100
|
+
- Individual `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_NAME` vars in `.env`
|
|
101
|
+
|
|
50
102
|
### Frontend (`apps/web`)
|
|
51
103
|
|
|
52
104
|
- Vite + React or Next.js
|
|
@@ -93,6 +145,32 @@ pnpm codegen # generate types once
|
|
|
93
145
|
pnpm codegen:watch # watch for schema/spec changes and regenerate automatically
|
|
94
146
|
```
|
|
95
147
|
|
|
148
|
+
### Database scripts
|
|
149
|
+
|
|
150
|
+
**Prisma:**
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
pnpm db:migrate # run pending migrations (prisma migrate dev)
|
|
154
|
+
pnpm db:migrate:deploy # deploy migrations in CI/production
|
|
155
|
+
pnpm db:seed # run the seeder
|
|
156
|
+
pnpm db:studio # open Prisma Studio
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Kysely:**
|
|
160
|
+
|
|
161
|
+
```sh
|
|
162
|
+
pnpm db:migrate # run pending migrations
|
|
163
|
+
pnpm db:rollback # revert the last migration
|
|
164
|
+
pnpm db:seed # run the seeder
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Creating a new migration file is a backend-level command:
|
|
168
|
+
|
|
169
|
+
```sh
|
|
170
|
+
pnpm --filter backend migration:new <name>
|
|
171
|
+
# → creates apps/backend/src/database/migrations/<timestamp>-<name>.ts
|
|
172
|
+
```
|
|
173
|
+
|
|
96
174
|
Typical dev workflow — run both in parallel:
|
|
97
175
|
|
|
98
176
|
```sh
|
|
@@ -111,7 +189,7 @@ Generate a new domain module (model + repository + service):
|
|
|
111
189
|
pnpm generate:module --name=trainer
|
|
112
190
|
```
|
|
113
191
|
|
|
114
|
-
|
|
192
|
+
The generated repository and service match your chosen ORM — Prisma or Kysely.
|
|
115
193
|
|
|
116
194
|
Generate a REST controller:
|
|
117
195
|
|
|
@@ -156,12 +234,13 @@ const { data, loading } = useGetTrainersQuery()
|
|
|
156
234
|
|---|---|
|
|
157
235
|
| Monorepo | Nx |
|
|
158
236
|
| Package manager | pnpm or npm |
|
|
159
|
-
| Backend | NestJS
|
|
237
|
+
| Backend | NestJS |
|
|
238
|
+
| ORM | Prisma (default) or Kysely (`--full`) |
|
|
160
239
|
| Database | PostgreSQL or MySQL |
|
|
161
240
|
| Frontend | Vite + React or Next.js |
|
|
162
241
|
| Mobile | Expo + Expo Router |
|
|
163
242
|
| Styles | Tailwind CSS v4 |
|
|
164
|
-
| Linter / formatter | ESLint + Prettier or Biome |
|
|
243
|
+
| Linter / formatter | ESLint + Prettier or Biome (`--full`) |
|
|
165
244
|
| GraphQL client | Apollo Client |
|
|
166
245
|
| REST types | @hey-api/openapi-ts |
|
|
167
246
|
| GraphQL types + hooks | @graphql-codegen/cli |
|
|
@@ -180,8 +259,10 @@ const { data, loading } = useGetTrainersQuery()
|
|
|
180
259
|
- [x] Interactive `generate:module` prompt
|
|
181
260
|
- [x] Biome as an alternative to ESLint + Prettier
|
|
182
261
|
- [x] Docker Compose for local database + per-app `.env` files
|
|
262
|
+
- [x] Prisma ORM (default)
|
|
263
|
+
- [x] Kysely ORM with repository abstraction (`--full`)
|
|
264
|
+
- [x] `stackcraft init` + `--config` for non-interactive use
|
|
183
265
|
- [ ] `stackcraft add` addon system (auth, Supabase, etc.)
|
|
184
|
-
- [ ] Presets and `--config` for non-interactive use
|
|
185
266
|
|
|
186
267
|
## License
|
|
187
268
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Backend, Database, Frontend, Linter, Mobile, ORM, PackageManager } from './types.js';
|
|
2
|
+
export interface ConfigFile {
|
|
3
|
+
name?: string;
|
|
4
|
+
backend?: Backend;
|
|
5
|
+
orm?: ORM;
|
|
6
|
+
frontend?: Frontend;
|
|
7
|
+
mobile?: Mobile;
|
|
8
|
+
database?: Database;
|
|
9
|
+
packageManager?: PackageManager;
|
|
10
|
+
linter?: Linter;
|
|
11
|
+
}
|
|
12
|
+
export declare function loadConfig(configPath: string): Promise<ConfigFile>;
|
|
13
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/create/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAElG,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,GAAG,CAAC,EAAE,GAAG,CAAA;IACT,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAaD,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAsCxE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
const VALID = {
|
|
4
|
+
name: [],
|
|
5
|
+
backend: ['nestjs-rest', 'nestjs-graphql'],
|
|
6
|
+
orm: ['prisma', 'kysely'],
|
|
7
|
+
frontend: ['vite', 'nextjs'],
|
|
8
|
+
mobile: ['none', 'expo'],
|
|
9
|
+
database: ['postgres', 'mysql'],
|
|
10
|
+
packageManager: ['pnpm', 'npm'],
|
|
11
|
+
linter: ['eslint', 'biome'],
|
|
12
|
+
};
|
|
13
|
+
export async function loadConfig(configPath) {
|
|
14
|
+
const abs = resolve(process.cwd(), configPath);
|
|
15
|
+
let raw;
|
|
16
|
+
try {
|
|
17
|
+
raw = await readFile(abs, 'utf-8');
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
throw new Error(`Config file not found: ${abs}`);
|
|
21
|
+
}
|
|
22
|
+
let parsed;
|
|
23
|
+
try {
|
|
24
|
+
parsed = JSON.parse(raw);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
throw new Error(`Config file is not valid JSON: ${abs}`);
|
|
28
|
+
}
|
|
29
|
+
const errors = [];
|
|
30
|
+
for (const [field, valid] of Object.entries(VALID)) {
|
|
31
|
+
const key = field;
|
|
32
|
+
const value = parsed[key];
|
|
33
|
+
if (value === undefined)
|
|
34
|
+
continue;
|
|
35
|
+
if (key === 'name') {
|
|
36
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
37
|
+
errors.push(`"name" must be a non-empty string`);
|
|
38
|
+
}
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (!valid.includes(value)) {
|
|
42
|
+
errors.push(`"${key}" must be one of: ${valid.join(', ')} — got "${value}"`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (errors.length > 0) {
|
|
46
|
+
throw new Error(`Invalid config:\n${errors.map((e) => ` • ${e}`).join('\n')}`);
|
|
47
|
+
}
|
|
48
|
+
return parsed;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/create/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAcnC,MAAM,KAAK,GAAgD;IACzD,IAAI,EAAE,EAAE;IACR,OAAO,EAAE,CAAC,aAAa,EAAE,gBAAgB,CAAC;IAC1C,GAAG,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;IACzB,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC5B,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC;IAC/B,cAAc,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC;IAC/B,MAAM,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B,CAAA;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAkB;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAA;IAC9C,IAAI,GAAW,CAAA;IACf,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAA;IAClD,CAAC;IAED,IAAI,MAA+B,CAAA;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,EAAE,CAAC,CAAA;IAC1D,CAAC;IAED,MAAM,MAAM,GAAa,EAAE,CAAA;IAE3B,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,MAAM,GAAG,GAAG,KAAyB,CAAA;QACrC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;QACzB,IAAI,KAAK,KAAK,SAAS;YAAE,SAAQ;QACjC,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;YACnB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC/C,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAA;YAClD,CAAC;YACD,SAAQ;QACV,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAe,CAAC,EAAE,CAAC;YACrC,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,qBAAqB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,KAAK,GAAG,CAAC,CAAA;QAC9E,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACjF,CAAC;IAED,OAAO,MAAoB,CAAA;AAC7B,CAAC"}
|
package/dist/create/index.d.ts
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
interface CreateOptions {
|
|
2
|
+
fullMode?: boolean;
|
|
3
|
+
configPath?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function create({ fullMode, configPath }?: CreateOptions): Promise<void>;
|
|
6
|
+
export {};
|
|
2
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/create/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/create/index.ts"],"names":[],"mappings":"AAMA,UAAU,aAAa;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,wBAAsB,MAAM,CAAC,EAAE,QAAgB,EAAE,UAAU,EAAE,GAAE,aAAkB,iBAuIhF"}
|
package/dist/create/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { cancel, intro, isCancel, outro, select, spinner, text } from '@clack/prompts';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
|
+
import { loadConfig } from './config.js';
|
|
3
4
|
import { scaffold } from './scaffold.js';
|
|
4
|
-
export async function create() {
|
|
5
|
+
export async function create({ fullMode = false, configPath } = {}) {
|
|
6
|
+
const cfg = configPath ? await loadConfig(configPath) : {};
|
|
5
7
|
intro('stackcraft — spin up a production-ready monorepo');
|
|
6
|
-
const projectName = await text({
|
|
8
|
+
const projectName = cfg.name ?? await text({
|
|
7
9
|
message: 'Project name',
|
|
8
10
|
placeholder: 'my-app',
|
|
9
11
|
validate: (v) => (!v ? 'Required' : undefined),
|
|
@@ -12,18 +14,40 @@ export async function create() {
|
|
|
12
14
|
cancel('Cancelled.');
|
|
13
15
|
process.exit(0);
|
|
14
16
|
}
|
|
15
|
-
const backend = await select({
|
|
17
|
+
const backend = cfg.backend ?? await select({
|
|
16
18
|
message: 'Backend',
|
|
17
19
|
options: [
|
|
18
|
-
{ value: 'nestjs-rest', label: 'NestJS REST', hint: 'REST API
|
|
19
|
-
{ value: 'nestjs-graphql', label: 'NestJS GraphQL', hint: 'Code-first GraphQL
|
|
20
|
+
{ value: 'nestjs-rest', label: 'NestJS REST', hint: 'REST API' },
|
|
21
|
+
{ value: 'nestjs-graphql', label: 'NestJS GraphQL', hint: 'Code-first GraphQL' },
|
|
20
22
|
],
|
|
21
23
|
});
|
|
22
24
|
if (isCancel(backend)) {
|
|
23
25
|
cancel('Cancelled.');
|
|
24
26
|
process.exit(0);
|
|
25
27
|
}
|
|
26
|
-
const
|
|
28
|
+
const ormFromConfig = cfg.orm;
|
|
29
|
+
let orm;
|
|
30
|
+
if (ormFromConfig) {
|
|
31
|
+
orm = ormFromConfig;
|
|
32
|
+
}
|
|
33
|
+
else if (fullMode) {
|
|
34
|
+
const ormAnswer = await select({
|
|
35
|
+
message: 'ORM',
|
|
36
|
+
options: [
|
|
37
|
+
{ value: 'prisma', label: 'Prisma', hint: 'recommended — schema-first, great DX' },
|
|
38
|
+
{ value: 'kysely', label: 'Kysely', hint: 'type-safe SQL query builder' },
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
if (isCancel(ormAnswer)) {
|
|
42
|
+
cancel('Cancelled.');
|
|
43
|
+
process.exit(0);
|
|
44
|
+
}
|
|
45
|
+
orm = ormAnswer;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
orm = 'prisma';
|
|
49
|
+
}
|
|
50
|
+
const frontend = cfg.frontend ?? await select({
|
|
27
51
|
message: 'Frontend',
|
|
28
52
|
options: [
|
|
29
53
|
{ value: 'vite', label: 'Vite + React', hint: 'Fast dev server, great for SPAs' },
|
|
@@ -34,7 +58,7 @@ export async function create() {
|
|
|
34
58
|
cancel('Cancelled.');
|
|
35
59
|
process.exit(0);
|
|
36
60
|
}
|
|
37
|
-
const mobile = await select({
|
|
61
|
+
const mobile = cfg.mobile ?? await select({
|
|
38
62
|
message: 'Mobile',
|
|
39
63
|
options: [
|
|
40
64
|
{ value: 'none', label: 'None' },
|
|
@@ -45,7 +69,7 @@ export async function create() {
|
|
|
45
69
|
cancel('Cancelled.');
|
|
46
70
|
process.exit(0);
|
|
47
71
|
}
|
|
48
|
-
const database = await select({
|
|
72
|
+
const database = cfg.database ?? await select({
|
|
49
73
|
message: 'Database',
|
|
50
74
|
options: [
|
|
51
75
|
{ value: 'postgres', label: 'PostgreSQL', hint: 'recommended' },
|
|
@@ -56,7 +80,7 @@ export async function create() {
|
|
|
56
80
|
cancel('Cancelled.');
|
|
57
81
|
process.exit(0);
|
|
58
82
|
}
|
|
59
|
-
const packageManager = await select({
|
|
83
|
+
const packageManager = cfg.packageManager ?? await select({
|
|
60
84
|
message: 'Package manager',
|
|
61
85
|
options: [
|
|
62
86
|
{ value: 'pnpm', label: 'pnpm', hint: 'recommended' },
|
|
@@ -67,16 +91,27 @@ export async function create() {
|
|
|
67
91
|
cancel('Cancelled.');
|
|
68
92
|
process.exit(0);
|
|
69
93
|
}
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
94
|
+
const linterFromConfig = cfg.linter;
|
|
95
|
+
let linter;
|
|
96
|
+
if (linterFromConfig) {
|
|
97
|
+
linter = linterFromConfig;
|
|
98
|
+
}
|
|
99
|
+
else if (fullMode) {
|
|
100
|
+
const linterAnswer = await select({
|
|
101
|
+
message: 'Linter / formatter',
|
|
102
|
+
options: [
|
|
103
|
+
{ value: 'eslint', label: 'ESLint + Prettier', hint: 'recommended' },
|
|
104
|
+
{ value: 'biome', label: 'Biome', hint: 'fast all-in-one, replaces both' },
|
|
105
|
+
],
|
|
106
|
+
});
|
|
107
|
+
if (isCancel(linterAnswer)) {
|
|
108
|
+
cancel('Cancelled.');
|
|
109
|
+
process.exit(0);
|
|
110
|
+
}
|
|
111
|
+
linter = linterAnswer;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
linter = 'eslint';
|
|
80
115
|
}
|
|
81
116
|
const config = {
|
|
82
117
|
projectName: projectName,
|
|
@@ -84,7 +119,8 @@ export async function create() {
|
|
|
84
119
|
backend: backend,
|
|
85
120
|
database: database,
|
|
86
121
|
mobile: mobile,
|
|
87
|
-
linter
|
|
122
|
+
linter,
|
|
123
|
+
orm,
|
|
88
124
|
packageManager: packageManager,
|
|
89
125
|
targetDir: resolve(process.cwd(), projectName),
|
|
90
126
|
};
|
package/dist/create/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/create/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AACtF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/create/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-vite.test.js","sourceRoot":"","sources":["../../../../src/create/scaffolders/__tests__/web-vite.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE5D,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,CAAC;IACjC,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;IAC3C,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;IACxC,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACtC,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACvC,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;CAChD,CAAC,CAAC,CAAA;AAEH,MAAM,MAAM,GAAG;IACb,WAAW,EAAE,QAAQ;IACrB,QAAQ,EAAE,MAAe;IACzB,OAAO,EAAE,aAAsB;IAC/B,QAAQ,EAAE,UAAmB;IAC7B,MAAM,EAAE,MAAe;IACvB,MAAM,EAAE,QAAiB;IACzB,cAAc,EAAE,MAAe;IAC/B,SAAS,EAAE,aAAa;CACzB,CAAA;AAED,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,SAAS,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,CAAA;IAEnC,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;QAClD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAA;QAEvD,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;QAE1B,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,CAChC,MAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC,EACnC,EAAE,SAAS,EAAE,IAAI,EAAE,CACpB,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;QAC/C,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAA;QAEvD,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;QAE1B,MAAM,CAAC,EAAE,CAAC,CAAC,oBAAoB,CAC7B,MAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC,EACnC,MAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC,EACnC,EAAE,SAAS,EAAE,IAAI,EAAE,CACpB,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"web-vite.test.js","sourceRoot":"","sources":["../../../../src/create/scaffolders/__tests__/web-vite.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE5D,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,CAAC;IACjC,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;IAC3C,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;IACxC,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACtC,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACvC,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;CAChD,CAAC,CAAC,CAAA;AAEH,MAAM,MAAM,GAAG;IACb,WAAW,EAAE,QAAQ;IACrB,QAAQ,EAAE,MAAe;IACzB,OAAO,EAAE,aAAsB;IAC/B,QAAQ,EAAE,UAAmB;IAC7B,MAAM,EAAE,MAAe;IACvB,MAAM,EAAE,QAAiB;IACzB,GAAG,EAAE,QAAiB;IACtB,cAAc,EAAE,MAAe;IAC/B,SAAS,EAAE,aAAa;CACzB,CAAA;AAED,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,SAAS,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,CAAA;IAEnC,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;QAClD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAA;QAEvD,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;QAE1B,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,CAChC,MAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC,EACnC,EAAE,SAAS,EAAE,IAAI,EAAE,CACpB,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;QAC/C,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAA;QAEvD,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;QAE1B,MAAM,CAAC,EAAE,CAAC,CAAC,oBAAoB,CAC7B,MAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC,EACnC,MAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC,EACnC,EAAE,SAAS,EAAE,IAAI,EAAE,CACpB,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-nestjs-graphql.d.ts","sourceRoot":"","sources":["../../../src/create/scaffolders/api-nestjs-graphql.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"api-nestjs-graphql.d.ts","sourceRoot":"","sources":["../../../src/create/scaffolders/api-nestjs-graphql.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAOhD,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,aAAa,iBA+BhE"}
|
|
@@ -1,33 +1,30 @@
|
|
|
1
1
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { injectOrmDeps, writeKyselyService, writeMigrateScript, writeModuleGeneratorIndex } from './orm.js';
|
|
4
5
|
import { copyTemplate } from './utils/copy.js';
|
|
5
6
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
7
|
const TEMPLATES_DIR = join(__dirname, '..', '..', '..', 'templates');
|
|
7
|
-
const DB_CONFIG = {
|
|
8
|
-
postgres: { type: 'postgres', port: '5432', driver: 'pg', driverVersion: '^8.0.0', typesPackage: '@types/pg', typesVersion: '^8.0.0' },
|
|
9
|
-
mysql: { type: 'mysql', port: '3306', driver: 'mysql2', driverVersion: '^3.0.0', typesPackage: null, typesVersion: null },
|
|
10
|
-
};
|
|
11
8
|
export async function scaffoldNestjsGraphql(config) {
|
|
12
9
|
const appDir = join(config.targetDir, 'apps', 'backend');
|
|
13
10
|
await mkdir(appDir, { recursive: true });
|
|
14
|
-
const
|
|
11
|
+
const dbProvider = config.database === 'postgres' ? 'postgresql' : 'mysql';
|
|
15
12
|
await copyTemplate(join(TEMPLATES_DIR, 'api-nestjs-graphql'), appDir, {
|
|
16
13
|
projectName: config.projectName,
|
|
17
|
-
dbType: db.type,
|
|
18
|
-
dbPort: db.port,
|
|
19
14
|
});
|
|
20
|
-
await
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (
|
|
28
|
-
|
|
15
|
+
await copyTemplate(join(TEMPLATES_DIR, `orm-${config.orm}`), appDir, {
|
|
16
|
+
projectName: config.projectName,
|
|
17
|
+
dbProvider,
|
|
18
|
+
});
|
|
19
|
+
// Push ORM generator templates to workspace root, overwriting base TypeORM generators
|
|
20
|
+
await copyTemplate(join(TEMPLATES_DIR, `orm-${config.orm}`, 'tools'), join(config.targetDir, 'tools'), { projectName: config.projectName, dbProvider });
|
|
21
|
+
await injectOrmDeps(appDir, config);
|
|
22
|
+
if (config.orm === 'kysely') {
|
|
23
|
+
await writeKyselyService(appDir, config);
|
|
24
|
+
await writeMigrateScript(appDir, config);
|
|
29
25
|
}
|
|
30
|
-
await
|
|
26
|
+
await writeModuleGeneratorIndex(config.targetDir, config.backend);
|
|
27
|
+
await setupGraphqlCodegen(config.targetDir);
|
|
31
28
|
}
|
|
32
29
|
async function setupGraphqlCodegen(targetDir) {
|
|
33
30
|
const typesDir = join(targetDir, 'packages', 'types');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-nestjs-graphql.js","sourceRoot":"","sources":["../../../src/create/scaffolders/api-nestjs-graphql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AACzD,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAA;AAEpE,MAAM,
|
|
1
|
+
{"version":3,"file":"api-nestjs-graphql.js","sourceRoot":"","sources":["../../../src/create/scaffolders/api-nestjs-graphql.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-nestjs-rest.d.ts","sourceRoot":"","sources":["../../../src/create/scaffolders/api-nestjs-rest.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"api-nestjs-rest.d.ts","sourceRoot":"","sources":["../../../src/create/scaffolders/api-nestjs-rest.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAOhD,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,aAAa,iBA+B7D"}
|
|
@@ -1,33 +1,30 @@
|
|
|
1
1
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { injectOrmDeps, writeKyselyService, writeMigrateScript, writeModuleGeneratorIndex } from './orm.js';
|
|
4
5
|
import { copyTemplate } from './utils/copy.js';
|
|
5
6
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
7
|
const TEMPLATES_DIR = join(__dirname, '..', '..', '..', 'templates');
|
|
7
|
-
const DB_CONFIG = {
|
|
8
|
-
postgres: { type: 'postgres', port: '5432', driver: 'pg', driverVersion: '^8.0.0', typesPackage: '@types/pg', typesVersion: '^8.0.0' },
|
|
9
|
-
mysql: { type: 'mysql', port: '3306', driver: 'mysql2', driverVersion: '^3.0.0', typesPackage: null, typesVersion: null },
|
|
10
|
-
};
|
|
11
8
|
export async function scaffoldNestjsRest(config) {
|
|
12
9
|
const appDir = join(config.targetDir, 'apps', 'backend');
|
|
13
10
|
await mkdir(appDir, { recursive: true });
|
|
14
|
-
const
|
|
11
|
+
const dbProvider = config.database === 'postgres' ? 'postgresql' : 'mysql';
|
|
15
12
|
await copyTemplate(join(TEMPLATES_DIR, 'api-nestjs-rest'), appDir, {
|
|
16
13
|
projectName: config.projectName,
|
|
17
|
-
dbType: db.type,
|
|
18
|
-
dbPort: db.port,
|
|
19
14
|
});
|
|
20
|
-
await
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (
|
|
28
|
-
|
|
15
|
+
await copyTemplate(join(TEMPLATES_DIR, `orm-${config.orm}`), appDir, {
|
|
16
|
+
projectName: config.projectName,
|
|
17
|
+
dbProvider,
|
|
18
|
+
});
|
|
19
|
+
// Push ORM generator templates to workspace root, overwriting base TypeORM generators
|
|
20
|
+
await copyTemplate(join(TEMPLATES_DIR, `orm-${config.orm}`, 'tools'), join(config.targetDir, 'tools'), { projectName: config.projectName, dbProvider });
|
|
21
|
+
await injectOrmDeps(appDir, config);
|
|
22
|
+
if (config.orm === 'kysely') {
|
|
23
|
+
await writeKyselyService(appDir, config);
|
|
24
|
+
await writeMigrateScript(appDir, config);
|
|
29
25
|
}
|
|
30
|
-
await
|
|
26
|
+
await writeModuleGeneratorIndex(config.targetDir, config.backend);
|
|
27
|
+
await setupRestCodegen(config.targetDir);
|
|
31
28
|
}
|
|
32
29
|
async function setupRestCodegen(targetDir) {
|
|
33
30
|
const typesDir = join(targetDir, 'packages', 'types');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-nestjs-rest.js","sourceRoot":"","sources":["../../../src/create/scaffolders/api-nestjs-rest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AACzD,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAA;AAEpE,MAAM,
|
|
1
|
+
{"version":3,"file":"api-nestjs-rest.js","sourceRoot":"","sources":["../../../src/create/scaffolders/api-nestjs-rest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Backend, ProjectConfig } from '../types.js';
|
|
2
|
+
export declare function writeModuleGeneratorIndex(targetDir: string, backend: Backend): Promise<void>;
|
|
3
|
+
export declare function injectOrmDeps(appDir: string, config: ProjectConfig): Promise<void>;
|
|
4
|
+
export declare function writeKyselyService(appDir: string, config: ProjectConfig): Promise<void>;
|
|
5
|
+
export declare function writeMigrateScript(appDir: string, config: ProjectConfig): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=orm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orm.d.ts","sourceRoot":"","sources":["../../../src/create/scaffolders/orm.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAqDzD,wBAAsB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,iBAOlF;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,iBAoCxE;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,iBAmE7E;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,iBAiH7E"}
|