@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/dist/index.d.cts
CHANGED
|
@@ -141,7 +141,12 @@ interface WatchOptions {
|
|
|
141
141
|
* re-runs static AST route discovery via ts-morph, then re-emits `routes.ts` and (when
|
|
142
142
|
* contracts are present) `api.ts` + `index.d.ts`.
|
|
143
143
|
*
|
|
144
|
-
*
|
|
144
|
+
* 3. **Tracked-inputs watcher** — the files extensions declared via `ctx.trackInput` (recorded
|
|
145
|
+
* in the manifest as `extraInputs`), re-synced after every pass. A change re-runs the
|
|
146
|
+
* contracts path, so an extension's out-of-glob dependencies (a filter class, a sandbox-kit
|
|
147
|
+
* component) regenerate in watch mode too, not only on the next one-shot run.
|
|
148
|
+
*
|
|
149
|
+
* All watchers share a single lock file in `config.codegen.outDir`. If another live process
|
|
145
150
|
* already holds the lock, logs a warning and returns a no-op watcher.
|
|
146
151
|
*/
|
|
147
152
|
declare function watch(config: ResolvedConfig, onChange?: () => void, options?: WatchOptions): Promise<Watcher>;
|
|
@@ -367,6 +372,67 @@ declare function buildMocksFile(routes: RouteDescriptor[], opts?: MocksEmitOptio
|
|
|
367
372
|
/** Emit `mocks.ts` into `outDir`. */
|
|
368
373
|
declare function emitMocks(routes: RouteDescriptor[], outDir: string, opts?: MocksEmitOptions): Promise<void>;
|
|
369
374
|
|
|
375
|
+
/** Where the Nest server reads the descriptor from by default (relative to the app root). */
|
|
376
|
+
declare const DEFAULT_SANDBOX_KIT_OUTPUT = ".genui/sandbox-kit.json";
|
|
377
|
+
/** What {@link genuiSandboxKit} passes to `writeSandboxKitDocs`. */
|
|
378
|
+
interface WriteSandboxKitDocsOptions {
|
|
379
|
+
root: string;
|
|
380
|
+
output: string;
|
|
381
|
+
components?: string | readonly string[];
|
|
382
|
+
styles?: string | readonly string[];
|
|
383
|
+
wrapper?: string;
|
|
384
|
+
stylesDocs?: string;
|
|
385
|
+
tsconfig?: string;
|
|
386
|
+
}
|
|
387
|
+
/** The same options as the agent's Vite plugin (`@dudousxd/nestjs-agent/vite`). */
|
|
388
|
+
interface GenuiSandboxKitOptions {
|
|
389
|
+
/**
|
|
390
|
+
* Modules whose exports are the kit's React components: files, globs, directories or packages
|
|
391
|
+
* (`web/components/ui`, `src/genui/kit.ts`, `@mui/material`). Default: the first shadcn
|
|
392
|
+
* `components/ui` dir found.
|
|
393
|
+
*/
|
|
394
|
+
components?: string | readonly string[];
|
|
395
|
+
/**
|
|
396
|
+
* The app's style entry files (plain CSS, Sass, a Tailwind stylesheet…): what the model is told
|
|
397
|
+
* about the styles (Tailwind tokens, or the CSS class vocabulary) and the theme's variables.
|
|
398
|
+
*/
|
|
399
|
+
styles?: string | readonly string[];
|
|
400
|
+
/** A module whose default export wraps the model's App (theme providers). */
|
|
401
|
+
wrapper?: string;
|
|
402
|
+
/** Guidance on the styles for the model: a markdown file, or the text itself. */
|
|
403
|
+
stylesDocs?: string;
|
|
404
|
+
/** The tsconfig the component prop types are read through. */
|
|
405
|
+
tsconfig?: string;
|
|
406
|
+
/**
|
|
407
|
+
* Where the descriptor is written, relative to the app `cwd` (or absolute).
|
|
408
|
+
* @default '.genui/sandbox-kit.json'
|
|
409
|
+
*/
|
|
410
|
+
output?: string;
|
|
411
|
+
/**
|
|
412
|
+
* The docs writer. Defaults to `writeSandboxKitDocs` from
|
|
413
|
+
* `@dudousxd/nestjs-agent-core/genui/kit`; inject one to test, or to use another generator.
|
|
414
|
+
* It is expected to write `output` itself (and only when the contents change).
|
|
415
|
+
*/
|
|
416
|
+
generate?: (options: WriteSandboxKitDocsOptions) => Promise<unknown>;
|
|
417
|
+
/** The module the writer is loaded from. Default `@dudousxd/nestjs-agent-core/genui/kit`. */
|
|
418
|
+
kitModule?: string;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Writes the generative-UI **sandbox kit docs** — the app's design-system components (shadcn
|
|
422
|
+
* `components/ui` by default) with the props read from their TypeScript types, and what its
|
|
423
|
+
* `styles` are (Tailwind tokens, or a CSS class vocabulary, and the theme's variables) — to
|
|
424
|
+
* `.genui/sandbox-kit.json`, where the `@dudousxd/nestjs-agent` server reads them.
|
|
425
|
+
*
|
|
426
|
+
* Runs on every generate pass (one-shot CLI, `--watch`, and the Nest module's watcher). The
|
|
427
|
+
* descriptor lives outside `outDir`, so it is written by the generator itself, not through
|
|
428
|
+
* `emitFiles`; the kit files, the stylesheets (and what they import) and the descriptor are
|
|
429
|
+
* tracked as inputs, so editing a component or a stylesheet regenerates in watch mode and a
|
|
430
|
+
* deleted descriptor is rewritten.
|
|
431
|
+
*
|
|
432
|
+
* Needs the optional peer `@dudousxd/nestjs-agent-core` (>=0.53.0) unless `generate` is given.
|
|
433
|
+
*/
|
|
434
|
+
declare function genuiSandboxKit(options?: GenuiSandboxKitOptions): CodegenExtension;
|
|
435
|
+
|
|
370
436
|
/**
|
|
371
437
|
* Static AST-based contract discovery using ts-morph.
|
|
372
438
|
* Cold start ~100-500 ms.
|
|
@@ -382,6 +448,6 @@ interface FastDiscoveryOptions {
|
|
|
382
448
|
}
|
|
383
449
|
declare function discoverContractsFast(opts: FastDiscoveryOptions): Promise<RouteDescriptor[]>;
|
|
384
450
|
|
|
385
|
-
declare const VERSION = "0.
|
|
451
|
+
declare const VERSION = "0.29.0";
|
|
386
452
|
|
|
387
|
-
export { type ChainModuleRendererOptions, CodegenError, type CodegenManifest, ConfigError, DriftGuardError, type EntryPoint, type FastDiscoveryOptions, type JsonSchema, type MocksEmitOptions, type OpenApiDocument, type OpenApiEmitOptions, type OpenApiInfo, RenderContext, RenderedModule, ResolvedConfig, RouteDescriptor, SchemaModule, SchemaNode, type TsTypeContext, UserConfig, VERSION, ValidationAdapter, type WatchOptions, type Watcher, acquireLock, buildMocksFile, buildOpenApiSpec, createChainModuleRenderer, defineConfig, discoverContractsFast, emitApi, emitForms, emitMocks, emitOpenApi, emitRoutes, extractSchemaFromDto, generate, loadConfig, renderTsType, resolveConfig, schemaModuleToJsonSchema, schemaNodeToJsonSchema, toObjectKey, typeNameFor, watch };
|
|
453
|
+
export { type ChainModuleRendererOptions, CodegenError, type CodegenManifest, ConfigError, DEFAULT_SANDBOX_KIT_OUTPUT, DriftGuardError, type EntryPoint, type FastDiscoveryOptions, type GenuiSandboxKitOptions, type JsonSchema, type MocksEmitOptions, type OpenApiDocument, type OpenApiEmitOptions, type OpenApiInfo, RenderContext, RenderedModule, ResolvedConfig, RouteDescriptor, SchemaModule, SchemaNode, type TsTypeContext, UserConfig, VERSION, ValidationAdapter, type WatchOptions, type Watcher, type WriteSandboxKitDocsOptions, acquireLock, buildMocksFile, buildOpenApiSpec, createChainModuleRenderer, defineConfig, discoverContractsFast, emitApi, emitForms, emitMocks, emitOpenApi, emitRoutes, extractSchemaFromDto, generate, genuiSandboxKit, loadConfig, renderTsType, resolveConfig, schemaModuleToJsonSchema, schemaNodeToJsonSchema, toObjectKey, typeNameFor, watch };
|
package/dist/index.d.ts
CHANGED
|
@@ -141,7 +141,12 @@ interface WatchOptions {
|
|
|
141
141
|
* re-runs static AST route discovery via ts-morph, then re-emits `routes.ts` and (when
|
|
142
142
|
* contracts are present) `api.ts` + `index.d.ts`.
|
|
143
143
|
*
|
|
144
|
-
*
|
|
144
|
+
* 3. **Tracked-inputs watcher** — the files extensions declared via `ctx.trackInput` (recorded
|
|
145
|
+
* in the manifest as `extraInputs`), re-synced after every pass. A change re-runs the
|
|
146
|
+
* contracts path, so an extension's out-of-glob dependencies (a filter class, a sandbox-kit
|
|
147
|
+
* component) regenerate in watch mode too, not only on the next one-shot run.
|
|
148
|
+
*
|
|
149
|
+
* All watchers share a single lock file in `config.codegen.outDir`. If another live process
|
|
145
150
|
* already holds the lock, logs a warning and returns a no-op watcher.
|
|
146
151
|
*/
|
|
147
152
|
declare function watch(config: ResolvedConfig, onChange?: () => void, options?: WatchOptions): Promise<Watcher>;
|
|
@@ -367,6 +372,67 @@ declare function buildMocksFile(routes: RouteDescriptor[], opts?: MocksEmitOptio
|
|
|
367
372
|
/** Emit `mocks.ts` into `outDir`. */
|
|
368
373
|
declare function emitMocks(routes: RouteDescriptor[], outDir: string, opts?: MocksEmitOptions): Promise<void>;
|
|
369
374
|
|
|
375
|
+
/** Where the Nest server reads the descriptor from by default (relative to the app root). */
|
|
376
|
+
declare const DEFAULT_SANDBOX_KIT_OUTPUT = ".genui/sandbox-kit.json";
|
|
377
|
+
/** What {@link genuiSandboxKit} passes to `writeSandboxKitDocs`. */
|
|
378
|
+
interface WriteSandboxKitDocsOptions {
|
|
379
|
+
root: string;
|
|
380
|
+
output: string;
|
|
381
|
+
components?: string | readonly string[];
|
|
382
|
+
styles?: string | readonly string[];
|
|
383
|
+
wrapper?: string;
|
|
384
|
+
stylesDocs?: string;
|
|
385
|
+
tsconfig?: string;
|
|
386
|
+
}
|
|
387
|
+
/** The same options as the agent's Vite plugin (`@dudousxd/nestjs-agent/vite`). */
|
|
388
|
+
interface GenuiSandboxKitOptions {
|
|
389
|
+
/**
|
|
390
|
+
* Modules whose exports are the kit's React components: files, globs, directories or packages
|
|
391
|
+
* (`web/components/ui`, `src/genui/kit.ts`, `@mui/material`). Default: the first shadcn
|
|
392
|
+
* `components/ui` dir found.
|
|
393
|
+
*/
|
|
394
|
+
components?: string | readonly string[];
|
|
395
|
+
/**
|
|
396
|
+
* The app's style entry files (plain CSS, Sass, a Tailwind stylesheet…): what the model is told
|
|
397
|
+
* about the styles (Tailwind tokens, or the CSS class vocabulary) and the theme's variables.
|
|
398
|
+
*/
|
|
399
|
+
styles?: string | readonly string[];
|
|
400
|
+
/** A module whose default export wraps the model's App (theme providers). */
|
|
401
|
+
wrapper?: string;
|
|
402
|
+
/** Guidance on the styles for the model: a markdown file, or the text itself. */
|
|
403
|
+
stylesDocs?: string;
|
|
404
|
+
/** The tsconfig the component prop types are read through. */
|
|
405
|
+
tsconfig?: string;
|
|
406
|
+
/**
|
|
407
|
+
* Where the descriptor is written, relative to the app `cwd` (or absolute).
|
|
408
|
+
* @default '.genui/sandbox-kit.json'
|
|
409
|
+
*/
|
|
410
|
+
output?: string;
|
|
411
|
+
/**
|
|
412
|
+
* The docs writer. Defaults to `writeSandboxKitDocs` from
|
|
413
|
+
* `@dudousxd/nestjs-agent-core/genui/kit`; inject one to test, or to use another generator.
|
|
414
|
+
* It is expected to write `output` itself (and only when the contents change).
|
|
415
|
+
*/
|
|
416
|
+
generate?: (options: WriteSandboxKitDocsOptions) => Promise<unknown>;
|
|
417
|
+
/** The module the writer is loaded from. Default `@dudousxd/nestjs-agent-core/genui/kit`. */
|
|
418
|
+
kitModule?: string;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Writes the generative-UI **sandbox kit docs** — the app's design-system components (shadcn
|
|
422
|
+
* `components/ui` by default) with the props read from their TypeScript types, and what its
|
|
423
|
+
* `styles` are (Tailwind tokens, or a CSS class vocabulary, and the theme's variables) — to
|
|
424
|
+
* `.genui/sandbox-kit.json`, where the `@dudousxd/nestjs-agent` server reads them.
|
|
425
|
+
*
|
|
426
|
+
* Runs on every generate pass (one-shot CLI, `--watch`, and the Nest module's watcher). The
|
|
427
|
+
* descriptor lives outside `outDir`, so it is written by the generator itself, not through
|
|
428
|
+
* `emitFiles`; the kit files, the stylesheets (and what they import) and the descriptor are
|
|
429
|
+
* tracked as inputs, so editing a component or a stylesheet regenerates in watch mode and a
|
|
430
|
+
* deleted descriptor is rewritten.
|
|
431
|
+
*
|
|
432
|
+
* Needs the optional peer `@dudousxd/nestjs-agent-core` (>=0.53.0) unless `generate` is given.
|
|
433
|
+
*/
|
|
434
|
+
declare function genuiSandboxKit(options?: GenuiSandboxKitOptions): CodegenExtension;
|
|
435
|
+
|
|
370
436
|
/**
|
|
371
437
|
* Static AST-based contract discovery using ts-morph.
|
|
372
438
|
* Cold start ~100-500 ms.
|
|
@@ -382,6 +448,6 @@ interface FastDiscoveryOptions {
|
|
|
382
448
|
}
|
|
383
449
|
declare function discoverContractsFast(opts: FastDiscoveryOptions): Promise<RouteDescriptor[]>;
|
|
384
450
|
|
|
385
|
-
declare const VERSION = "0.
|
|
451
|
+
declare const VERSION = "0.29.0";
|
|
386
452
|
|
|
387
|
-
export { type ChainModuleRendererOptions, CodegenError, type CodegenManifest, ConfigError, DriftGuardError, type EntryPoint, type FastDiscoveryOptions, type JsonSchema, type MocksEmitOptions, type OpenApiDocument, type OpenApiEmitOptions, type OpenApiInfo, RenderContext, RenderedModule, ResolvedConfig, RouteDescriptor, SchemaModule, SchemaNode, type TsTypeContext, UserConfig, VERSION, ValidationAdapter, type WatchOptions, type Watcher, acquireLock, buildMocksFile, buildOpenApiSpec, createChainModuleRenderer, defineConfig, discoverContractsFast, emitApi, emitForms, emitMocks, emitOpenApi, emitRoutes, extractSchemaFromDto, generate, loadConfig, renderTsType, resolveConfig, schemaModuleToJsonSchema, schemaNodeToJsonSchema, toObjectKey, typeNameFor, watch };
|
|
453
|
+
export { type ChainModuleRendererOptions, CodegenError, type CodegenManifest, ConfigError, DEFAULT_SANDBOX_KIT_OUTPUT, DriftGuardError, type EntryPoint, type FastDiscoveryOptions, type GenuiSandboxKitOptions, type JsonSchema, type MocksEmitOptions, type OpenApiDocument, type OpenApiEmitOptions, type OpenApiInfo, RenderContext, RenderedModule, ResolvedConfig, RouteDescriptor, SchemaModule, SchemaNode, type TsTypeContext, UserConfig, VERSION, ValidationAdapter, type WatchOptions, type Watcher, type WriteSandboxKitDocsOptions, acquireLock, buildMocksFile, buildOpenApiSpec, createChainModuleRenderer, defineConfig, discoverContractsFast, emitApi, emitForms, emitMocks, emitOpenApi, emitRoutes, extractSchemaFromDto, generate, genuiSandboxKit, loadConfig, renderTsType, resolveConfig, schemaModuleToJsonSchema, schemaNodeToJsonSchema, toObjectKey, typeNameFor, watch };
|
package/dist/index.js
CHANGED
|
@@ -5655,14 +5655,26 @@ async function computeInputsHash(config, extraInputs = []) {
|
|
|
5655
5655
|
hash.update("\n");
|
|
5656
5656
|
}
|
|
5657
5657
|
for (const file of extra) {
|
|
5658
|
-
const contents = await readFile2(join13(cwd, file), "utf8").catch(() => null);
|
|
5659
5658
|
hash.update(`extra:${file}
|
|
5660
5659
|
`);
|
|
5661
|
-
hash.update(
|
|
5660
|
+
hash.update(await readTrackedInput(join13(cwd, file)));
|
|
5662
5661
|
hash.update("\n");
|
|
5663
5662
|
}
|
|
5664
5663
|
return hash.digest("hex");
|
|
5665
5664
|
}
|
|
5665
|
+
async function readTrackedInput(path) {
|
|
5666
|
+
try {
|
|
5667
|
+
return await readFile2(path, "utf8");
|
|
5668
|
+
} catch (err) {
|
|
5669
|
+
if (err.code !== "EISDIR") return "\0missing";
|
|
5670
|
+
}
|
|
5671
|
+
try {
|
|
5672
|
+
const entries = await readdir(path);
|
|
5673
|
+
return `\0dir:${entries.sort().join("\n")}`;
|
|
5674
|
+
} catch {
|
|
5675
|
+
return "\0missing";
|
|
5676
|
+
}
|
|
5677
|
+
}
|
|
5666
5678
|
async function readManifest(outDir) {
|
|
5667
5679
|
try {
|
|
5668
5680
|
const raw = await readFile2(join13(outDir, MANIFEST_FILE), "utf8");
|
|
@@ -5818,7 +5830,7 @@ async function generate(config, inputRoutes = [], entryPoint = "cli") {
|
|
|
5818
5830
|
|
|
5819
5831
|
// src/watch/watcher.ts
|
|
5820
5832
|
import { readFile as readFile4 } from "fs/promises";
|
|
5821
|
-
import { join as join16 } from "path";
|
|
5833
|
+
import { join as join16, resolve as resolve5 } from "path";
|
|
5822
5834
|
import chokidar from "chokidar";
|
|
5823
5835
|
|
|
5824
5836
|
// src/watch/lock-file.ts
|
|
@@ -5900,11 +5912,36 @@ async function watch(config, onChange, options = {}) {
|
|
|
5900
5912
|
}
|
|
5901
5913
|
return discovery;
|
|
5902
5914
|
}
|
|
5915
|
+
const trackedWatcher = chokidar.watch([], {
|
|
5916
|
+
ignoreInitial: true,
|
|
5917
|
+
persistent: true,
|
|
5918
|
+
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
5919
|
+
});
|
|
5920
|
+
const trackedPaths = /* @__PURE__ */ new Set();
|
|
5921
|
+
async function syncTrackedInputs() {
|
|
5922
|
+
const manifest = await readManifest(config.codegen.outDir);
|
|
5923
|
+
const fresh = [];
|
|
5924
|
+
for (const path of manifest?.extraInputs ?? []) {
|
|
5925
|
+
const abs = resolve5(config.codegen.cwd, path);
|
|
5926
|
+
if (trackedPaths.has(abs)) continue;
|
|
5927
|
+
trackedPaths.add(abs);
|
|
5928
|
+
fresh.push(abs);
|
|
5929
|
+
}
|
|
5930
|
+
if (fresh.length > 0) trackedWatcher.add(fresh);
|
|
5931
|
+
}
|
|
5932
|
+
async function generateAndTrack(routes) {
|
|
5933
|
+
try {
|
|
5934
|
+
await generate(config, routes, entryPoint);
|
|
5935
|
+
} finally {
|
|
5936
|
+
await syncTrackedInputs().catch(() => {
|
|
5937
|
+
});
|
|
5938
|
+
}
|
|
5939
|
+
}
|
|
5903
5940
|
async function runInitialPass() {
|
|
5904
5941
|
try {
|
|
5905
5942
|
const initialRoutes = (await getDiscovery()).discover();
|
|
5906
5943
|
lastRoutes = initialRoutes;
|
|
5907
|
-
await
|
|
5944
|
+
await generateAndTrack(initialRoutes);
|
|
5908
5945
|
} catch (err) {
|
|
5909
5946
|
if (err instanceof DriftGuardError) {
|
|
5910
5947
|
console.error(err.message);
|
|
@@ -5914,7 +5951,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
5914
5951
|
`[nestjs-codegen] Initial route discovery failed, falling back to pages-only: ${err instanceof Error ? err.message : String(err)}`
|
|
5915
5952
|
);
|
|
5916
5953
|
try {
|
|
5917
|
-
await
|
|
5954
|
+
await generateAndTrack(lastRoutes);
|
|
5918
5955
|
} catch {
|
|
5919
5956
|
}
|
|
5920
5957
|
}
|
|
@@ -5947,7 +5984,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
5947
5984
|
pagesDebounceTimer = setTimeout(async () => {
|
|
5948
5985
|
pagesDebounceTimer = void 0;
|
|
5949
5986
|
try {
|
|
5950
|
-
await
|
|
5987
|
+
await generateAndTrack(lastRoutes);
|
|
5951
5988
|
} catch (err) {
|
|
5952
5989
|
console.error(
|
|
5953
5990
|
"[nestjs-codegen] Pages generation failed:",
|
|
@@ -5979,7 +6016,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
5979
6016
|
try {
|
|
5980
6017
|
const routes = await (await getDiscovery()).rediscover(changed);
|
|
5981
6018
|
lastRoutes = routes;
|
|
5982
|
-
await
|
|
6019
|
+
await generateAndTrack(routes);
|
|
5983
6020
|
} catch (err) {
|
|
5984
6021
|
console.error(
|
|
5985
6022
|
"[nestjs-codegen] Contracts generation failed:",
|
|
@@ -6000,6 +6037,9 @@ async function watch(config, onChange, options = {}) {
|
|
|
6000
6037
|
formsWatcher.on("add", (p) => scheduleContractsRegenerate(p));
|
|
6001
6038
|
formsWatcher.on("change", (p) => scheduleContractsRegenerate(p));
|
|
6002
6039
|
formsWatcher.on("unlink", (p) => scheduleContractsRegenerate(p));
|
|
6040
|
+
trackedWatcher.on("add", (p) => scheduleContractsRegenerate(p));
|
|
6041
|
+
trackedWatcher.on("change", (p) => scheduleContractsRegenerate(p));
|
|
6042
|
+
trackedWatcher.on("unlink", (p) => scheduleContractsRegenerate(p));
|
|
6003
6043
|
return {
|
|
6004
6044
|
close: async () => {
|
|
6005
6045
|
if (pagesDebounceTimer !== void 0) {
|
|
@@ -6013,6 +6053,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
6013
6053
|
await pagesWatcher.close();
|
|
6014
6054
|
await contractsWatcher.close();
|
|
6015
6055
|
await formsWatcher.close();
|
|
6056
|
+
await trackedWatcher.close();
|
|
6016
6057
|
await lock.release();
|
|
6017
6058
|
}
|
|
6018
6059
|
};
|
|
@@ -6101,11 +6142,164 @@ function createChainModuleRenderer(opts) {
|
|
|
6101
6142
|
};
|
|
6102
6143
|
}
|
|
6103
6144
|
|
|
6145
|
+
// src/extension/genui-sandbox-kit.ts
|
|
6146
|
+
import { existsSync as existsSync2, statSync } from "fs";
|
|
6147
|
+
import { dirname as dirname5, isAbsolute as isAbsolute3, resolve as resolve6 } from "path";
|
|
6148
|
+
import fg4 from "fast-glob";
|
|
6149
|
+
var GENUI_KIT_MODULE = "@dudousxd/nestjs-agent-core/genui/kit";
|
|
6150
|
+
var DEFAULT_SANDBOX_KIT_OUTPUT = ".genui/sandbox-kit.json";
|
|
6151
|
+
var DEFAULT_KIT_DIRS = [
|
|
6152
|
+
"inertia/components/ui",
|
|
6153
|
+
"resources/js/components/ui",
|
|
6154
|
+
"src/components/ui",
|
|
6155
|
+
"app/components/ui",
|
|
6156
|
+
"components/ui"
|
|
6157
|
+
];
|
|
6158
|
+
var LEGACY_OPTIONS = {
|
|
6159
|
+
entry: "`entry: X` is now `components: X`",
|
|
6160
|
+
include: "`include: G` is now `components: G` (globs, files, directories or packages)",
|
|
6161
|
+
css: "`css: G` is now `styles: G` (the app's style entry files)"
|
|
6162
|
+
};
|
|
6163
|
+
var MIN_CORE = "0.53.0";
|
|
6164
|
+
async function loadKitModule(specifier = GENUI_KIT_MODULE) {
|
|
6165
|
+
let mod;
|
|
6166
|
+
try {
|
|
6167
|
+
mod = await import(specifier);
|
|
6168
|
+
} catch (err) {
|
|
6169
|
+
const code = err.code;
|
|
6170
|
+
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") {
|
|
6171
|
+
throw new CodegenError(
|
|
6172
|
+
`genuiSandboxKit() needs "${GENUI_KIT_MODULE}" \u2014 install @dudousxd/nestjs-agent-core@>=${MIN_CORE}, or pass \`generate\` to genuiSandboxKit().`
|
|
6173
|
+
);
|
|
6174
|
+
}
|
|
6175
|
+
if (code === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
|
|
6176
|
+
throw new CodegenError(
|
|
6177
|
+
`genuiSandboxKit() needs "${GENUI_KIT_MODULE}", which the installed @dudousxd/nestjs-agent-core does not export \u2014 upgrade it to >=${MIN_CORE}.`
|
|
6178
|
+
);
|
|
6179
|
+
}
|
|
6180
|
+
throw err;
|
|
6181
|
+
}
|
|
6182
|
+
if (typeof mod.writeSandboxKitDocs !== "function") {
|
|
6183
|
+
throw new CodegenError(
|
|
6184
|
+
`"${GENUI_KIT_MODULE}" has no writeSandboxKitDocs export \u2014 upgrade @dudousxd/nestjs-agent-core to >=${MIN_CORE}.`
|
|
6185
|
+
);
|
|
6186
|
+
}
|
|
6187
|
+
if (typeof mod.resolveStyleEntries !== "function") {
|
|
6188
|
+
throw new CodegenError(
|
|
6189
|
+
`The installed @dudousxd/nestjs-agent-core predates genuiSandboxKit({ components, styles, wrapper }) \u2014 upgrade it to >=${MIN_CORE}.`
|
|
6190
|
+
);
|
|
6191
|
+
}
|
|
6192
|
+
return mod;
|
|
6193
|
+
}
|
|
6194
|
+
function globBase(glob) {
|
|
6195
|
+
const base = [];
|
|
6196
|
+
for (const part of glob.replace(/\\/g, "/").split("/")) {
|
|
6197
|
+
if (/[*?{[]/.test(part)) break;
|
|
6198
|
+
base.push(part);
|
|
6199
|
+
}
|
|
6200
|
+
return base.join("/");
|
|
6201
|
+
}
|
|
6202
|
+
function resolveKitFilesLocally(root, options) {
|
|
6203
|
+
const specs = options.components === void 0 ? DEFAULT_KIT_DIRS.filter((dir) => existsSync2(resolve6(root, dir))).slice(0, 1) : typeof options.components === "string" ? [options.components] : [...options.components];
|
|
6204
|
+
const files = [];
|
|
6205
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
6206
|
+
for (const spec of specs) {
|
|
6207
|
+
if (/[*?{]/.test(spec)) {
|
|
6208
|
+
files.push(...fg4.sync(spec, { cwd: root, absolute: true, onlyFiles: true }));
|
|
6209
|
+
dirs.add(resolve6(root, globBase(spec)));
|
|
6210
|
+
continue;
|
|
6211
|
+
}
|
|
6212
|
+
const path = isAbsolute3(spec) ? spec : resolve6(root, spec);
|
|
6213
|
+
if (existsSync2(path) && statSync(path).isDirectory()) {
|
|
6214
|
+
files.push(...fg4.sync("*.{tsx,jsx,ts,js}", { cwd: path, absolute: true, onlyFiles: true }));
|
|
6215
|
+
dirs.add(path);
|
|
6216
|
+
} else if (existsSync2(path)) {
|
|
6217
|
+
files.push(path);
|
|
6218
|
+
dirs.add(dirname5(path));
|
|
6219
|
+
}
|
|
6220
|
+
}
|
|
6221
|
+
if (options.wrapper !== void 0) {
|
|
6222
|
+
const wrapper = isAbsolute3(options.wrapper) ? options.wrapper : resolve6(root, options.wrapper);
|
|
6223
|
+
if (existsSync2(wrapper)) files.push(wrapper);
|
|
6224
|
+
}
|
|
6225
|
+
if (files.length === 0 && dirs.size === 0) return null;
|
|
6226
|
+
return { files: [...new Set(files)].sort(), dirs: [...dirs] };
|
|
6227
|
+
}
|
|
6228
|
+
function genuiSandboxKit(options = {}) {
|
|
6229
|
+
const legacy = Object.keys(LEGACY_OPTIONS).filter(
|
|
6230
|
+
(key) => options[key] !== void 0
|
|
6231
|
+
);
|
|
6232
|
+
if (legacy.length > 0) {
|
|
6233
|
+
throw new CodegenError(
|
|
6234
|
+
`genuiSandboxKit(): ${legacy.map((key) => `\`${key}\``).join(", ")} ${legacy.length > 1 ? "were" : "was"} removed \u2014 ${legacy.map((key) => LEGACY_OPTIONS[key]).join("; ")}. The options are now the agent's Vite plugin's: components, styles, wrapper, stylesDocs.`
|
|
6235
|
+
);
|
|
6236
|
+
}
|
|
6237
|
+
const output = options.output ?? DEFAULT_SANDBOX_KIT_OUTPUT;
|
|
6238
|
+
const source = {
|
|
6239
|
+
...options.components !== void 0 ? { components: options.components } : {},
|
|
6240
|
+
...options.wrapper !== void 0 ? { wrapper: options.wrapper } : {}
|
|
6241
|
+
};
|
|
6242
|
+
const extension = {
|
|
6243
|
+
name: "genui-sandbox-kit",
|
|
6244
|
+
// Not read by the host: serialized into the config hash, so changing an option
|
|
6245
|
+
// invalidates skip-when-unchanged.
|
|
6246
|
+
options: {
|
|
6247
|
+
...source,
|
|
6248
|
+
styles: options.styles,
|
|
6249
|
+
stylesDocs: options.stylesDocs,
|
|
6250
|
+
tsconfig: options.tsconfig,
|
|
6251
|
+
output
|
|
6252
|
+
},
|
|
6253
|
+
async emitFiles(ctx) {
|
|
6254
|
+
const root = ctx.cwd;
|
|
6255
|
+
let generate2 = options.generate;
|
|
6256
|
+
let mod;
|
|
6257
|
+
if (!generate2) {
|
|
6258
|
+
mod = await loadKitModule(options.kitModule);
|
|
6259
|
+
generate2 = mod.writeSandboxKitDocs;
|
|
6260
|
+
}
|
|
6261
|
+
const resolveFiles = mod?.resolveSandboxKitFiles ?? resolveKitFilesLocally;
|
|
6262
|
+
let kit = null;
|
|
6263
|
+
try {
|
|
6264
|
+
kit = resolveFiles(root, source);
|
|
6265
|
+
} catch {
|
|
6266
|
+
kit = null;
|
|
6267
|
+
}
|
|
6268
|
+
if (kit) ctx.trackInput(...kit.files, ...kit.dirs);
|
|
6269
|
+
if (options.styles !== void 0) {
|
|
6270
|
+
const entries = mod?.resolveStyleEntries ? mod.resolveStyleEntries(root, options.styles).files : fg4.sync(typeof options.styles === "string" ? [options.styles] : [...options.styles], {
|
|
6271
|
+
cwd: root,
|
|
6272
|
+
absolute: true,
|
|
6273
|
+
onlyFiles: true
|
|
6274
|
+
});
|
|
6275
|
+
const files = mod?.collectStyleSources ? mod.collectStyleSources(entries).map((source2) => source2.file) : entries;
|
|
6276
|
+
ctx.trackInput(.../* @__PURE__ */ new Set([...entries, ...files]));
|
|
6277
|
+
}
|
|
6278
|
+
if (options.stylesDocs !== void 0 && !options.stylesDocs.includes("\n")) {
|
|
6279
|
+
const guide = isAbsolute3(options.stylesDocs) ? options.stylesDocs : resolve6(root, options.stylesDocs);
|
|
6280
|
+
if (existsSync2(guide)) ctx.trackInput(guide);
|
|
6281
|
+
}
|
|
6282
|
+
ctx.trackInput(isAbsolute3(output) ? output : resolve6(root, output));
|
|
6283
|
+
await generate2({
|
|
6284
|
+
root,
|
|
6285
|
+
output,
|
|
6286
|
+
...source,
|
|
6287
|
+
...options.styles !== void 0 ? { styles: options.styles } : {},
|
|
6288
|
+
...options.stylesDocs !== void 0 ? { stylesDocs: options.stylesDocs } : {},
|
|
6289
|
+
...options.tsconfig !== void 0 ? { tsconfig: options.tsconfig } : {}
|
|
6290
|
+
});
|
|
6291
|
+
return [];
|
|
6292
|
+
}
|
|
6293
|
+
};
|
|
6294
|
+
return extension;
|
|
6295
|
+
}
|
|
6296
|
+
|
|
6104
6297
|
// src/index.ts
|
|
6105
|
-
var VERSION = "0.
|
|
6298
|
+
var VERSION = "0.29.0";
|
|
6106
6299
|
export {
|
|
6107
6300
|
CodegenError,
|
|
6108
6301
|
ConfigError,
|
|
6302
|
+
DEFAULT_SANDBOX_KIT_OUTPUT,
|
|
6109
6303
|
DriftGuardError,
|
|
6110
6304
|
VERSION,
|
|
6111
6305
|
acquireLock,
|
|
@@ -6121,6 +6315,7 @@ export {
|
|
|
6121
6315
|
emitRoutes,
|
|
6122
6316
|
extractSchemaFromDto,
|
|
6123
6317
|
generate,
|
|
6318
|
+
genuiSandboxKit,
|
|
6124
6319
|
loadConfig,
|
|
6125
6320
|
renderTsType,
|
|
6126
6321
|
resolveAdapter,
|