@exanderal/stackcraft 0.1.2 → 0.2.1
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 +96 -21
- package/dist/create/index.d.ts.map +1 -1
- package/dist/create/index.js +12 -1
- package/dist/create/index.js.map +1 -1
- package/dist/create/scaffold.d.ts.map +1 -1
- package/dist/create/scaffold.js +11 -2
- package/dist/create/scaffold.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 +44 -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 +11 -1
- package/dist/create/scaffolders/api-nestjs-rest.js.map +1 -1
- package/dist/create/scaffolders/wire-client.d.ts +3 -0
- package/dist/create/scaffolders/wire-client.d.ts.map +1 -0
- package/dist/create/scaffolders/wire-client.js +77 -0
- package/dist/create/scaffolders/wire-client.js.map +1 -0
- package/dist/create/types.d.ts +1 -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 +1 -0
- package/templates/api-nestjs-rest/src/main.ts +11 -0
- package/templates/base/package.json +5 -1
- package/templates/base/packages/types/package.json +10 -0
- package/templates/base/packages/types/tsconfig.json +10 -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 +11 -1
- package/templates/base/tools/generators/module/graphql-files/__fileName__.model.ts__tmpl__ +11 -0
- package/templates/base/tools/generators/module/index.js +4 -22
- package/templates/base/tools/generators/module/schema.json +4 -5
- 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/types-graphql/codegen.ts +17 -0
- package/templates/types-graphql/project.json +19 -0
- package/templates/types-rest/openapi-ts.config.ts +10 -0
- package/templates/types-rest/project.json +19 -0
- /package/templates/base/tools/generators/{module/crud-files → controller/files}/__fileName__.controller.ts__tmpl__ +0 -0
package/README.md
CHANGED
|
@@ -17,65 +17,140 @@ Follow the prompts — you'll have an Nx monorepo with deps installed and ready
|
|
|
17
17
|
```
|
|
18
18
|
your-project/
|
|
19
19
|
├── apps/
|
|
20
|
-
│ ├── backend/ # NestJS REST API
|
|
20
|
+
│ ├── backend/ # NestJS REST or GraphQL API
|
|
21
21
|
│ └── web/ # Vite + React or Next.js
|
|
22
|
-
├── packages/
|
|
22
|
+
├── packages/
|
|
23
|
+
│ └── types/ # auto-generated types shared across all apps
|
|
23
24
|
└── tools/
|
|
24
25
|
└── generators/ # local Nx code generators
|
|
25
26
|
```
|
|
26
27
|
|
|
27
28
|
### Backend (`apps/backend`)
|
|
28
29
|
|
|
30
|
+
Choose between REST or GraphQL at setup — both share the same structure:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
src/
|
|
34
|
+
├── modules/ # domain layer — model, repository, service, module
|
|
35
|
+
├── api/ # REST controllers
|
|
36
|
+
├── resolvers/ # GraphQL resolvers
|
|
37
|
+
└── common/ # shared base classes (EntityRepository, EntityService)
|
|
38
|
+
```
|
|
39
|
+
|
|
29
40
|
- NestJS with TypeORM
|
|
30
41
|
- PostgreSQL or MySQL
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
42
|
+
- `EntityRepository` and `EntityService` base classes — extend them for each module
|
|
43
|
+
- UUID primary keys
|
|
44
|
+
- REST: Swagger UI at `/api`, spec written to `swagger.json` on startup
|
|
45
|
+
- GraphQL: schema auto-generated to `schema.gql` on startup (code-first)
|
|
34
46
|
|
|
35
47
|
### Frontend (`apps/web`)
|
|
36
48
|
|
|
37
49
|
- Vite + React or Next.js
|
|
38
50
|
- Tailwind CSS v4
|
|
39
51
|
- TypeScript
|
|
52
|
+
- GraphQL projects: Apollo Client pre-configured, `ApolloProvider` already wired at the app root
|
|
53
|
+
|
|
54
|
+
### Types (`packages/types`)
|
|
55
|
+
|
|
56
|
+
Auto-generated TypeScript types shared across all apps — import from `@local/types/rest` or `@local/types/graphql`:
|
|
57
|
+
|
|
58
|
+
- REST → generated from `swagger.json` via `@hey-api/openapi-ts`
|
|
59
|
+
- GraphQL → generated from `schema.gql` + your `.graphql` operation files via `@graphql-codegen/cli`, outputs typed Apollo hooks
|
|
40
60
|
|
|
41
61
|
## Running the project
|
|
42
62
|
|
|
43
|
-
|
|
63
|
+
```sh
|
|
64
|
+
pnpm dev # start all apps in parallel
|
|
65
|
+
pnpm build # build all apps
|
|
66
|
+
pnpm test # run all tests
|
|
67
|
+
pnpm lint # lint all apps
|
|
68
|
+
```
|
|
44
69
|
|
|
45
70
|
```sh
|
|
46
|
-
pnpm
|
|
47
|
-
pnpm
|
|
48
|
-
pnpm test # run all tests
|
|
49
|
-
pnpm lint # lint all apps
|
|
71
|
+
pnpm codegen # generate types once
|
|
72
|
+
pnpm codegen:watch # watch for schema/spec changes and regenerate automatically
|
|
50
73
|
```
|
|
51
74
|
|
|
52
|
-
|
|
75
|
+
Typical dev workflow — run both in parallel:
|
|
53
76
|
|
|
54
77
|
```sh
|
|
55
|
-
|
|
56
|
-
pnpm
|
|
78
|
+
# terminal 1
|
|
79
|
+
pnpm dev
|
|
80
|
+
|
|
81
|
+
# terminal 2
|
|
82
|
+
pnpm codegen:watch
|
|
57
83
|
```
|
|
58
84
|
|
|
59
|
-
## Code
|
|
85
|
+
## Code generators
|
|
60
86
|
|
|
61
|
-
Generate a new
|
|
87
|
+
Generate a new domain module (model + repository + service):
|
|
62
88
|
|
|
63
89
|
```sh
|
|
64
90
|
pnpm generate:module --name=trainer
|
|
91
|
+
pnpm generate:module --name=trainer --graphql # adds @ObjectType() to the model
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Generate a REST controller:
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
pnpm generate:controller --name=trainer
|
|
98
|
+
# → apps/backend/src/api/trainer/trainer.controller.ts
|
|
65
99
|
```
|
|
66
100
|
|
|
67
|
-
|
|
101
|
+
Generate a GraphQL resolver:
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
pnpm generate:resolver --name=trainer
|
|
105
|
+
# → apps/backend/src/resolvers/trainer/trainer.resolver.ts
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Using generated types
|
|
109
|
+
|
|
110
|
+
**REST** — import types directly:
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import type { Trainer } from '@local/types/rest'
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**GraphQL** — write `.graphql` files in `apps/web/src/graphql/`, run `pnpm codegen`, then use the generated hooks:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
// apps/web/src/graphql/trainer.graphql
|
|
120
|
+
query GetTrainers {
|
|
121
|
+
trainers { id createdAt updatedAt }
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { useGetTrainersQuery } from '@local/types/graphql'
|
|
127
|
+
|
|
128
|
+
const { data, loading } = useGetTrainersQuery()
|
|
129
|
+
```
|
|
68
130
|
|
|
69
131
|
## Stack
|
|
70
132
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
133
|
+
| Layer | Technology |
|
|
134
|
+
|---|---|
|
|
135
|
+
| Monorepo | Nx |
|
|
136
|
+
| Package manager | pnpm or npm |
|
|
137
|
+
| Backend | NestJS, TypeORM |
|
|
138
|
+
| Database | PostgreSQL or MySQL |
|
|
139
|
+
| Frontend | Vite + React or Next.js |
|
|
140
|
+
| Styles | Tailwind CSS v4 |
|
|
141
|
+
| GraphQL client | Apollo Client |
|
|
142
|
+
| REST types | @hey-api/openapi-ts |
|
|
143
|
+
| GraphQL types + hooks | @graphql-codegen/cli |
|
|
75
144
|
|
|
76
145
|
## Roadmap
|
|
77
146
|
|
|
78
|
-
- [
|
|
147
|
+
- [x] NestJS REST API with Swagger
|
|
148
|
+
- [x] NestJS GraphQL API (code-first)
|
|
149
|
+
- [x] Module, controller, and resolver generators
|
|
150
|
+
- [x] Auto-generated types in `packages/types`
|
|
151
|
+
- [x] `codegen:watch` for live type generation during dev
|
|
152
|
+
- [x] Apollo Client pre-configured in GraphQL projects
|
|
153
|
+
- [x] Typed Apollo hooks from `.graphql` operation files
|
|
79
154
|
- [ ] Expo mobile
|
|
80
155
|
- [ ] `stackcraft add` addon system (auth, Supabase, etc.)
|
|
81
156
|
- [ ] 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: [
|
|
@@ -48,7 +59,7 @@ export async function create() {
|
|
|
48
59
|
const config = {
|
|
49
60
|
projectName: projectName,
|
|
50
61
|
frontend: frontend,
|
|
51
|
-
backend:
|
|
62
|
+
backend: backend,
|
|
52
63
|
database: database,
|
|
53
64
|
packageManager: packageManager,
|
|
54
65
|
targetDir: resolve(process.cwd(), projectName),
|
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,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,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/create/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -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":"AAOA,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,iBAwBlF"}
|
package/dist/create/scaffold.js
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
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';
|
|
5
6
|
import { scaffoldVite } from './scaffolders/web-vite.js';
|
|
7
|
+
import { wireClientIntegration } from './scaffolders/wire-client.js';
|
|
6
8
|
export async function scaffold(config, onStep) {
|
|
7
9
|
onStep('Creating workspace...');
|
|
8
10
|
await scaffoldBase(config);
|
|
9
|
-
onStep('Adding
|
|
10
|
-
|
|
11
|
+
onStep('Adding backend...');
|
|
12
|
+
if (config.backend === 'nestjs-graphql') {
|
|
13
|
+
await scaffoldNestjsGraphql(config);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
await scaffoldNestjsRest(config);
|
|
17
|
+
}
|
|
11
18
|
if (config.frontend === 'vite') {
|
|
12
19
|
onStep('Adding Vite + React app...');
|
|
13
20
|
await scaffoldVite(config);
|
|
@@ -16,6 +23,8 @@ export async function scaffold(config, onStep) {
|
|
|
16
23
|
onStep('Adding Next.js app...');
|
|
17
24
|
await scaffoldNextjs(config);
|
|
18
25
|
}
|
|
26
|
+
onStep('Wiring client integration...');
|
|
27
|
+
await wireClientIntegration(config);
|
|
19
28
|
onStep('Installing dependencies...');
|
|
20
29
|
await execa(config.packageManager, ['install'], { cwd: config.targetDir });
|
|
21
30
|
}
|
|
@@ -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;
|
|
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;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAGpE,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,8BAA8B,CAAC,CAAA;IACtC,MAAM,qBAAqB,CAAC,MAAM,CAAC,CAAA;IAEnC,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"}
|
|
@@ -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,iBAchE"}
|
|
@@ -0,0 +1,44 @@
|
|
|
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
|
+
await setupGraphqlCodegen(config.targetDir);
|
|
22
|
+
}
|
|
23
|
+
async function injectDbDriver(appDir, db) {
|
|
24
|
+
const pkgPath = join(appDir, 'package.json');
|
|
25
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
26
|
+
pkg.dependencies[db.driver] = db.driverVersion;
|
|
27
|
+
if (db.typesPackage) {
|
|
28
|
+
pkg.devDependencies[db.typesPackage] = db.typesVersion;
|
|
29
|
+
}
|
|
30
|
+
await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
|
|
31
|
+
}
|
|
32
|
+
async function setupGraphqlCodegen(targetDir) {
|
|
33
|
+
const typesDir = join(targetDir, 'packages', 'types');
|
|
34
|
+
await copyTemplate(join(TEMPLATES_DIR, 'types-graphql'), typesDir, {});
|
|
35
|
+
const pkgPath = join(typesDir, 'package.json');
|
|
36
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
37
|
+
pkg.devDependencies['@graphql-codegen/cli'] = '^5.0.0';
|
|
38
|
+
pkg.devDependencies['@graphql-codegen/typescript'] = '^4.0.0';
|
|
39
|
+
pkg.devDependencies['@graphql-codegen/typescript-operations'] = '^4.0.0';
|
|
40
|
+
pkg.devDependencies['@graphql-codegen/typescript-react-apollo'] = '^4.0.0';
|
|
41
|
+
pkg.devDependencies['@parcel/watcher'] = '^2.0.0';
|
|
42
|
+
await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
|
|
43
|
+
}
|
|
44
|
+
//# 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":"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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;AAWhD,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,aAAa,
|
|
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,iBAc7D"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFile, writeFile
|
|
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
4
|
import { copyTemplate } from './utils/copy.js';
|
|
@@ -18,6 +18,7 @@ export async function scaffoldNestjsRest(config) {
|
|
|
18
18
|
dbPort: db.port,
|
|
19
19
|
});
|
|
20
20
|
await injectDbDriver(appDir, db);
|
|
21
|
+
await setupRestCodegen(config.targetDir);
|
|
21
22
|
}
|
|
22
23
|
async function injectDbDriver(appDir, db) {
|
|
23
24
|
const pkgPath = join(appDir, 'package.json');
|
|
@@ -28,4 +29,13 @@ async function injectDbDriver(appDir, db) {
|
|
|
28
29
|
}
|
|
29
30
|
await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
|
|
30
31
|
}
|
|
32
|
+
async function setupRestCodegen(targetDir) {
|
|
33
|
+
const typesDir = join(targetDir, 'packages', 'types');
|
|
34
|
+
await copyTemplate(join(TEMPLATES_DIR, 'types-rest'), typesDir, {});
|
|
35
|
+
const pkgPath = join(typesDir, 'package.json');
|
|
36
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
37
|
+
pkg.devDependencies['@hey-api/openapi-ts'] = '^0.64.0';
|
|
38
|
+
pkg.devDependencies['chokidar-cli'] = '^3.0.0';
|
|
39
|
+
await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
|
|
40
|
+
}
|
|
31
41
|
//# 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,
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"wire-client.d.ts","sourceRoot":"","sources":["../../../src/create/scaffolders/wire-client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,aAAa,iBAehE"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
export async function wireClientIntegration(config) {
|
|
4
|
+
const webDir = join(config.targetDir, 'apps', 'web');
|
|
5
|
+
const webPkgPath = join(webDir, 'package.json');
|
|
6
|
+
const pkg = JSON.parse(await readFile(webPkgPath, 'utf-8'));
|
|
7
|
+
pkg.dependencies['@local/types'] = 'workspace:*';
|
|
8
|
+
if (config.backend === 'nestjs-graphql') {
|
|
9
|
+
pkg.dependencies['@apollo/client'] = '^3.13.0';
|
|
10
|
+
pkg.dependencies['graphql'] = '^16.0.0';
|
|
11
|
+
await writeFile(webPkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
|
|
12
|
+
await setupApolloClient(config, webDir);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
await writeFile(webPkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async function setupApolloClient(config, webDir) {
|
|
19
|
+
await mkdir(join(webDir, 'src', 'lib'), { recursive: true });
|
|
20
|
+
await mkdir(join(webDir, 'src', 'graphql'), { recursive: true });
|
|
21
|
+
if (config.frontend === 'vite') {
|
|
22
|
+
await writeFile(join(webDir, 'src', 'lib', 'apollo.ts'), apolloViteClient(), 'utf-8');
|
|
23
|
+
await patchViteMain(webDir);
|
|
24
|
+
}
|
|
25
|
+
else if (config.frontend === 'nextjs') {
|
|
26
|
+
await writeFile(join(webDir, 'src', 'lib', 'apollo.ts'), apolloNextClient(), 'utf-8');
|
|
27
|
+
await writeFile(join(webDir, 'src', 'app', 'providers.tsx'), apolloNextProviders(), 'utf-8');
|
|
28
|
+
await patchNextLayout(webDir);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function patchViteMain(webDir) {
|
|
32
|
+
const mainPath = join(webDir, 'src', 'main.tsx');
|
|
33
|
+
const content = await readFile(mainPath, 'utf-8');
|
|
34
|
+
const patched = content
|
|
35
|
+
.replace(`import { StrictMode } from 'react'`, `import { ApolloProvider } from '@apollo/client'\nimport { StrictMode } from 'react'\nimport { client } from './lib/apollo'`)
|
|
36
|
+
.replace(`<App />`, `<ApolloProvider client={client}>\n <App />\n </ApolloProvider>`);
|
|
37
|
+
await writeFile(mainPath, patched, 'utf-8');
|
|
38
|
+
}
|
|
39
|
+
async function patchNextLayout(webDir) {
|
|
40
|
+
const layoutPath = join(webDir, 'src', 'app', 'layout.tsx');
|
|
41
|
+
const content = await readFile(layoutPath, 'utf-8');
|
|
42
|
+
const patched = content
|
|
43
|
+
.replace(`import type { Metadata } from "next";`, `import type { Metadata } from "next";\nimport { Providers } from './providers';`)
|
|
44
|
+
.replace(`<body>`, `<body>\n <Providers>`)
|
|
45
|
+
.replace(`</body>`, `</Providers>\n </body>`);
|
|
46
|
+
await writeFile(layoutPath, patched, 'utf-8');
|
|
47
|
+
}
|
|
48
|
+
function apolloViteClient() {
|
|
49
|
+
return `import { ApolloClient, InMemoryCache } from '@apollo/client'
|
|
50
|
+
|
|
51
|
+
export const client = new ApolloClient({
|
|
52
|
+
uri: import.meta.env.VITE_API_URL ?? 'http://localhost:3000/graphql',
|
|
53
|
+
cache: new InMemoryCache(),
|
|
54
|
+
})
|
|
55
|
+
`;
|
|
56
|
+
}
|
|
57
|
+
function apolloNextClient() {
|
|
58
|
+
return `import { ApolloClient, InMemoryCache } from '@apollo/client'
|
|
59
|
+
|
|
60
|
+
export const client = new ApolloClient({
|
|
61
|
+
uri: process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:3000/graphql',
|
|
62
|
+
cache: new InMemoryCache(),
|
|
63
|
+
})
|
|
64
|
+
`;
|
|
65
|
+
}
|
|
66
|
+
function apolloNextProviders() {
|
|
67
|
+
return `'use client'
|
|
68
|
+
|
|
69
|
+
import { ApolloProvider } from '@apollo/client'
|
|
70
|
+
import { client } from '../lib/apollo'
|
|
71
|
+
|
|
72
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
73
|
+
return <ApolloProvider client={client}>{children}</ApolloProvider>
|
|
74
|
+
}
|
|
75
|
+
`;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=wire-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wire-client.js","sourceRoot":"","sources":["../../../src/create/scaffolders/wire-client.ts"],"names":[],"mappings":"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"}
|
package/dist/create/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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
4
|
export type Database = 'postgres' | 'mysql';
|
|
5
5
|
export interface ProjectConfig {
|
|
6
6
|
projectName: string;
|
|
@@ -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
|
+
}
|