@exanderal/stackcraft 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 +79 -8
- package/dist/create/index.d.ts.map +1 -1
- package/dist/create/index.js +24 -1
- package/dist/create/index.js.map +1 -1
- package/dist/create/scaffold.d.ts.map +1 -1
- package/dist/create/scaffold.js +8 -2
- package/dist/create/scaffold.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 +3 -0
- package/dist/create/scaffolders/api-nestjs-graphql.d.ts.map +1 -0
- package/dist/create/scaffolders/api-nestjs-graphql.js +31 -0
- package/dist/create/scaffolders/api-nestjs-graphql.js.map +1 -0
- package/dist/create/scaffolders/api-nestjs-rest.d.ts.map +1 -1
- package/dist/create/scaffolders/api-nestjs-rest.js +19 -2
- package/dist/create/scaffolders/api-nestjs-rest.js.map +1 -1
- package/dist/create/types.d.ts +3 -1
- package/dist/create/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/templates/api-nestjs-graphql/.prettierrc +4 -0
- package/templates/api-nestjs-graphql/eslint.config.mjs +34 -0
- package/templates/api-nestjs-graphql/nest-cli.json +8 -0
- package/templates/api-nestjs-graphql/package.json +81 -0
- package/templates/api-nestjs-graphql/project.json +21 -0
- package/templates/api-nestjs-graphql/src/app.module.ts +21 -0
- package/templates/api-nestjs-graphql/src/common/entities/base.entity.ts +21 -0
- package/templates/api-nestjs-graphql/src/common/repositories/entity.repository.ts +21 -0
- package/templates/api-nestjs-graphql/src/common/repositories/readonly-entity.repository.ts +22 -0
- package/templates/api-nestjs-graphql/src/common/services/entity.service.ts +24 -0
- package/templates/api-nestjs-graphql/src/common/services/readonly-entity.service.ts +23 -0
- package/templates/api-nestjs-graphql/src/main.ts +8 -0
- package/templates/api-nestjs-graphql/src/modules/database/database.module.ts +18 -0
- package/templates/api-nestjs-graphql/src/modules/health/__tests__/health.controller.spec.ts +20 -0
- package/templates/api-nestjs-graphql/src/modules/health/__tests__/health.service.spec.ts +18 -0
- package/templates/api-nestjs-graphql/src/modules/health/health.controller.ts +12 -0
- package/templates/api-nestjs-graphql/src/modules/health/health.module.ts +9 -0
- package/templates/api-nestjs-graphql/src/modules/health/health.service.ts +8 -0
- package/templates/api-nestjs-graphql/test/app.e2e-spec.ts +29 -0
- package/templates/api-nestjs-graphql/test/jest-e2e.json +9 -0
- package/templates/api-nestjs-graphql/tsconfig.build.json +4 -0
- package/templates/api-nestjs-graphql/tsconfig.json +21 -0
- package/templates/api-nestjs-rest/package.json +5 -2
- package/templates/api-nestjs-rest/project.json +1 -1
- package/templates/api-nestjs-rest/src/app.module.ts +8 -5
- package/templates/api-nestjs-rest/src/common/entities/base.entity.ts +16 -0
- package/templates/api-nestjs-rest/src/common/repositories/entity.repository.ts +21 -0
- package/templates/api-nestjs-rest/src/common/repositories/readonly-entity.repository.ts +22 -0
- package/templates/api-nestjs-rest/src/common/services/entity.service.ts +24 -0
- package/templates/api-nestjs-rest/src/common/services/readonly-entity.service.ts +23 -0
- package/templates/api-nestjs-rest/src/modules/database/database.module.ts +18 -0
- package/templates/api-nestjs-rest/src/modules/health/__tests__/health.controller.spec.ts +20 -0
- package/templates/api-nestjs-rest/src/modules/health/__tests__/health.service.spec.ts +18 -0
- package/templates/api-nestjs-rest/src/modules/health/health.controller.ts +12 -0
- package/templates/api-nestjs-rest/src/modules/health/health.module.ts +9 -0
- package/templates/api-nestjs-rest/src/modules/health/health.service.ts +8 -0
- package/templates/api-nestjs-rest/test/app.e2e-spec.ts +9 -5
- package/templates/base/package.json +5 -1
- package/templates/base/pnpm-workspace.yaml +1 -0
- package/templates/base/tools/generators/controller/files/__fileName__.controller.ts__tmpl__ +36 -0
- package/templates/base/tools/generators/controller/index.js +22 -0
- package/templates/base/tools/generators/controller/schema.json +18 -0
- package/templates/base/tools/generators/generators.json +19 -0
- package/templates/base/tools/generators/module/files/__fileName__.model.ts__tmpl__ +8 -0
- package/templates/base/tools/generators/module/files/__fileName__.module.ts__tmpl__ +12 -0
- package/templates/base/tools/generators/module/files/__fileName__.repository.ts__tmpl__ +15 -0
- package/templates/base/tools/generators/module/files/__fileName__.service.ts__tmpl__ +11 -0
- package/templates/base/tools/generators/module/files/__tests__/__fileName__.integration.spec.ts__tmpl__ +31 -0
- package/templates/base/tools/generators/module/graphql-files/__fileName__.model.ts__tmpl__ +11 -0
- package/templates/base/tools/generators/module/index.js +26 -0
- package/templates/base/tools/generators/module/schema.json +23 -0
- package/templates/base/tools/generators/package.json +6 -0
- package/templates/base/tools/generators/resolver/files/__fileName__.resolver.ts__tmpl__ +28 -0
- package/templates/base/tools/generators/resolver/index.js +22 -0
- package/templates/base/tools/generators/resolver/schema.json +18 -0
- package/templates/web-nextjs/package.json +3 -0
- package/templates/web-nextjs/postcss.config.mjs +7 -0
- package/templates/web-nextjs/src/app/globals.css +1 -0
- package/templates/web-nextjs/src/components/TemplateComponent/TemplateComponent.behaviour.ts +39 -0
- package/templates/web-nextjs/src/components/TemplateComponent/TemplateComponent.tsx +14 -0
- package/templates/web-vite/package.json +2 -0
- package/templates/web-vite/src/components/TemplateComponent/TemplateComponent.behaviour.ts +39 -0
- package/templates/web-vite/src/components/TemplateComponent/TemplateComponent.tsx +14 -0
- package/templates/web-vite/src/index.css +1 -8
- package/templates/web-vite/vite.config.ts +3 -3
- package/templates/api-nestjs-rest/src/app.controller.spec.ts +0 -22
- package/templates/api-nestjs-rest/src/app.controller.ts +0 -12
- package/templates/api-nestjs-rest/src/app.service.ts +0 -8
- package/templates/web-nextjs/app/globals.css +0 -10
- /package/templates/web-nextjs/{app → src/app}/favicon.ico +0 -0
- /package/templates/web-nextjs/{app → src/app}/layout.tsx +0 -0
- /package/templates/web-nextjs/{app → src/app}/page.tsx +0 -0
package/README.md
CHANGED
|
@@ -10,25 +10,96 @@ Spin up a production-ready monorepo in one command.
|
|
|
10
10
|
npx @exanderal/stackcraft
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Follow the prompts
|
|
13
|
+
Follow the prompts — you'll have an Nx monorepo with deps installed and ready to run.
|
|
14
14
|
|
|
15
15
|
## What you get
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
```
|
|
18
|
+
your-project/
|
|
19
|
+
├── apps/
|
|
20
|
+
│ ├── backend/ # NestJS REST or GraphQL API
|
|
21
|
+
│ └── web/ # Vite + React or Next.js
|
|
22
|
+
├── packages/ # shared code
|
|
23
|
+
└── tools/
|
|
24
|
+
└── generators/ # local Nx code generators
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Backend (`apps/backend`)
|
|
28
|
+
|
|
29
|
+
Choose between REST or GraphQL at setup time — both use the same underlying structure:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
src/
|
|
33
|
+
├── modules/ # domain layer — model, repository, service, module
|
|
34
|
+
├── api/ # REST controllers (REST only)
|
|
35
|
+
├── resolvers/ # GraphQL resolvers (GraphQL only)
|
|
36
|
+
└── common/ # shared base classes
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- NestJS with TypeORM
|
|
40
|
+
- PostgreSQL or MySQL
|
|
41
|
+
- `EntityRepository` and `EntityService` base classes — extend them for each module
|
|
42
|
+
- UUID primary keys
|
|
43
|
+
|
|
44
|
+
### Frontend (`apps/web`)
|
|
45
|
+
|
|
46
|
+
- Vite + React or Next.js
|
|
47
|
+
- Tailwind CSS v4
|
|
48
|
+
- TypeScript
|
|
49
|
+
|
|
50
|
+
## Running the project
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
pnpm dev # start all apps in parallel
|
|
54
|
+
pnpm build # build all apps
|
|
55
|
+
pnpm test # run all tests
|
|
56
|
+
pnpm lint # lint all apps
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Target a specific app:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
pnpm nx run backend:dev
|
|
63
|
+
pnpm nx run web:dev
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Code generation
|
|
67
|
+
|
|
68
|
+
Generate a new domain module:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
pnpm generate:module --name=trainer
|
|
72
|
+
# add --graphql to include @ObjectType() on the model
|
|
73
|
+
pnpm generate:module --name=trainer --graphql
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Generate a REST controller for an existing module:
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
pnpm generate:controller --name=trainer
|
|
80
|
+
# creates apps/backend/src/api/trainer/trainer.controller.ts
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Generate a GraphQL resolver for an existing module:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
pnpm generate:resolver --name=trainer
|
|
87
|
+
# creates apps/backend/src/resolvers/trainer/trainer.resolver.ts
|
|
88
|
+
```
|
|
21
89
|
|
|
22
90
|
## Stack
|
|
23
91
|
|
|
24
92
|
- **Monorepo** — Nx
|
|
25
93
|
- **Package manager** — pnpm or npm
|
|
26
|
-
- **Backend** — NestJS
|
|
27
|
-
- **Frontend** — Vite + React or Next.js
|
|
94
|
+
- **Backend** — NestJS, TypeORM, PostgreSQL/MySQL
|
|
95
|
+
- **Frontend** — Vite + React or Next.js, Tailwind CSS v4
|
|
28
96
|
|
|
29
97
|
## Roadmap
|
|
30
98
|
|
|
31
|
-
- [
|
|
99
|
+
- [x] NestJS REST API
|
|
100
|
+
- [x] NestJS GraphQL API
|
|
101
|
+
- [x] Module, controller, and resolver generators
|
|
102
|
+
- [ ] GraphQL codegen pipeline
|
|
32
103
|
- [ ] Expo mobile
|
|
33
104
|
- [ ] `stackcraft add` addon system (auth, Supabase, etc.)
|
|
34
105
|
- [ ] Presets and `--config` for non-interactive use
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/create/index.ts"],"names":[],"mappings":"AAKA,wBAAsB,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/create/index.ts"],"names":[],"mappings":"AAKA,wBAAsB,MAAM,kBA4E3B"}
|
package/dist/create/index.js
CHANGED
|
@@ -12,6 +12,17 @@ export async function create() {
|
|
|
12
12
|
cancel('Cancelled.');
|
|
13
13
|
process.exit(0);
|
|
14
14
|
}
|
|
15
|
+
const backend = await select({
|
|
16
|
+
message: 'Backend',
|
|
17
|
+
options: [
|
|
18
|
+
{ value: 'nestjs-rest', label: 'NestJS REST', hint: 'REST API with TypeORM' },
|
|
19
|
+
{ value: 'nestjs-graphql', label: 'NestJS GraphQL', hint: 'Code-first GraphQL with TypeORM' },
|
|
20
|
+
],
|
|
21
|
+
});
|
|
22
|
+
if (isCancel(backend)) {
|
|
23
|
+
cancel('Cancelled.');
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
15
26
|
const frontend = await select({
|
|
16
27
|
message: 'Frontend',
|
|
17
28
|
options: [
|
|
@@ -23,6 +34,17 @@ export async function create() {
|
|
|
23
34
|
cancel('Cancelled.');
|
|
24
35
|
process.exit(0);
|
|
25
36
|
}
|
|
37
|
+
const database = await select({
|
|
38
|
+
message: 'Database',
|
|
39
|
+
options: [
|
|
40
|
+
{ value: 'postgres', label: 'PostgreSQL', hint: 'recommended' },
|
|
41
|
+
{ value: 'mysql', label: 'MySQL' },
|
|
42
|
+
],
|
|
43
|
+
});
|
|
44
|
+
if (isCancel(database)) {
|
|
45
|
+
cancel('Cancelled.');
|
|
46
|
+
process.exit(0);
|
|
47
|
+
}
|
|
26
48
|
const packageManager = await select({
|
|
27
49
|
message: 'Package manager',
|
|
28
50
|
options: [
|
|
@@ -37,7 +59,8 @@ export async function create() {
|
|
|
37
59
|
const config = {
|
|
38
60
|
projectName: projectName,
|
|
39
61
|
frontend: frontend,
|
|
40
|
-
backend:
|
|
62
|
+
backend: backend,
|
|
63
|
+
database: database,
|
|
41
64
|
packageManager: packageManager,
|
|
42
65
|
targetDir: resolve(process.cwd(), projectName),
|
|
43
66
|
};
|
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;AAGxC,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,KAAK,CAAC,kDAAkD,CAAC,CAAA;IAEzD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;QAC7B,OAAO,EAAE,cAAc;QACvB,WAAW,EAAE,QAAQ;QACrB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;KAC/C,CAAC,CAAA;IACF,IAAI,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,YAAY,CAAC,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC;QAC5B,OAAO,EAAE,UAAU;QACnB,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,iCAAiC,EAAE;YACjF,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,+BAA+B,EAAE;SAC7E;KACF,CAAC,CAAA;IACF,IAAI,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,YAAY,CAAC,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC;QAClC,OAAO,EAAE,iBAAiB;QAC1B,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE;YACrD,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;SAC/B;KACF,CAAC,CAAA;IACF,IAAI,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,YAAY,CAAC,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,MAAM,GAAkB;QAC5B,WAAW,EAAE,WAAqB;QAClC,QAAQ,EAAE,QAAoB;QAC9B,OAAO,EAAE,
|
|
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;AAGxC,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,KAAK,CAAC,kDAAkD,CAAC,CAAA;IAEzD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;QAC7B,OAAO,EAAE,cAAc;QACvB,WAAW,EAAE,QAAQ;QACrB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;KAC/C,CAAC,CAAA;IACF,IAAI,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,YAAY,CAAC,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC;QAC3B,OAAO,EAAE,SAAS;QAClB,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,uBAAuB,EAAE;YAC7E,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,iCAAiC,EAAE;SAC9F;KACF,CAAC,CAAA;IACF,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,YAAY,CAAC,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC;QAC5B,OAAO,EAAE,UAAU;QACnB,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,iCAAiC,EAAE;YACjF,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,+BAA+B,EAAE;SAC7E;KACF,CAAC,CAAA;IACF,IAAI,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,YAAY,CAAC,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC;QAC5B,OAAO,EAAE,UAAU;QACnB,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE;YAC/D,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;SACnC;KACF,CAAC,CAAA;IACF,IAAI,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,YAAY,CAAC,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC;QAClC,OAAO,EAAE,iBAAiB;QAC1B,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE;YACrD,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;SAC/B;KACF,CAAC,CAAA;IACF,IAAI,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,YAAY,CAAC,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,MAAM,GAAkB;QAC5B,WAAW,EAAE,WAAqB;QAClC,QAAQ,EAAE,QAAoB;QAC9B,OAAO,EAAE,OAAkB;QAC3B,QAAQ,EAAE,QAAoB;QAC9B,cAAc,EAAE,cAAgC;QAChD,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAqB,CAAC;KACzD,CAAA;IAED,MAAM,CAAC,GAAG,OAAO,EAAE,CAAA;IACnB,CAAC,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;IACtC,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAA;IAC/C,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAEf,KAAK,CAAC,MAAM,MAAM,CAAC,WAAW,OAAO,MAAM,CAAC,cAAc,MAAM,CAAC,CAAA;AACnE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../src/create/scaffold.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../src/create/scaffold.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,wBAAsB,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,iBAqBlF"}
|
package/dist/create/scaffold.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { execa } from 'execa';
|
|
2
|
+
import { scaffoldNestjsGraphql } from './scaffolders/api-nestjs-graphql.js';
|
|
2
3
|
import { scaffoldNestjsRest } from './scaffolders/api-nestjs-rest.js';
|
|
3
4
|
import { scaffoldBase } from './scaffolders/base.js';
|
|
4
5
|
import { scaffoldNextjs } from './scaffolders/web-nextjs.js';
|
|
@@ -6,8 +7,13 @@ import { scaffoldVite } from './scaffolders/web-vite.js';
|
|
|
6
7
|
export async function scaffold(config, onStep) {
|
|
7
8
|
onStep('Creating workspace...');
|
|
8
9
|
await scaffoldBase(config);
|
|
9
|
-
onStep('Adding
|
|
10
|
-
|
|
10
|
+
onStep('Adding backend...');
|
|
11
|
+
if (config.backend === 'nestjs-graphql') {
|
|
12
|
+
await scaffoldNestjsGraphql(config);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
await scaffoldNestjsRest(config);
|
|
16
|
+
}
|
|
11
17
|
if (config.frontend === 'vite') {
|
|
12
18
|
onStep('Adding Vite + React app...');
|
|
13
19
|
await scaffoldVite(config);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/create/scaffold.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAGxD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAqB,EAAE,MAA6B;IACjF,MAAM,CAAC,uBAAuB,CAAC,CAAA;IAC/B,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAE1B,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/create/scaffold.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAA;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAGxD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAqB,EAAE,MAA6B;IACjF,MAAM,CAAC,uBAAuB,CAAC,CAAA;IAC/B,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAE1B,MAAM,CAAC,mBAAmB,CAAC,CAAA;IAC3B,IAAI,MAAM,CAAC,OAAO,KAAK,gBAAgB,EAAE,CAAC;QACxC,MAAM,qBAAqB,CAAC,MAAM,CAAC,CAAA;IACrC,CAAC;SAAM,CAAC;QACN,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAClC,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;QAC/B,MAAM,CAAC,4BAA4B,CAAC,CAAA;QACpC,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAC5B,CAAC;SAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,CAAC,uBAAuB,CAAC,CAAA;QAC/B,MAAM,cAAc,CAAC,MAAM,CAAC,CAAA;IAC9B,CAAC;IAED,MAAM,CAAC,4BAA4B,CAAC,CAAA;IACpC,MAAM,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;AAC5E,CAAC"}
|
|
@@ -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,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,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"}
|
|
@@ -0,0 +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;AAWhD,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,aAAa,iBAahE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { copyTemplate } from './utils/copy.js';
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
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
|
+
export async function scaffoldNestjsGraphql(config) {
|
|
12
|
+
const appDir = join(config.targetDir, 'apps', 'backend');
|
|
13
|
+
await mkdir(appDir, { recursive: true });
|
|
14
|
+
const db = DB_CONFIG[config.database];
|
|
15
|
+
await copyTemplate(join(TEMPLATES_DIR, 'api-nestjs-graphql'), appDir, {
|
|
16
|
+
projectName: config.projectName,
|
|
17
|
+
dbType: db.type,
|
|
18
|
+
dbPort: db.port,
|
|
19
|
+
});
|
|
20
|
+
await injectDbDriver(appDir, db);
|
|
21
|
+
}
|
|
22
|
+
async function injectDbDriver(appDir, db) {
|
|
23
|
+
const pkgPath = join(appDir, 'package.json');
|
|
24
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
25
|
+
pkg.dependencies[db.driver] = db.driverVersion;
|
|
26
|
+
if (db.typesPackage) {
|
|
27
|
+
pkg.devDependencies[db.typesPackage] = db.typesVersion;
|
|
28
|
+
}
|
|
29
|
+
await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=api-nestjs-graphql.js.map
|
|
@@ -0,0 +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,SAAS,GAAG;IAChB,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE;IACtI,KAAK,EAAK,EAAE,IAAI,EAAE,OAAO,EAAK,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE;CACvH,CAAA;AAEV,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,MAAqB;IAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,CAAA;IACxD,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAExC,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAErC,MAAM,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,oBAAoB,CAAC,EAAE,MAAM,EAAE;QACpE,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,MAAM,EAAE,EAAE,CAAC,IAAI;QACf,MAAM,EAAE,EAAE,CAAC,IAAI;KAChB,CAAC,CAAA;IAEF,MAAM,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;AAClC,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,MAAc,EAAE,EAA4C;IACxF,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;IAExD,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,aAAa,CAAA;IAE9C,IAAI,EAAE,CAAC,YAAY,EAAE,CAAC;QACpB,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,YAAY,CAAA;IACxD,CAAC;IAED,MAAM,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAA;AACxE,CAAC"}
|
|
@@ -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;AAWhD,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,aAAa,iBAa7D"}
|
|
@@ -1,14 +1,31 @@
|
|
|
1
|
-
import { mkdir } from 'node:fs/promises';
|
|
1
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { copyTemplate } from './utils/copy.js';
|
|
5
5
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
6
|
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
|
+
};
|
|
7
11
|
export async function scaffoldNestjsRest(config) {
|
|
8
|
-
const appDir = join(config.targetDir, 'apps', '
|
|
12
|
+
const appDir = join(config.targetDir, 'apps', 'backend');
|
|
9
13
|
await mkdir(appDir, { recursive: true });
|
|
14
|
+
const db = DB_CONFIG[config.database];
|
|
10
15
|
await copyTemplate(join(TEMPLATES_DIR, 'api-nestjs-rest'), appDir, {
|
|
11
16
|
projectName: config.projectName,
|
|
17
|
+
dbType: db.type,
|
|
18
|
+
dbPort: db.port,
|
|
12
19
|
});
|
|
20
|
+
await injectDbDriver(appDir, db);
|
|
21
|
+
}
|
|
22
|
+
async function injectDbDriver(appDir, db) {
|
|
23
|
+
const pkgPath = join(appDir, 'package.json');
|
|
24
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
25
|
+
pkg.dependencies[db.driver] = db.driverVersion;
|
|
26
|
+
if (db.typesPackage) {
|
|
27
|
+
pkg.devDependencies[db.typesPackage] = db.typesVersion;
|
|
28
|
+
}
|
|
29
|
+
await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
|
|
13
30
|
}
|
|
14
31
|
//# sourceMappingURL=api-nestjs-rest.js.map
|
|
@@ -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,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"api-nestjs-rest.js","sourceRoot":"","sources":["../../../src/create/scaffolders/api-nestjs-rest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,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,SAAS,GAAG;IAChB,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE;IACtI,KAAK,EAAK,EAAE,IAAI,EAAE,OAAO,EAAK,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE;CACvH,CAAA;AAEV,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAqB;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,CAAA;IACxD,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAExC,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAErC,MAAM,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,iBAAiB,CAAC,EAAE,MAAM,EAAE;QACjE,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,MAAM,EAAE,EAAE,CAAC,IAAI;QACf,MAAM,EAAE,EAAE,CAAC,IAAI;KAChB,CAAC,CAAA;IAEF,MAAM,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;AAClC,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,MAAc,EAAE,EAA4C;IACxF,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;IAExD,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,aAAa,CAAA;IAE9C,IAAI,EAAE,CAAC,YAAY,EAAE,CAAC;QACpB,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,YAAY,CAAA;IACxD,CAAC;IAED,MAAM,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAA;AACxE,CAAC"}
|
package/dist/create/types.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export type PackageManager = 'pnpm' | 'npm';
|
|
2
2
|
export type Frontend = 'vite' | 'nextjs';
|
|
3
|
-
export type Backend = 'nestjs-rest';
|
|
3
|
+
export type Backend = 'nestjs-rest' | 'nestjs-graphql';
|
|
4
|
+
export type Database = 'postgres' | 'mysql';
|
|
4
5
|
export interface ProjectConfig {
|
|
5
6
|
projectName: string;
|
|
6
7
|
frontend: Frontend;
|
|
7
8
|
backend: Backend;
|
|
9
|
+
database: Database;
|
|
8
10
|
packageManager: PackageManager;
|
|
9
11
|
targetDir: string;
|
|
10
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/create/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,CAAA;AAC3C,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAA;AACxC,MAAM,MAAM,OAAO,GAAG,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/create/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,CAAA;AAC3C,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAA;AACxC,MAAM,MAAM,OAAO,GAAG,aAAa,GAAG,gBAAgB,CAAA;AACtD,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAA;AAE3C,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,QAAQ,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,QAAQ,CAAA;IAClB,cAAc,EAAE,cAAc,CAAA;IAC9B,SAAS,EAAE,MAAM,CAAA;CAClB"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import eslint from '@eslint/js';
|
|
3
|
+
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
|
4
|
+
import globals from 'globals';
|
|
5
|
+
import tseslint from 'typescript-eslint';
|
|
6
|
+
|
|
7
|
+
export default tseslint.config(
|
|
8
|
+
{
|
|
9
|
+
ignores: ['eslint.config.mjs'],
|
|
10
|
+
},
|
|
11
|
+
eslint.configs.recommended,
|
|
12
|
+
...tseslint.configs.recommendedTypeChecked,
|
|
13
|
+
eslintPluginPrettierRecommended,
|
|
14
|
+
{
|
|
15
|
+
languageOptions: {
|
|
16
|
+
globals: {
|
|
17
|
+
...globals.node,
|
|
18
|
+
...globals.jest,
|
|
19
|
+
},
|
|
20
|
+
sourceType: 'commonjs',
|
|
21
|
+
parserOptions: {
|
|
22
|
+
projectService: true,
|
|
23
|
+
tsconfigRootDir: import.meta.dirname,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
rules: {
|
|
29
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
30
|
+
'@typescript-eslint/no-floating-promises': 'warn',
|
|
31
|
+
'@typescript-eslint/no-unsafe-argument': 'warn'
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
);
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{projectName}}-backend",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"author": "",
|
|
6
|
+
"private": true,
|
|
7
|
+
"license": "UNLICENSED",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"dev": "nest start --watch",
|
|
10
|
+
"build": "nest build",
|
|
11
|
+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
12
|
+
"start": "nest start",
|
|
13
|
+
"start:dev": "nest start --watch",
|
|
14
|
+
"start:debug": "nest start --debug --watch",
|
|
15
|
+
"start:prod": "node dist/main",
|
|
16
|
+
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
|
17
|
+
"test": "jest",
|
|
18
|
+
"test:watch": "jest --watch",
|
|
19
|
+
"test:cov": "jest --coverage",
|
|
20
|
+
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
|
21
|
+
"test:e2e": "jest --config ./test/jest-e2e.json"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@apollo/server": "^4.0.0",
|
|
25
|
+
"@nestjs/apollo": "^13.0.0",
|
|
26
|
+
"@nestjs/common": "^11.0.1",
|
|
27
|
+
"@nestjs/config": "^3.0.0",
|
|
28
|
+
"@nestjs/core": "^11.0.1",
|
|
29
|
+
"@nestjs/graphql": "^13.0.0",
|
|
30
|
+
"@nestjs/platform-express": "^11.0.1",
|
|
31
|
+
"@nestjs/typeorm": "^10.0.0",
|
|
32
|
+
"graphql": "^16.0.0",
|
|
33
|
+
"reflect-metadata": "^0.2.2",
|
|
34
|
+
"rxjs": "^7.8.1",
|
|
35
|
+
"typeorm": "^0.3.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@eslint/eslintrc": "^3.2.0",
|
|
39
|
+
"@eslint/js": "^9.18.0",
|
|
40
|
+
"@nestjs/cli": "^11.0.0",
|
|
41
|
+
"@nestjs/schematics": "^11.0.0",
|
|
42
|
+
"@nestjs/testing": "^11.0.1",
|
|
43
|
+
"@swc/cli": "^0.6.0",
|
|
44
|
+
"@swc/core": "^1.10.7",
|
|
45
|
+
"@types/express": "^5.0.0",
|
|
46
|
+
"@types/jest": "^29.5.14",
|
|
47
|
+
"@types/node": "^22.10.7",
|
|
48
|
+
"@types/supertest": "^6.0.2",
|
|
49
|
+
"eslint": "^9.18.0",
|
|
50
|
+
"eslint-config-prettier": "^10.0.1",
|
|
51
|
+
"eslint-plugin-prettier": "^5.2.2",
|
|
52
|
+
"globals": "^16.0.0",
|
|
53
|
+
"jest": "^29.7.0",
|
|
54
|
+
"prettier": "^3.4.2",
|
|
55
|
+
"source-map-support": "^0.5.21",
|
|
56
|
+
"supertest": "^7.0.0",
|
|
57
|
+
"ts-jest": "^29.2.5",
|
|
58
|
+
"ts-loader": "^9.5.2",
|
|
59
|
+
"ts-node": "^10.9.2",
|
|
60
|
+
"tsconfig-paths": "^4.2.0",
|
|
61
|
+
"typescript": "^5.7.3",
|
|
62
|
+
"typescript-eslint": "^8.20.0"
|
|
63
|
+
},
|
|
64
|
+
"jest": {
|
|
65
|
+
"moduleFileExtensions": [
|
|
66
|
+
"js",
|
|
67
|
+
"json",
|
|
68
|
+
"ts"
|
|
69
|
+
],
|
|
70
|
+
"rootDir": "src",
|
|
71
|
+
"testRegex": ".*\\.spec\\.ts$",
|
|
72
|
+
"transform": {
|
|
73
|
+
"^.+\\.(t|j)s$": "ts-jest"
|
|
74
|
+
},
|
|
75
|
+
"collectCoverageFrom": [
|
|
76
|
+
"**/*.(t|j)s"
|
|
77
|
+
],
|
|
78
|
+
"coverageDirectory": "../coverage",
|
|
79
|
+
"testEnvironment": "node"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "backend",
|
|
3
|
+
"targets": {
|
|
4
|
+
"dev": {
|
|
5
|
+
"executor": "nx:run-commands",
|
|
6
|
+
"options": { "command": "pnpm run dev", "cwd": "{projectRoot}" }
|
|
7
|
+
},
|
|
8
|
+
"build": {
|
|
9
|
+
"executor": "nx:run-commands",
|
|
10
|
+
"options": { "command": "pnpm run build", "cwd": "{projectRoot}" }
|
|
11
|
+
},
|
|
12
|
+
"lint": {
|
|
13
|
+
"executor": "nx:run-commands",
|
|
14
|
+
"options": { "command": "pnpm run lint", "cwd": "{projectRoot}" }
|
|
15
|
+
},
|
|
16
|
+
"test": {
|
|
17
|
+
"executor": "nx:run-commands",
|
|
18
|
+
"options": { "command": "pnpm run test", "cwd": "{projectRoot}" }
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
|
|
2
|
+
import { Module } from '@nestjs/common';
|
|
3
|
+
import { ConfigModule } from '@nestjs/config';
|
|
4
|
+
import { GraphQLModule } from '@nestjs/graphql';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { DatabaseModule } from './modules/database/database.module';
|
|
7
|
+
import { HealthModule } from './modules/health/health.module';
|
|
8
|
+
|
|
9
|
+
@Module({
|
|
10
|
+
imports: [
|
|
11
|
+
ConfigModule.forRoot({ isGlobal: true }),
|
|
12
|
+
GraphQLModule.forRoot<ApolloDriverConfig>({
|
|
13
|
+
driver: ApolloDriver,
|
|
14
|
+
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
|
|
15
|
+
sortSchema: true,
|
|
16
|
+
}),
|
|
17
|
+
DatabaseModule,
|
|
18
|
+
HealthModule,
|
|
19
|
+
],
|
|
20
|
+
})
|
|
21
|
+
export class AppModule {}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Field, ID, ObjectType } from '@nestjs/graphql';
|
|
2
|
+
import {
|
|
3
|
+
CreateDateColumn,
|
|
4
|
+
PrimaryGeneratedColumn,
|
|
5
|
+
UpdateDateColumn,
|
|
6
|
+
} from 'typeorm';
|
|
7
|
+
|
|
8
|
+
@ObjectType({ isAbstract: true })
|
|
9
|
+
export abstract class BaseEntity {
|
|
10
|
+
@Field(() => ID)
|
|
11
|
+
@PrimaryGeneratedColumn('uuid')
|
|
12
|
+
id: string;
|
|
13
|
+
|
|
14
|
+
@Field()
|
|
15
|
+
@CreateDateColumn()
|
|
16
|
+
createdAt: Date;
|
|
17
|
+
|
|
18
|
+
@Field()
|
|
19
|
+
@UpdateDateColumn()
|
|
20
|
+
updatedAt: Date;
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { DeepPartial } from 'typeorm';
|
|
2
|
+
import { BaseEntity } from '../entities/base.entity';
|
|
3
|
+
import { ReadonlyEntityRepository } from './readonly-entity.repository';
|
|
4
|
+
|
|
5
|
+
export abstract class EntityRepository<
|
|
6
|
+
T extends BaseEntity,
|
|
7
|
+
> extends ReadonlyEntityRepository<T> {
|
|
8
|
+
async create(data: DeepPartial<T>): Promise<T> {
|
|
9
|
+
const entity = this.repo.create(data);
|
|
10
|
+
return this.repo.save(entity);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async update(id: string, data: DeepPartial<T>): Promise<T> {
|
|
14
|
+
await this.repo.update(id, data as any);
|
|
15
|
+
return this.findById(id) as Promise<T>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async remove(id: string): Promise<void> {
|
|
19
|
+
await this.repo.delete(id);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { FindManyOptions, FindOptionsWhere, In, Repository } from 'typeorm';
|
|
2
|
+
import { BaseEntity } from '../entities/base.entity';
|
|
3
|
+
|
|
4
|
+
export abstract class ReadonlyEntityRepository<T extends BaseEntity> {
|
|
5
|
+
constructor(protected readonly repo: Repository<T>) {}
|
|
6
|
+
|
|
7
|
+
findAll(options?: FindManyOptions<T>): Promise<T[]> {
|
|
8
|
+
return this.repo.find(options);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
findByIds(ids: string[]): Promise<T[]> {
|
|
12
|
+
return this.repo.findBy({ id: In(ids) } as FindOptionsWhere<T>);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
findById(id: string): Promise<T | null> {
|
|
16
|
+
return this.repo.findOneBy({ id } as FindOptionsWhere<T>);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
findOne(where: FindOptionsWhere<T>): Promise<T | null> {
|
|
20
|
+
return this.repo.findOneBy(where);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { DeepPartial } from 'typeorm';
|
|
2
|
+
import { BaseEntity } from '../entities/base.entity';
|
|
3
|
+
import { EntityRepository } from '../repositories/entity.repository';
|
|
4
|
+
import { ReadonlyEntityService } from './readonly-entity.service';
|
|
5
|
+
|
|
6
|
+
export abstract class EntityService<
|
|
7
|
+
T extends BaseEntity,
|
|
8
|
+
> extends ReadonlyEntityService<T> {
|
|
9
|
+
constructor(protected readonly repository: EntityRepository<T>) {
|
|
10
|
+
super(repository);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
create(data: DeepPartial<T>): Promise<T> {
|
|
14
|
+
return this.repository.create(data);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
update(id: string, data: DeepPartial<T>): Promise<T> {
|
|
18
|
+
return this.repository.update(id, data);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
remove(id: string): Promise<void> {
|
|
22
|
+
return this.repository.remove(id);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FindManyOptions, FindOptionsWhere } from 'typeorm';
|
|
2
|
+
import { BaseEntity } from '../entities/base.entity';
|
|
3
|
+
import { ReadonlyEntityRepository } from '../repositories/readonly-entity.repository';
|
|
4
|
+
|
|
5
|
+
export abstract class ReadonlyEntityService<T extends BaseEntity> {
|
|
6
|
+
constructor(protected readonly repository: ReadonlyEntityRepository<T>) {}
|
|
7
|
+
|
|
8
|
+
findAll(options?: FindManyOptions<T>): Promise<T[]> {
|
|
9
|
+
return this.repository.findAll(options);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
findByIds(ids: string[]): Promise<T[]> {
|
|
13
|
+
return this.repository.findByIds(ids);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
findById(id: string): Promise<T | null> {
|
|
17
|
+
return this.repository.findById(id);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
findOne(where: FindOptionsWhere<T>): Promise<T | null> {
|
|
21
|
+
return this.repository.findOne(where);
|
|
22
|
+
}
|
|
23
|
+
}
|