@dudousxd/nestjs-codegen 0.2.0 → 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/CHANGELOG.md +11 -0
- package/README.md +161 -0
- package/dist/cli/main.cjs +1 -1
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +1 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @dudousxd/nestjs-codegen
|
|
2
2
|
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0207fcc: docs: add a README to every published package and update the docs site to the extension architecture
|
|
8
|
+
|
|
9
|
+
Each package now ships a README (npm package pages were previously blank), and the
|
|
10
|
+
docs site documents integrations as registered `extensions: [...]` (the obsolete
|
|
11
|
+
`mutationClient` option is gone) with a new "Extensions" page covering the
|
|
12
|
+
`@dudousxd/nestjs-codegen/extension` contract.
|
|
13
|
+
|
|
3
14
|
## 0.2.0
|
|
4
15
|
|
|
5
16
|
### Minor Changes
|
package/README.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# @dudousxd/nestjs-codegen
|
|
2
|
+
|
|
3
|
+
> Extensible typed-client codegen for NestJS — routes, API client, and validation schemas.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
`nestjs-codegen` reads your NestJS controllers, `defineContract` contracts, DTOs, and
|
|
8
|
+
(optionally) Inertia pages via [ts-morph](https://ts-morph.com), builds a neutral schema
|
|
9
|
+
IR, and emits a **fully-typed client**: a route map, a Tuyau-style API client, and
|
|
10
|
+
client-side validation schemas. It works **with or without Inertia.js**, and every moving
|
|
11
|
+
part is pluggable — the validation library, the HTTP client, the serializer, and the query
|
|
12
|
+
layer.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add -D @dudousxd/nestjs-codegen
|
|
18
|
+
# the runtime the generated client imports its Fetcher type from:
|
|
19
|
+
pnpm add @dudousxd/nestjs-client
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The generated `api.ts` imports its `Fetcher` type from `@dudousxd/nestjs-client`, so it's a
|
|
23
|
+
real runtime dependency. `@nestjs/common`, `tsx`, and `typescript` are peer dependencies
|
|
24
|
+
(`@nestjs/common` and `tsx` are optional — your Nest app already has them).
|
|
25
|
+
|
|
26
|
+
## Quick start
|
|
27
|
+
|
|
28
|
+
Import `NestjsCodegenModule` into your root module. The codegen starts with your dev server
|
|
29
|
+
and regenerates the client as you edit your controllers — no config file, no extra process.
|
|
30
|
+
The watcher is a dev/CI concern, so the module skips itself automatically when
|
|
31
|
+
`NODE_ENV === 'production'`.
|
|
32
|
+
|
|
33
|
+
```ts title="src/app.module.ts"
|
|
34
|
+
import { Module } from '@nestjs/common';
|
|
35
|
+
import { NestjsCodegenModule } from '@dudousxd/nestjs-codegen/nest';
|
|
36
|
+
|
|
37
|
+
@Module({
|
|
38
|
+
imports: [
|
|
39
|
+
NestjsCodegenModule.forRoot({
|
|
40
|
+
// controllers to scan for routes + contracts
|
|
41
|
+
contracts: { glob: 'src/**/*.controller.ts' },
|
|
42
|
+
// output directory for the generated files
|
|
43
|
+
codegen: { outDir: 'src/generated' },
|
|
44
|
+
|
|
45
|
+
validation: 'zod', // 'zod' (bundled) | valibotAdapter | arktypeAdapter
|
|
46
|
+
}),
|
|
47
|
+
],
|
|
48
|
+
})
|
|
49
|
+
export class AppModule {}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The generated `api.ts` exports a `createApi(fetcher)` factory — create the client once,
|
|
53
|
+
injecting your fetcher. Each endpoint is a **unified awaitable handle**: `await` it to run
|
|
54
|
+
the request.
|
|
55
|
+
|
|
56
|
+
```ts title="src/lib/api.ts"
|
|
57
|
+
import { createApi } from '../generated/api';
|
|
58
|
+
import { createFetcher } from '@dudousxd/nestjs-client';
|
|
59
|
+
|
|
60
|
+
export const api = createApi(createFetcher({ baseUrl: '/api' }));
|
|
61
|
+
|
|
62
|
+
const users = await api.users.list(); // typed User[]
|
|
63
|
+
const created = await api.users.create({ body }); // typed body + response
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## What it generates
|
|
67
|
+
|
|
68
|
+
The codegen writes these files into your output directory:
|
|
69
|
+
|
|
70
|
+
- **`routes.ts`** — a `ROUTES` map, a `RouteName` union, and a typed `route()` helper.
|
|
71
|
+
- **`api.ts`** — a Tuyau-style `createApi(fetcher)` factory, nested by route name, fully typed.
|
|
72
|
+
- **`forms.ts`** — a validation schema per validated endpoint, in your chosen lib.
|
|
73
|
+
- **`pages.d.ts` / `components.json`** — when the Inertia integration is enabled.
|
|
74
|
+
|
|
75
|
+
## Extensions & the ecosystem
|
|
76
|
+
|
|
77
|
+
Everything beyond the core is pluggable. Extensions are registered via `extensions: [...]`;
|
|
78
|
+
validation adapters via `validation: ...`.
|
|
79
|
+
|
|
80
|
+
```ts title="src/app.module.ts"
|
|
81
|
+
import { NestjsCodegenModule } from '@dudousxd/nestjs-codegen/nest';
|
|
82
|
+
import { tanstackQuery } from '@dudousxd/nestjs-codegen-tanstack';
|
|
83
|
+
import { nestjsFilterCodegen } from '@dudousxd/nestjs-filter-codegen';
|
|
84
|
+
import { nestjsInertiaCodegen } from '@dudousxd/nestjs-inertia-codegen-extension';
|
|
85
|
+
import { arktypeAdapter } from '@dudousxd/nestjs-codegen-arktype';
|
|
86
|
+
|
|
87
|
+
NestjsCodegenModule.forRoot({
|
|
88
|
+
contracts: { glob: 'src/**/*.controller.ts' },
|
|
89
|
+
codegen: { outDir: 'src/generated' },
|
|
90
|
+
validation: arktypeAdapter, // render the IR as arktype instead of the bundled zod
|
|
91
|
+
extensions: [tanstackQuery(), nestjsFilterCodegen(), nestjsInertiaCodegen()],
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
When the TanStack extension is registered, every generated leaf becomes a unified handle:
|
|
96
|
+
`await api.users.show({ params })` performs the request, and the *same* handle carries
|
|
97
|
+
`.queryOptions()` / `.mutationOptions()` / `.infiniteQueryOptions()` / `.queryKey()`.
|
|
98
|
+
|
|
99
|
+
```tsx title="users-page.tsx"
|
|
100
|
+
import { useQuery, useMutation } from '@tanstack/react-query';
|
|
101
|
+
import { api } from '../lib/api';
|
|
102
|
+
|
|
103
|
+
const users = useQuery(api.users.list().queryOptions());
|
|
104
|
+
const create = useMutation(api.users.create().mutationOptions());
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
| Package | What it adds |
|
|
108
|
+
| --- | --- |
|
|
109
|
+
| [`@dudousxd/nestjs-client`](https://www.npmjs.com/package/@dudousxd/nestjs-client) | The runtime fetcher — `createFetcher` with a pluggable transport (native `fetch` or `axiosTransport()`) and a superjson hook. Pass it to `createApi(fetcher)`. |
|
|
110
|
+
| [`@dudousxd/nestjs-codegen-tanstack`](https://www.npmjs.com/package/@dudousxd/nestjs-codegen-tanstack) | TanStack Query helpers (`queryOptions` / `mutationOptions` / `infiniteQueryOptions` / `queryKey`) on each generated leaf. Registered as an extension. |
|
|
111
|
+
| [`@dudousxd/nestjs-codegen-arktype`](https://www.npmjs.com/package/@dudousxd/nestjs-codegen-arktype) | Validation adapter — render `forms.ts` as [arktype](https://arktype.io). Pass via `validation: arktypeAdapter`. |
|
|
112
|
+
| [`@dudousxd/nestjs-codegen-valibot`](https://www.npmjs.com/package/@dudousxd/nestjs-codegen-valibot) | Validation adapter — render `forms.ts` as [valibot](https://valibot.dev). Pass via `validation: valibotAdapter`. |
|
|
113
|
+
| [`@dudousxd/nestjs-filter-codegen`](https://www.npmjs.com/package/@dudousxd/nestjs-filter-codegen) | Extension — typed `filterQuery` helpers from the [nestjs-filter](https://github.com/DavideCarvalho/nestjs-filter) repo. |
|
|
114
|
+
| [`@dudousxd/nestjs-inertia-codegen-extension`](https://www.npmjs.com/package/@dudousxd/nestjs-inertia-codegen-extension) | Extension — Inertia `router` / navigate output from the nestjs-inertia repo. |
|
|
115
|
+
|
|
116
|
+
Write your own against the `@dudousxd/nestjs-codegen/extension` contract:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
import { defineExtension, type CodegenExtension } from '@dudousxd/nestjs-codegen/extension';
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## CLI
|
|
123
|
+
|
|
124
|
+
For CI (before deploy) you want a one-shot, watch-free run that fails the build if the
|
|
125
|
+
committed client has drifted. The package ships the `nestjs-codegen` CLI:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npx nestjs-codegen codegen # one-shot generate (CI); pair with `git diff --exit-code`
|
|
129
|
+
npx nestjs-codegen init # scaffold nestjs-codegen.config.ts
|
|
130
|
+
npx nestjs-codegen doctor # diagnose your setup
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The CLI reads `nestjs-codegen.config.ts` (the legacy `nestjs-inertia.config.ts` name is
|
|
134
|
+
still accepted) from your project root. Keep a single source of truth by authoring options
|
|
135
|
+
with `defineConfig` and importing them into `forRoot()`:
|
|
136
|
+
|
|
137
|
+
```ts title="nestjs-codegen.config.ts"
|
|
138
|
+
import { defineConfig } from '@dudousxd/nestjs-codegen';
|
|
139
|
+
|
|
140
|
+
export default defineConfig({
|
|
141
|
+
contracts: { glob: 'src/**/*.controller.ts' },
|
|
142
|
+
codegen: { outDir: 'src/generated' },
|
|
143
|
+
validation: 'zod',
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
npx nestjs-codegen codegen
|
|
149
|
+
git diff --exit-code src/generated # non-zero if the client is stale
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Documentation
|
|
153
|
+
|
|
154
|
+
Full docs — getting started, configuration, validation adapters, the fetcher, and the
|
|
155
|
+
extension contract — live in the repo:
|
|
156
|
+
|
|
157
|
+
- Repository & docs: https://github.com/DavideCarvalho/nestjs-codegen
|
|
158
|
+
|
|
159
|
+
## License
|
|
160
|
+
|
|
161
|
+
MIT
|