@dudousxd/nestjs-codegen 0.6.1 → 0.7.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/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { U as UserConfig, R as ResolvedConfig, a as RouteDescriptor, S as SchemaNode, b as RenderContext, c as SchemaModule, d as RenderedModule, e as ResolvedFormsConfig, V as ValidationAdapter, C as CodegenExtension, E as ExtensionContext } from './index-_qRai4M3.cjs';
2
- export { A as AdapterUsage, f as ContractDescriptor, g as ContractSource, h as ControllerRef, N as NumberCheck, i as ScopeConfig, j as StringCheck, T as TypeRef, k as ValidationOption, r as resolveAdapter } from './index-_qRai4M3.cjs';
1
+ import { U as UserConfig, R as ResolvedConfig, a as RouteDescriptor, S as SchemaNode, b as RenderContext, c as SchemaModule, d as RenderedModule, e as ResolvedFormsConfig, V as ValidationAdapter, C as CodegenExtension, E as ExtensionContext, f as SerializationMode } from './index-DgIAN5k5.cjs';
2
+ export { A as AdapterUsage, g as ContractDescriptor, h as ContractSource, i as ControllerRef, N as NumberCheck, j as ScopeConfig, k as StringCheck, T as TypeRef, l as ValidationOption, r as resolveAdapter } from './index-DgIAN5k5.cjs';
3
3
  import { ClassDeclaration, SourceFile, Project } from 'ts-morph';
4
4
 
5
5
  declare function defineConfig(c: UserConfig): UserConfig;
