@dudousxd/nestjs-codegen 0.27.2 → 0.29.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/CHANGELOG.md +16 -0
- package/README.md +25 -0
- package/dist/cli/main.cjs +54 -13
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +55 -14
- package/dist/cli/main.js.map +1 -1
- package/dist/index.cjs +204 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -3
- package/dist/index.d.ts +69 -3
- package/dist/index.js +203 -8
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +48 -7
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.js +49 -8
- package/dist/nest/index.js.map +1 -1
- package/package.json +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @dudousxd/nestjs-codegen
|
|
2
2
|
|
|
3
|
+
## 0.29.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#113](https://github.com/DavideCarvalho/nestjs-codegen/pull/113) [`e01376c`](https://github.com/DavideCarvalho/nestjs-codegen/commit/e01376cce17518b32f105526c0b7627f01738921) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - `genuiSandboxKit()` takes the same options as the agent's Vite plugin: `components` (files, globs, directories or packages), `styles` (the app's style entries: the model is told the Tailwind tokens or the CSS class vocabulary, and the theme's variables), `wrapper`, `stylesDocs`, `tsconfig` and `output`. The stylesheets and what they `@import` are tracked as inputs.
|
|
8
|
+
|
|
9
|
+
**Breaking:** `include` and `entry` are now `components`, and `css` is now `styles`. Passing the old options throws a `CodegenError` naming the replacement. It needs `@dudousxd/nestjs-agent-core` >= 0.53.0.
|
|
10
|
+
|
|
11
|
+
## 0.28.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- [#111](https://github.com/DavideCarvalho/nestjs-codegen/pull/111) [`26529df`](https://github.com/DavideCarvalho/nestjs-codegen/commit/26529df5f6fd1f91148217f9149da41de49fc8ca) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - New built-in `genuiSandboxKit()` extension: writes the generative-UI sandbox-kit docs (`.genui/sandbox-kit.json`, the component names and props of your shadcn `components/ui` read from their TypeScript types) for `@dudousxd/nestjs-agent`, on every generate and in watch mode. It calls `writeSandboxKitDocs` from the optional peer `@dudousxd/nestjs-agent-core/genui/kit` (>=0.52.0), or a `generate` function you pass.
|
|
16
|
+
|
|
17
|
+
Watch mode now also watches the files extensions declare with `ctx.trackInput` (so editing an extension's out-of-glob dependency, such as a filter class or a kit component, regenerates without waiting for an unrelated change), and a tracked directory hashes as its file listing, so adding a file to it invalidates the skip-when-unchanged check.
|
|
18
|
+
|
|
3
19
|
## 0.27.2
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -116,6 +116,31 @@ const create = useMutation(api.users.create().mutationOptions());
|
|
|
116
116
|
| [`@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. |
|
|
117
117
|
| [`@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. |
|
|
118
118
|
|
|
119
|
+
### Generative-UI sandbox kit (built in)
|
|
120
|
+
|
|
121
|
+
`genuiSandboxKit()` writes the sandbox-kit docs that
|
|
122
|
+
[`@dudousxd/nestjs-agent`](https://github.com/DavideCarvalho/nestjs-agent) uses to render
|
|
123
|
+
generative UI in your design system. The names and props of your components (read from their
|
|
124
|
+
TypeScript types), and what your styles offer, go to `.genui/sandbox-kit.json`. That happens on
|
|
125
|
+
every generate and in watch mode. It needs the optional peer `@dudousxd/nestjs-agent-core`
|
|
126
|
+
(>=0.53.0).
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { defineConfig, genuiSandboxKit } from '@dudousxd/nestjs-codegen';
|
|
130
|
+
|
|
131
|
+
export default defineConfig({
|
|
132
|
+
contracts: { glob: 'src/**/*.controller.ts' },
|
|
133
|
+
codegen: { outDir: 'src/generated' },
|
|
134
|
+
extensions: [genuiSandboxKit({ components: 'web/components/ui', styles: 'web/styles/globals.css' })],
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Options (the same as the agent's Vite plugin):
|
|
139
|
+
|
|
140
|
+
- `components` (default: the first shadcn `components/ui` dir found), `styles`, `wrapper`, `stylesDocs`, `tsconfig`;
|
|
141
|
+
- `output` (default `.genui/sandbox-kit.json`, relative to the app cwd);
|
|
142
|
+
- `generate`, to inject the docs writer.
|
|
143
|
+
|
|
119
144
|
Write your own against the `@dudousxd/nestjs-codegen/extension` contract:
|
|
120
145
|
|
|
121
146
|
```ts
|
package/dist/cli/main.cjs
CHANGED
|
@@ -5663,14 +5663,26 @@ async function computeInputsHash(config, extraInputs = []) {
|
|
|
5663
5663
|
hash.update("\n");
|
|
5664
5664
|
}
|
|
5665
5665
|
for (const file of extra) {
|
|
5666
|
-
const contents = await (0, import_promises11.readFile)((0, import_node_path15.join)(cwd, file), "utf8").catch(() => null);
|
|
5667
5666
|
hash.update(`extra:${file}
|
|
5668
5667
|
`);
|
|
5669
|
-
hash.update(
|
|
5668
|
+
hash.update(await readTrackedInput((0, import_node_path15.join)(cwd, file)));
|
|
5670
5669
|
hash.update("\n");
|
|
5671
5670
|
}
|
|
5672
5671
|
return hash.digest("hex");
|
|
5673
5672
|
}
|
|
5673
|
+
async function readTrackedInput(path) {
|
|
5674
|
+
try {
|
|
5675
|
+
return await (0, import_promises11.readFile)(path, "utf8");
|
|
5676
|
+
} catch (err) {
|
|
5677
|
+
if (err.code !== "EISDIR") return "\0missing";
|
|
5678
|
+
}
|
|
5679
|
+
try {
|
|
5680
|
+
const entries = await (0, import_promises11.readdir)(path);
|
|
5681
|
+
return `\0dir:${entries.sort().join("\n")}`;
|
|
5682
|
+
} catch {
|
|
5683
|
+
return "\0missing";
|
|
5684
|
+
}
|
|
5685
|
+
}
|
|
5674
5686
|
async function readManifest(outDir) {
|
|
5675
5687
|
try {
|
|
5676
5688
|
const raw = await (0, import_promises11.readFile)((0, import_node_path15.join)(outDir, MANIFEST_FILE), "utf8");
|
|
@@ -5908,11 +5920,36 @@ async function watch(config, onChange, options = {}) {
|
|
|
5908
5920
|
}
|
|
5909
5921
|
return discovery;
|
|
5910
5922
|
}
|
|
5923
|
+
const trackedWatcher = import_chokidar.default.watch([], {
|
|
5924
|
+
ignoreInitial: true,
|
|
5925
|
+
persistent: true,
|
|
5926
|
+
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
5927
|
+
});
|
|
5928
|
+
const trackedPaths = /* @__PURE__ */ new Set();
|
|
5929
|
+
async function syncTrackedInputs() {
|
|
5930
|
+
const manifest = await readManifest(config.codegen.outDir);
|
|
5931
|
+
const fresh = [];
|
|
5932
|
+
for (const path of manifest?.extraInputs ?? []) {
|
|
5933
|
+
const abs = (0, import_node_path18.resolve)(config.codegen.cwd, path);
|
|
5934
|
+
if (trackedPaths.has(abs)) continue;
|
|
5935
|
+
trackedPaths.add(abs);
|
|
5936
|
+
fresh.push(abs);
|
|
5937
|
+
}
|
|
5938
|
+
if (fresh.length > 0) trackedWatcher.add(fresh);
|
|
5939
|
+
}
|
|
5940
|
+
async function generateAndTrack(routes) {
|
|
5941
|
+
try {
|
|
5942
|
+
await generate(config, routes, entryPoint);
|
|
5943
|
+
} finally {
|
|
5944
|
+
await syncTrackedInputs().catch(() => {
|
|
5945
|
+
});
|
|
5946
|
+
}
|
|
5947
|
+
}
|
|
5911
5948
|
async function runInitialPass() {
|
|
5912
5949
|
try {
|
|
5913
5950
|
const initialRoutes = (await getDiscovery()).discover();
|
|
5914
5951
|
lastRoutes = initialRoutes;
|
|
5915
|
-
await
|
|
5952
|
+
await generateAndTrack(initialRoutes);
|
|
5916
5953
|
} catch (err) {
|
|
5917
5954
|
if (err instanceof DriftGuardError) {
|
|
5918
5955
|
console.error(err.message);
|
|
@@ -5922,7 +5959,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
5922
5959
|
`[nestjs-codegen] Initial route discovery failed, falling back to pages-only: ${err instanceof Error ? err.message : String(err)}`
|
|
5923
5960
|
);
|
|
5924
5961
|
try {
|
|
5925
|
-
await
|
|
5962
|
+
await generateAndTrack(lastRoutes);
|
|
5926
5963
|
} catch {
|
|
5927
5964
|
}
|
|
5928
5965
|
}
|
|
@@ -5955,7 +5992,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
5955
5992
|
pagesDebounceTimer = setTimeout(async () => {
|
|
5956
5993
|
pagesDebounceTimer = void 0;
|
|
5957
5994
|
try {
|
|
5958
|
-
await
|
|
5995
|
+
await generateAndTrack(lastRoutes);
|
|
5959
5996
|
} catch (err) {
|
|
5960
5997
|
console.error(
|
|
5961
5998
|
"[nestjs-codegen] Pages generation failed:",
|
|
@@ -5987,7 +6024,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
5987
6024
|
try {
|
|
5988
6025
|
const routes = await (await getDiscovery()).rediscover(changed);
|
|
5989
6026
|
lastRoutes = routes;
|
|
5990
|
-
await
|
|
6027
|
+
await generateAndTrack(routes);
|
|
5991
6028
|
} catch (err) {
|
|
5992
6029
|
console.error(
|
|
5993
6030
|
"[nestjs-codegen] Contracts generation failed:",
|
|
@@ -6008,6 +6045,9 @@ async function watch(config, onChange, options = {}) {
|
|
|
6008
6045
|
formsWatcher.on("add", (p) => scheduleContractsRegenerate(p));
|
|
6009
6046
|
formsWatcher.on("change", (p) => scheduleContractsRegenerate(p));
|
|
6010
6047
|
formsWatcher.on("unlink", (p) => scheduleContractsRegenerate(p));
|
|
6048
|
+
trackedWatcher.on("add", (p) => scheduleContractsRegenerate(p));
|
|
6049
|
+
trackedWatcher.on("change", (p) => scheduleContractsRegenerate(p));
|
|
6050
|
+
trackedWatcher.on("unlink", (p) => scheduleContractsRegenerate(p));
|
|
6011
6051
|
return {
|
|
6012
6052
|
close: async () => {
|
|
6013
6053
|
if (pagesDebounceTimer !== void 0) {
|
|
@@ -6021,13 +6061,14 @@ async function watch(config, onChange, options = {}) {
|
|
|
6021
6061
|
await pagesWatcher.close();
|
|
6022
6062
|
await contractsWatcher.close();
|
|
6023
6063
|
await formsWatcher.close();
|
|
6064
|
+
await trackedWatcher.close();
|
|
6024
6065
|
await lock.release();
|
|
6025
6066
|
}
|
|
6026
6067
|
};
|
|
6027
6068
|
}
|
|
6028
6069
|
|
|
6029
6070
|
// src/index.ts
|
|
6030
|
-
var VERSION = "0.
|
|
6071
|
+
var VERSION = "0.29.0";
|
|
6031
6072
|
|
|
6032
6073
|
// src/cli/codegen.ts
|
|
6033
6074
|
async function runCodegen(opts = {}) {
|
|
@@ -6035,9 +6076,9 @@ async function runCodegen(opts = {}) {
|
|
|
6035
6076
|
const config = await loadConfig(cwd);
|
|
6036
6077
|
if (opts.watch) {
|
|
6037
6078
|
const watcher = await watch(config, void 0, { entryPoint: "cli" });
|
|
6038
|
-
await new Promise((
|
|
6079
|
+
await new Promise((resolve6) => {
|
|
6039
6080
|
function onSignal() {
|
|
6040
|
-
watcher.close().then(
|
|
6081
|
+
watcher.close().then(resolve6).catch(resolve6);
|
|
6041
6082
|
}
|
|
6042
6083
|
process.once("SIGINT", onSignal);
|
|
6043
6084
|
process.once("SIGTERM", onSignal);
|
|
@@ -6167,16 +6208,16 @@ async function detectPackageManager(cwd) {
|
|
|
6167
6208
|
}
|
|
6168
6209
|
async function promptFramework() {
|
|
6169
6210
|
if (!process.stdin.isTTY) return "react";
|
|
6170
|
-
return new Promise((
|
|
6211
|
+
return new Promise((resolve6) => {
|
|
6171
6212
|
const rl = (0, import_node_readline.createInterface)({ input: process.stdin, output: process.stdout });
|
|
6172
6213
|
rl.question(
|
|
6173
6214
|
"[nestjs-codegen] Which frontend framework? (react/vue/svelte) [react]: ",
|
|
6174
6215
|
(answer) => {
|
|
6175
6216
|
rl.close();
|
|
6176
6217
|
const trimmed = answer.trim().toLowerCase();
|
|
6177
|
-
if (trimmed === "vue")
|
|
6178
|
-
else if (trimmed === "svelte")
|
|
6179
|
-
else
|
|
6218
|
+
if (trimmed === "vue") resolve6("vue");
|
|
6219
|
+
else if (trimmed === "svelte") resolve6("svelte");
|
|
6220
|
+
else resolve6("react");
|
|
6180
6221
|
}
|
|
6181
6222
|
);
|
|
6182
6223
|
});
|