@dudousxd/nestjs-codegen 0.27.1 → 0.28.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 +14 -0
- package/README.md +23 -0
- package/dist/cli/main.cjs +64 -17
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +65 -18
- package/dist/cli/main.js.map +1 -1
- package/dist/index.cjs +163 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +56 -3
- package/dist/index.d.ts +56 -3
- package/dist/index.js +162 -12
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +58 -11
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.js +59 -12
- package/dist/nest/index.js.map +1 -1
- package/package.json +6 -2
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,54 @@ 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
|
+
entry?: string;
|
|
382
|
+
include?: string | readonly string[];
|
|
383
|
+
css?: string | readonly string[];
|
|
384
|
+
tsconfig?: string;
|
|
385
|
+
}
|
|
386
|
+
interface GenuiSandboxKitOptions {
|
|
387
|
+
/** A module whose exports are the kit (e.g. `src/genui/kit.ts`). */
|
|
388
|
+
entry?: string;
|
|
389
|
+
/** A glob (or several) whose files' exports are the kit (e.g. `web/components/ui/*.tsx`). */
|
|
390
|
+
include?: string | readonly string[];
|
|
391
|
+
/** Stylesheet glob(s) whose custom properties become the sandbox theme. */
|
|
392
|
+
css?: string | readonly string[];
|
|
393
|
+
/** The tsconfig the component prop types are read through. */
|
|
394
|
+
tsconfig?: string;
|
|
395
|
+
/**
|
|
396
|
+
* Where the descriptor is written, relative to the app `cwd` (or absolute).
|
|
397
|
+
* @default '.genui/sandbox-kit.json'
|
|
398
|
+
*/
|
|
399
|
+
output?: string;
|
|
400
|
+
/**
|
|
401
|
+
* The docs writer. Defaults to `writeSandboxKitDocs` from
|
|
402
|
+
* `@dudousxd/nestjs-agent-core/genui/kit`; inject one to test, or to use another generator.
|
|
403
|
+
* It is expected to write `output` itself (and only when the contents change).
|
|
404
|
+
*/
|
|
405
|
+
generate?: (options: WriteSandboxKitDocsOptions) => Promise<unknown>;
|
|
406
|
+
/** The module the writer is loaded from. Default `@dudousxd/nestjs-agent-core/genui/kit`. */
|
|
407
|
+
kitModule?: string;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Writes the generative-UI **sandbox kit docs** — the app's design-system components (shadcn
|
|
411
|
+
* `components/ui` by default) with the props read from their TypeScript types — to
|
|
412
|
+
* `.genui/sandbox-kit.json`, where the `@dudousxd/nestjs-agent` server reads them.
|
|
413
|
+
*
|
|
414
|
+
* Runs on every generate pass (one-shot CLI, `--watch`, and the Nest module's watcher). The
|
|
415
|
+
* descriptor lives outside `outDir`, so it is written by the generator itself, not through
|
|
416
|
+
* `emitFiles`; the kit files, stylesheets and the descriptor are tracked as inputs, so editing
|
|
417
|
+
* a component regenerates in watch mode and a deleted descriptor is rewritten.
|
|
418
|
+
*
|
|
419
|
+
* Needs the optional peer `@dudousxd/nestjs-agent-core` (>=0.52.0) unless `generate` is given.
|
|
420
|
+
*/
|
|
421
|
+
declare function genuiSandboxKit(options?: GenuiSandboxKitOptions): CodegenExtension;
|
|
422
|
+
|
|
370
423
|
/**
|
|
371
424
|
* Static AST-based contract discovery using ts-morph.
|
|
372
425
|
* Cold start ~100-500 ms.
|
|
@@ -382,6 +435,6 @@ interface FastDiscoveryOptions {
|
|
|
382
435
|
}
|
|
383
436
|
declare function discoverContractsFast(opts: FastDiscoveryOptions): Promise<RouteDescriptor[]>;
|
|
384
437
|
|
|
385
|
-
declare const VERSION = "0.
|
|
438
|
+
declare const VERSION = "0.28.0";
|
|
386
439
|
|
|
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 };
|
|
440
|
+
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,54 @@ 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
|
+
entry?: string;
|
|
382
|
+
include?: string | readonly string[];
|
|
383
|
+
css?: string | readonly string[];
|
|
384
|
+
tsconfig?: string;
|
|
385
|
+
}
|
|
386
|
+
interface GenuiSandboxKitOptions {
|
|
387
|
+
/** A module whose exports are the kit (e.g. `src/genui/kit.ts`). */
|
|
388
|
+
entry?: string;
|
|
389
|
+
/** A glob (or several) whose files' exports are the kit (e.g. `web/components/ui/*.tsx`). */
|
|
390
|
+
include?: string | readonly string[];
|
|
391
|
+
/** Stylesheet glob(s) whose custom properties become the sandbox theme. */
|
|
392
|
+
css?: string | readonly string[];
|
|
393
|
+
/** The tsconfig the component prop types are read through. */
|
|
394
|
+
tsconfig?: string;
|
|
395
|
+
/**
|
|
396
|
+
* Where the descriptor is written, relative to the app `cwd` (or absolute).
|
|
397
|
+
* @default '.genui/sandbox-kit.json'
|
|
398
|
+
*/
|
|
399
|
+
output?: string;
|
|
400
|
+
/**
|
|
401
|
+
* The docs writer. Defaults to `writeSandboxKitDocs` from
|
|
402
|
+
* `@dudousxd/nestjs-agent-core/genui/kit`; inject one to test, or to use another generator.
|
|
403
|
+
* It is expected to write `output` itself (and only when the contents change).
|
|
404
|
+
*/
|
|
405
|
+
generate?: (options: WriteSandboxKitDocsOptions) => Promise<unknown>;
|
|
406
|
+
/** The module the writer is loaded from. Default `@dudousxd/nestjs-agent-core/genui/kit`. */
|
|
407
|
+
kitModule?: string;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Writes the generative-UI **sandbox kit docs** — the app's design-system components (shadcn
|
|
411
|
+
* `components/ui` by default) with the props read from their TypeScript types — to
|
|
412
|
+
* `.genui/sandbox-kit.json`, where the `@dudousxd/nestjs-agent` server reads them.
|
|
413
|
+
*
|
|
414
|
+
* Runs on every generate pass (one-shot CLI, `--watch`, and the Nest module's watcher). The
|
|
415
|
+
* descriptor lives outside `outDir`, so it is written by the generator itself, not through
|
|
416
|
+
* `emitFiles`; the kit files, stylesheets and the descriptor are tracked as inputs, so editing
|
|
417
|
+
* a component regenerates in watch mode and a deleted descriptor is rewritten.
|
|
418
|
+
*
|
|
419
|
+
* Needs the optional peer `@dudousxd/nestjs-agent-core` (>=0.52.0) unless `generate` is given.
|
|
420
|
+
*/
|
|
421
|
+
declare function genuiSandboxKit(options?: GenuiSandboxKitOptions): CodegenExtension;
|
|
422
|
+
|
|
370
423
|
/**
|
|
371
424
|
* Static AST-based contract discovery using ts-morph.
|
|
372
425
|
* Cold start ~100-500 ms.
|
|
@@ -382,6 +435,6 @@ interface FastDiscoveryOptions {
|
|
|
382
435
|
}
|
|
383
436
|
declare function discoverContractsFast(opts: FastDiscoveryOptions): Promise<RouteDescriptor[]>;
|
|
384
437
|
|
|
385
|
-
declare const VERSION = "0.
|
|
438
|
+
declare const VERSION = "0.28.0";
|
|
386
439
|
|
|
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 };
|
|
440
|
+
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
|
@@ -690,12 +690,18 @@ function findTypeInFile(name, file) {
|
|
|
690
690
|
function resolveModuleSpecifier(moduleSpecifier, sourceFile, project) {
|
|
691
691
|
if (moduleSpecifier.startsWith(".")) {
|
|
692
692
|
const dir = dirname(sourceFile.getFilePath());
|
|
693
|
-
const
|
|
694
|
-
|
|
695
|
-
|
|
693
|
+
const ext = /\.(c|m)?(j|t)sx?$/.exec(moduleSpecifier)?.[0];
|
|
694
|
+
const base = ext ? moduleSpecifier.slice(0, -ext.length) : moduleSpecifier;
|
|
695
|
+
const flavour = ext?.startsWith(".c") ? "c" : ext?.startsWith(".m") ? "m" : "";
|
|
696
|
+
const candidates = [
|
|
697
|
+
resolve2(dir, `${base}.${flavour}ts`),
|
|
698
|
+
...flavour === "" ? [resolve2(dir, `${base}.tsx`)] : [],
|
|
696
699
|
resolve2(dir, `${moduleSpecifier}.ts`),
|
|
697
|
-
resolve2(dir, moduleSpecifier, "index.ts")
|
|
700
|
+
resolve2(dir, moduleSpecifier, "index.ts"),
|
|
701
|
+
resolve2(dir, `${base}.d.${flavour}ts`),
|
|
702
|
+
...ext === void 0 ? [resolve2(dir, moduleSpecifier, "index.d.ts")] : []
|
|
698
703
|
];
|
|
704
|
+
return [...new Set(candidates)];
|
|
699
705
|
}
|
|
700
706
|
const ctx = _ctxFor(project);
|
|
701
707
|
const baseUrl = ctx.pathsBase ?? ctx.projectRoot;
|
|
@@ -5649,14 +5655,26 @@ async function computeInputsHash(config, extraInputs = []) {
|
|
|
5649
5655
|
hash.update("\n");
|
|
5650
5656
|
}
|
|
5651
5657
|
for (const file of extra) {
|
|
5652
|
-
const contents = await readFile2(join13(cwd, file), "utf8").catch(() => null);
|
|
5653
5658
|
hash.update(`extra:${file}
|
|
5654
5659
|
`);
|
|
5655
|
-
hash.update(
|
|
5660
|
+
hash.update(await readTrackedInput(join13(cwd, file)));
|
|
5656
5661
|
hash.update("\n");
|
|
5657
5662
|
}
|
|
5658
5663
|
return hash.digest("hex");
|
|
5659
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
|
+
}
|
|
5660
5678
|
async function readManifest(outDir) {
|
|
5661
5679
|
try {
|
|
5662
5680
|
const raw = await readFile2(join13(outDir, MANIFEST_FILE), "utf8");
|
|
@@ -5812,7 +5830,7 @@ async function generate(config, inputRoutes = [], entryPoint = "cli") {
|
|
|
5812
5830
|
|
|
5813
5831
|
// src/watch/watcher.ts
|
|
5814
5832
|
import { readFile as readFile4 } from "fs/promises";
|
|
5815
|
-
import { join as join16 } from "path";
|
|
5833
|
+
import { join as join16, resolve as resolve5 } from "path";
|
|
5816
5834
|
import chokidar from "chokidar";
|
|
5817
5835
|
|
|
5818
5836
|
// src/watch/lock-file.ts
|
|
@@ -5894,11 +5912,36 @@ async function watch(config, onChange, options = {}) {
|
|
|
5894
5912
|
}
|
|
5895
5913
|
return discovery;
|
|
5896
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
|
+
}
|
|
5897
5940
|
async function runInitialPass() {
|
|
5898
5941
|
try {
|
|
5899
5942
|
const initialRoutes = (await getDiscovery()).discover();
|
|
5900
5943
|
lastRoutes = initialRoutes;
|
|
5901
|
-
await
|
|
5944
|
+
await generateAndTrack(initialRoutes);
|
|
5902
5945
|
} catch (err) {
|
|
5903
5946
|
if (err instanceof DriftGuardError) {
|
|
5904
5947
|
console.error(err.message);
|
|
@@ -5908,7 +5951,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
5908
5951
|
`[nestjs-codegen] Initial route discovery failed, falling back to pages-only: ${err instanceof Error ? err.message : String(err)}`
|
|
5909
5952
|
);
|
|
5910
5953
|
try {
|
|
5911
|
-
await
|
|
5954
|
+
await generateAndTrack(lastRoutes);
|
|
5912
5955
|
} catch {
|
|
5913
5956
|
}
|
|
5914
5957
|
}
|
|
@@ -5941,7 +5984,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
5941
5984
|
pagesDebounceTimer = setTimeout(async () => {
|
|
5942
5985
|
pagesDebounceTimer = void 0;
|
|
5943
5986
|
try {
|
|
5944
|
-
await
|
|
5987
|
+
await generateAndTrack(lastRoutes);
|
|
5945
5988
|
} catch (err) {
|
|
5946
5989
|
console.error(
|
|
5947
5990
|
"[nestjs-codegen] Pages generation failed:",
|
|
@@ -5973,7 +6016,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
5973
6016
|
try {
|
|
5974
6017
|
const routes = await (await getDiscovery()).rediscover(changed);
|
|
5975
6018
|
lastRoutes = routes;
|
|
5976
|
-
await
|
|
6019
|
+
await generateAndTrack(routes);
|
|
5977
6020
|
} catch (err) {
|
|
5978
6021
|
console.error(
|
|
5979
6022
|
"[nestjs-codegen] Contracts generation failed:",
|
|
@@ -5994,6 +6037,9 @@ async function watch(config, onChange, options = {}) {
|
|
|
5994
6037
|
formsWatcher.on("add", (p) => scheduleContractsRegenerate(p));
|
|
5995
6038
|
formsWatcher.on("change", (p) => scheduleContractsRegenerate(p));
|
|
5996
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));
|
|
5997
6043
|
return {
|
|
5998
6044
|
close: async () => {
|
|
5999
6045
|
if (pagesDebounceTimer !== void 0) {
|
|
@@ -6007,6 +6053,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
6007
6053
|
await pagesWatcher.close();
|
|
6008
6054
|
await contractsWatcher.close();
|
|
6009
6055
|
await formsWatcher.close();
|
|
6056
|
+
await trackedWatcher.close();
|
|
6010
6057
|
await lock.release();
|
|
6011
6058
|
}
|
|
6012
6059
|
};
|
|
@@ -6095,11 +6142,113 @@ function createChainModuleRenderer(opts) {
|
|
|
6095
6142
|
};
|
|
6096
6143
|
}
|
|
6097
6144
|
|
|
6145
|
+
// src/extension/genui-sandbox-kit.ts
|
|
6146
|
+
import { existsSync as existsSync2 } 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
|
+
async function loadKitModule(specifier = GENUI_KIT_MODULE) {
|
|
6159
|
+
let mod;
|
|
6160
|
+
try {
|
|
6161
|
+
mod = await import(specifier);
|
|
6162
|
+
} catch (err) {
|
|
6163
|
+
const code = err.code;
|
|
6164
|
+
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") {
|
|
6165
|
+
throw new CodegenError(
|
|
6166
|
+
`genuiSandboxKit() needs "${GENUI_KIT_MODULE}" \u2014 install @dudousxd/nestjs-agent-core@>=0.52.0, or pass \`generate\` to genuiSandboxKit().`
|
|
6167
|
+
);
|
|
6168
|
+
}
|
|
6169
|
+
if (code === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
|
|
6170
|
+
throw new CodegenError(
|
|
6171
|
+
`genuiSandboxKit() needs "${GENUI_KIT_MODULE}", which the installed @dudousxd/nestjs-agent-core does not export \u2014 upgrade it to >=0.52.0.`
|
|
6172
|
+
);
|
|
6173
|
+
}
|
|
6174
|
+
throw err;
|
|
6175
|
+
}
|
|
6176
|
+
if (typeof mod.writeSandboxKitDocs !== "function") {
|
|
6177
|
+
throw new CodegenError(
|
|
6178
|
+
`"${GENUI_KIT_MODULE}" has no writeSandboxKitDocs export \u2014 upgrade @dudousxd/nestjs-agent-core to >=0.52.0.`
|
|
6179
|
+
);
|
|
6180
|
+
}
|
|
6181
|
+
return mod;
|
|
6182
|
+
}
|
|
6183
|
+
function globBase(glob) {
|
|
6184
|
+
const base = [];
|
|
6185
|
+
for (const part of glob.replace(/\\/g, "/").split("/")) {
|
|
6186
|
+
if (/[*?{[]/.test(part)) break;
|
|
6187
|
+
base.push(part);
|
|
6188
|
+
}
|
|
6189
|
+
return base.join("/");
|
|
6190
|
+
}
|
|
6191
|
+
function resolveKitFilesLocally(root, options) {
|
|
6192
|
+
if (options.entry !== void 0) {
|
|
6193
|
+
const entry = isAbsolute3(options.entry) ? options.entry : resolve6(root, options.entry);
|
|
6194
|
+
return { entry, files: [entry], dirs: [dirname5(entry)] };
|
|
6195
|
+
}
|
|
6196
|
+
const include = options.include ?? DEFAULT_KIT_DIRS.filter((dir) => existsSync2(resolve6(root, dir))).map(
|
|
6197
|
+
(dir) => `${dir}/*.{tsx,jsx,ts,js}`
|
|
6198
|
+
)[0];
|
|
6199
|
+
if (include === void 0) return null;
|
|
6200
|
+
const globs = typeof include === "string" ? [include] : [...include];
|
|
6201
|
+
const files = fg4.sync(globs, { cwd: root, absolute: true, onlyFiles: true }).sort();
|
|
6202
|
+
return { files, dirs: [...new Set(globs.map((glob) => resolve6(root, globBase(glob))))] };
|
|
6203
|
+
}
|
|
6204
|
+
function genuiSandboxKit(options = {}) {
|
|
6205
|
+
const output = options.output ?? DEFAULT_SANDBOX_KIT_OUTPUT;
|
|
6206
|
+
const source = {
|
|
6207
|
+
...options.entry !== void 0 ? { entry: options.entry } : {},
|
|
6208
|
+
...options.include !== void 0 ? { include: options.include } : {}
|
|
6209
|
+
};
|
|
6210
|
+
const extension = {
|
|
6211
|
+
name: "genui-sandbox-kit",
|
|
6212
|
+
// Not read by the host: serialized into the config hash, so changing an option
|
|
6213
|
+
// invalidates skip-when-unchanged.
|
|
6214
|
+
options: { ...source, css: options.css, tsconfig: options.tsconfig, output },
|
|
6215
|
+
async emitFiles(ctx) {
|
|
6216
|
+
const root = ctx.cwd;
|
|
6217
|
+
let generate2 = options.generate;
|
|
6218
|
+
let resolveFiles = resolveKitFilesLocally;
|
|
6219
|
+
if (!generate2) {
|
|
6220
|
+
const mod = await loadKitModule(options.kitModule);
|
|
6221
|
+
generate2 = mod.writeSandboxKitDocs;
|
|
6222
|
+
if (typeof mod.resolveSandboxKitFiles === "function") {
|
|
6223
|
+
resolveFiles = mod.resolveSandboxKitFiles;
|
|
6224
|
+
}
|
|
6225
|
+
}
|
|
6226
|
+
const kit = resolveFiles(root, source);
|
|
6227
|
+
if (kit) ctx.trackInput(...kit.files, ...kit.dirs);
|
|
6228
|
+
if (options.css !== void 0) {
|
|
6229
|
+
const css = typeof options.css === "string" ? [options.css] : [...options.css];
|
|
6230
|
+
ctx.trackInput(...fg4.sync(css, { cwd: root, absolute: true, onlyFiles: true }));
|
|
6231
|
+
}
|
|
6232
|
+
ctx.trackInput(isAbsolute3(output) ? output : resolve6(root, output));
|
|
6233
|
+
await generate2({
|
|
6234
|
+
root,
|
|
6235
|
+
output,
|
|
6236
|
+
...source,
|
|
6237
|
+
...options.css !== void 0 ? { css: options.css } : {},
|
|
6238
|
+
...options.tsconfig !== void 0 ? { tsconfig: options.tsconfig } : {}
|
|
6239
|
+
});
|
|
6240
|
+
return [];
|
|
6241
|
+
}
|
|
6242
|
+
};
|
|
6243
|
+
return extension;
|
|
6244
|
+
}
|
|
6245
|
+
|
|
6098
6246
|
// src/index.ts
|
|
6099
|
-
var VERSION = "0.
|
|
6247
|
+
var VERSION = "0.28.0";
|
|
6100
6248
|
export {
|
|
6101
6249
|
CodegenError,
|
|
6102
6250
|
ConfigError,
|
|
6251
|
+
DEFAULT_SANDBOX_KIT_OUTPUT,
|
|
6103
6252
|
DriftGuardError,
|
|
6104
6253
|
VERSION,
|
|
6105
6254
|
acquireLock,
|
|
@@ -6115,6 +6264,7 @@ export {
|
|
|
6115
6264
|
emitRoutes,
|
|
6116
6265
|
extractSchemaFromDto,
|
|
6117
6266
|
generate,
|
|
6267
|
+
genuiSandboxKit,
|
|
6118
6268
|
loadConfig,
|
|
6119
6269
|
renderTsType,
|
|
6120
6270
|
resolveAdapter,
|