@@ -160,13 +160,20 @@ declare function emitForms(routes: RouteDescriptor[], outDir: string, config: Re
160
160
  * output: an `apiClientLayer` (e.g. `@dudousxd/nestjs-codegen-tanstack`) turns leaves into
161
161
  * handles wrapping the neutral fetcher request; `apiMembers` add handle members; `apiHeader`
162
162
  * contributes top-level imports/statements.
163
+ *
164
+ * `serialization` controls how response types are emitted (default `'json'`):
165
+ * in `'json'` mode each `response` type is wrapped in `Jsonify<...>` (so the
166
+ * generated type reflects the JSON wire shape, e.g. `Date` → `string`); in
167
+ * `'superjson'` mode the raw controller return type is emitted unchanged.
163
168
  */
164
169
  interface ApiEmitOptions {
165
- fetcherImportPath?: string;
170
+ fetcherImportPath?: string | undefined;
166
171
  /** Registered extensions. Their api.ts hooks (transport/layer/members/header) are applied. */
167
- extensions?: CodegenExtension[];
172
+ extensions?: CodegenExtension[] | undefined;
168
173
  /** Shared extension context (from `generate()`). When omitted, a minimal one is built from routes. */
169
- ctx?: ExtensionContext;
174
+ ctx?: ExtensionContext | undefined;
175
+ /** How response payloads deserialize on the client. Default `'json'`. */
176
+ serialization?: SerializationMode | undefined;
170
177
  }
171
178
  declare function emitApi(routes: RouteDescriptor[], outDir: string, opts?: ApiEmitOptions): Promise<void>;
172
179
 
@@ -289,6 +296,6 @@ interface FastDiscoveryOptions {
289
296
  }
290
297
  declare function discoverContractsFast(opts: FastDiscoveryOptions): Promise<RouteDescriptor[]>;
291
298
 
292
- declare const VERSION = "0.6.1";
299
+ declare const VERSION = "0.7.0";
293
300
 
294
301
  export { type ChainModuleRendererOptions, CodegenError, ConfigError, type FastDiscoveryOptions, type JsonSchema, type MocksEmitOptions, type OpenApiDocument, type OpenApiEmitOptions, type OpenApiInfo, RenderContext, RenderedModule, ResolvedConfig, RouteDescriptor, SchemaModule, SchemaNode, type TsTypeContext, UserConfig, VERSION, ValidationAdapter, type Watcher, acquireLock, buildMocksFile, buildOpenApiSpec, createChainModuleRenderer, defineConfig, discoverContractsFast, emitApi, emitForms, emitMocks, emitOpenApi, emitRoutes, extractSchemaFromDto, generate, loadConfig, renderTsType, resolveConfig, schemaModuleToJsonSchema, schemaNodeToJsonSchema, toObjectKey, typeNameFor, watch };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { U as UserConfig, R as ResolvedConfig, a as RouteDescriptor, S as SchemaNode, b as RenderContext, c as SchemaModule, d as RenderedModule, e as ResolvedFormsConfig, V as ValidationAdapter, C as CodegenExtension, E as ExtensionContext } from './index-_qRai4M3.js';
2
- export { A as AdapterUsage, f as ContractDescriptor, g as ContractSource, h as ControllerRef, N as NumberCheck, i as ScopeConfig, j as StringCheck, T as TypeRef, k as ValidationOption, r as resolveAdapter } from './index-_qRai4M3.js';
1
+ import { U as UserConfig, R as ResolvedConfig, a as RouteDescriptor, S as SchemaNode, b as RenderContext, c as SchemaModule, d as RenderedModule, e as ResolvedFormsConfig, V as ValidationAdapter, C as CodegenExtension, E as ExtensionContext, f as SerializationMode } from './index-DgIAN5k5.js';
2
+ export { A as AdapterUsage, g as ContractDescriptor, h as ContractSource, i as ControllerRef, N as NumberCheck, j as ScopeConfig, k as StringCheck, T as TypeRef, l as ValidationOption, r as resolveAdapter } from './index-DgIAN5k5.js';
3
3
  import { ClassDeclaration, SourceFile, Project } from 'ts-morph';
4
4
 
5
5
  declare function defineConfig(c: UserConfig): UserConfig;
@@ -160,13 +160,20 @@ declare function emitForms(routes: RouteDescriptor[], outDir: string, config: Re
160
160
  * output: an `apiClientLayer` (e.g. `@dudousxd/nestjs-codegen-tanstack`) turns leaves into
161
161
  * handles wrapping the neutral fetcher request; `apiMembers` add handle members; `apiHeader`
162
162
  * contributes top-level imports/statements.
163
+ *
164
+ * `serialization` controls how response types are emitted (default `'json'`):
165
+ * in `'json'` mode each `response` type is wrapped in `Jsonify<...>` (so the
166
+ * generated type reflects the JSON wire shape, e.g. `Date` → `string`); in
167
+ * `'superjson'` mode the raw controller return type is emitted unchanged.
163
168
  */
164
169
  interface ApiEmitOptions {
165
- fetcherImportPath?: string;
170
+ fetcherImportPath?: string | undefined;
166
171
  /** Registered extensions. Their api.ts hooks (transport/layer/members/header) are applied. */
167
- extensions?: CodegenExtension[];
172
+ extensions?: CodegenExtension[] | undefined;
168
173
  /** Shared extension context (from `generate()`). When omitted, a minimal one is built from routes. */
169
- ctx?: ExtensionContext;
174
+ ctx?: ExtensionContext | undefined;
175
+ /** How response payloads deserialize on the client. Default `'json'`. */
176
+ serialization?: SerializationMode | undefined;
170
177
  }
171
178
  declare function emitApi(routes: RouteDescriptor[], outDir: string, opts?: ApiEmitOptions): Promise<void>;
172
179
 
@@ -289,6 +296,6 @@ interface FastDiscoveryOptions {
289
296
  }
290
297
  declare function discoverContractsFast(opts: FastDiscoveryOptions): Promise<RouteDescriptor[]>;
291
298
 
292
- declare const VERSION = "0.6.1";
299
+ declare const VERSION = "0.7.0";
293
300
 
294
301
  export { type ChainModuleRendererOptions, CodegenError, ConfigError, type FastDiscoveryOptions, type JsonSchema, type MocksEmitOptions, type OpenApiDocument, type OpenApiEmitOptions, type OpenApiInfo, RenderContext, RenderedModule, ResolvedConfig, RouteDescriptor, SchemaModule, SchemaNode, type TsTypeContext, UserConfig, VERSION, ValidationAdapter, type Watcher, acquireLock, buildMocksFile, buildOpenApiSpec, createChainModuleRenderer, defineConfig, discoverContractsFast, emitApi, emitForms, emitMocks, emitOpenApi, emitRoutes, extractSchemaFromDto, generate, loadConfig, renderTsType, resolveConfig, schemaModuleToJsonSchema, schemaNodeToJsonSchema, toObjectKey, typeNameFor, watch };
package/dist/index.js CHANGED
@@ -127,6 +127,7 @@ function applyDefaults(userConfig, cwd) {
127
127
  },
128
128
  app,
129
129
  fetcher: userConfig.fetcher ?? null,
130
+ serialization: userConfig.serialization ?? "json",
130
131
  forms: {
131
132
  enabled: userConfig.forms?.enabled ?? true,
132
133
  watch: userConfig.forms?.watch ?? "src/**/*.dto.ts",
@@ -710,7 +711,11 @@ function emitFilterQueryTypeArgs(c) {
710
711
  function emitFilterQueryType(c) {
711
712
  return `import('@dudousxd/nestjs-filter-client').TypedFilterQuery<${emitFilterQueryTypeArgs(c)}>`;
712
713
  }
713
- function buildResponseType(c, outDir) {
714
+ function buildResponseType(c, outDir, serialization) {
715
+ const raw = rawResponseType(c, outDir);
716
+ return serialization === "json" ? `Jsonify<${raw}>` : raw;
717
+ }
718
+ function rawResponseType(c, outDir) {
714
719
  const respRef = c.contractSource.responseRef;
715
720
  if (c.contractSource.stream) {
716
721
  if (respRef) return respRef.isArray ? `Array<${respRef.name}>` : respRef.name;
@@ -733,7 +738,7 @@ function buildErrorType(c) {
733
738
  }
734
739
  return c.contractSource.error ?? "unknown";
735
740
  }
736
- function emitRouterTypeBlock(tree, indent, outDir) {
741
+ function emitRouterTypeBlock(tree, indent, outDir, serialization) {
737
742
  const pad = " ".repeat(indent);
738
743
  const lines = [];
739
744
  for (const [key, node] of tree) {
@@ -746,7 +751,7 @@ function emitRouterTypeBlock(tree, indent, outDir) {
746
751
  const query = queryRef ? queryRef.isArray ? `Array<${queryRef.name}>` : queryRef.name : isFilterQuery ? emitFilterQueryType(c) : c.contractSource.query ?? "never";
747
752
  const bodyRef = c.contractSource.bodyRef;
748
753
  const body = method === "GET" ? "never" : bodyRef ? bodyRef.isArray ? `Array<${bodyRef.name}>` : bodyRef.name : c.contractSource.body ?? "never";
749
- const response = buildResponseType(c, outDir);
754
+ const response = buildResponseType(c, outDir, serialization);
750
755
  const error = buildErrorType(c);
751
756
  const params = buildParamsType(c.params);
752
757
  const safeMethod = JSON.stringify(method);
@@ -758,7 +763,7 @@ function emitRouterTypeBlock(tree, indent, outDir) {
758
763
  );
759
764
  } else {
760
765
  lines.push(`${pad}${objKey}: {`);
761
- lines.push(...emitRouterTypeBlock(node.children, indent + 2, outDir));
766
+ lines.push(...emitRouterTypeBlock(node.children, indent + 2, outDir, serialization));
762
767
  lines.push(`${pad}};`);
763
768
  }
764
769
  }
@@ -963,6 +968,7 @@ var EMPTY_PATH_NAMESPACE = [
963
968
  ];
964
969
  function buildApiFile(routes, outDir, opts = {}) {
965
970
  const fetcherImportPath = opts.fetcherImportPath;
971
+ const serialization = opts.serialization ?? "json";
966
972
  const extensions = opts.extensions ?? [];
967
973
  const { layer } = resolveApiSlots(extensions);
968
974
  const memberExts = extensions.filter((e) => e.apiMembers);
@@ -1019,6 +1025,9 @@ function buildApiFile(routes, outDir, opts = {}) {
1019
1025
  );
1020
1026
  const runtimeImport = fetcherImportPath ?? "@dudousxd/nestjs-client";
1021
1027
  lines.push(`import type { Fetcher } from '${runtimeImport}';`);
1028
+ if (serialization === "json" && contracted.length > 0) {
1029
+ lines.push(`import type { Jsonify } from '${runtimeImport}';`);
1030
+ }
1022
1031
  if (importsByFile.size > 0 && outDir) {
1023
1032
  lines.push("");
1024
1033
  const emittedNames = /* @__PURE__ */ new Set();
@@ -1078,7 +1087,7 @@ function buildApiFile(routes, outDir, opts = {}) {
1078
1087
  insertIntoTree(tree, segments, leaf, name);
1079
1088
  }
1080
1089
  lines.push("export type ApiRouter = {");
1081
- lines.push(...emitRouterTypeBlock(tree, 2, outDir ?? ""));
1090
+ lines.push(...emitRouterTypeBlock(tree, 2, outDir ?? "", serialization));
1082
1091
  lines.push("};");
1083
1092
  lines.push("");
1084
1093
  lines.push(...emitReqHelper());
@@ -2099,6 +2108,7 @@ async function generate(config, inputRoutes = []) {
2099
2108
  if (hasContracts) {
2100
2109
  await emitApi(routes, config.codegen.outDir, {
2101
2110
  ...config.fetcher?.importPath ? { fetcherImportPath: config.fetcher.importPath } : {},
2111
+ serialization: config.serialization,
2102
2112
  extensions,
2103
2113
  ctx
2104
2114
  });
@@ -4538,7 +4548,7 @@ function createChainModuleRenderer(opts) {
4538
4548
  }
4539
4549
 
4540
4550
  // src/index.ts
4541
- var VERSION = "0.6.1";
4551
+ var VERSION = "0.7.0";
4542
4552
  export {
4543
4553
  CodegenError,
4544
4554
  ConfigError,