@dudousxd/nestjs-codegen 0.12.0 → 0.13.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/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, f as SerializationMode } from './index-CxkGbILp.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-CxkGbILp.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-D8RIMVpU.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-D8RIMVpU.cjs';
3
3
  import { ClassDeclaration, SourceFile, Project } from 'ts-morph';
4
4
 
5
5
  declare function defineConfig(c: UserConfig): UserConfig;
@@ -322,6 +322,6 @@ interface FastDiscoveryOptions {
322
322
  }
323
323
  declare function discoverContractsFast(opts: FastDiscoveryOptions): Promise<RouteDescriptor[]>;
324
324
 
325
- declare const VERSION = "0.12.0";
325
+ declare const VERSION = "0.13.1";
326
326
 
327
327
  export { type ChainModuleRendererOptions, CodegenError, type CodegenManifest, 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 WatchOptions, 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, f as SerializationMode } from './index-CxkGbILp.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-CxkGbILp.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-D8RIMVpU.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-D8RIMVpU.js';
3
3
  import { ClassDeclaration, SourceFile, Project } from 'ts-morph';
4
4
 
5
5
  declare function defineConfig(c: UserConfig): UserConfig;
@@ -322,6 +322,6 @@ interface FastDiscoveryOptions {
322
322
  }
323
323
  declare function discoverContractsFast(opts: FastDiscoveryOptions): Promise<RouteDescriptor[]>;
324
324
 
325
- declare const VERSION = "0.12.0";
325
+ declare const VERSION = "0.13.1";
326
326
 
327
327
  export { type ChainModuleRendererOptions, CodegenError, type CodegenManifest, 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 WatchOptions, 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
@@ -756,7 +756,15 @@ function emitRouterTypeBlock(tree, indent, outDir, serialization) {
756
756
  const isFilterQuery = c.contractSource.filterSource === "query" && !!c.contractSource.filterFields?.length;
757
757
  const query = queryRef ? queryRef.isArray ? `Array<${queryRef.name}>` : queryRef.name : isFilterQuery ? emitFilterQueryType(c) : c.contractSource.query ?? "never";
758
758
  const bodyRef = c.contractSource.bodyRef;
759
- const body = method === "GET" ? "never" : bodyRef ? bodyRef.isArray ? `Array<${bodyRef.name}>` : bodyRef.name : c.contractSource.body ?? "never";
759
+ let body = method === "GET" ? "never" : bodyRef ? bodyRef.isArray ? `Array<${bodyRef.name}>` : bodyRef.name : c.contractSource.body ?? "never";
760
+ const multipartBody = c.contractSource.multipartBody;
761
+ if (c.contractSource.multipart && multipartBody) {
762
+ if (body === "never") {
763
+ body = multipartBody;
764
+ } else if (!bodyAcceptsAnything(body)) {
765
+ body = `(${body}) & ${multipartBody}`;
766
+ }
767
+ }
760
768
  const response = buildResponseType(c, outDir, serialization);
761
769
  const error = buildErrorType(c);
762
770
  const params = buildParamsType(c.params);
@@ -775,6 +783,25 @@ function emitRouterTypeBlock(tree, indent, outDir, serialization) {
775
783
  }
776
784
  return lines;
777
785
  }
786
+ function topLevelUnionArms(type) {
787
+ const arms = [];
788
+ let depth = 0;
789
+ let start = 0;
790
+ for (let i = 0; i < type.length; i++) {
791
+ const ch = type[i];
792
+ if (ch === "{" || ch === "[" || ch === "<" || ch === "(") depth++;
793
+ else if (ch === "}" || ch === "]" || ch === ">" || ch === ")") depth--;
794
+ else if (ch === "|" && depth === 0) {
795
+ arms.push(type.slice(start, i).trim());
796
+ start = i + 1;
797
+ }
798
+ }
799
+ arms.push(type.slice(start).trim());
800
+ return arms;
801
+ }
802
+ function bodyAcceptsAnything(body) {
803
+ return topLevelUnionArms(body).some((arm) => arm === "unknown" || arm === "any");
804
+ }
778
805
  function buildRequestModel(c) {
779
806
  const m = c.method.toLowerCase();
780
807
  const flat = JSON.stringify(c.name);
@@ -791,6 +818,7 @@ function buildRequestModel(c) {
791
818
  const optsParts = [];
792
819
  if (hasQuery) optsParts.push("query: input?.query as Record<string, unknown> | undefined");
793
820
  if (hasBody) optsParts.push("body: input?.body");
821
+ if (hasBody && c.contractSource.multipart) optsParts.push("multipart: true");
794
822
  const optsExpr = optsParts.length ? `{ ${optsParts.join(", ")} }` : "{}";
795
823
  return {
796
824
  routeName: c.name,
@@ -3689,6 +3717,55 @@ function extractParamsType(method, sourceFile, project) {
3689
3717
  }
3690
3718
  return entries.length > 0 ? `{ ${entries.join("; ")} }` : null;
3691
3719
  }
3720
+ function extractUploadedFiles(method) {
3721
+ const FILE = "File | Blob";
3722
+ const entries = [];
3723
+ let multipart = false;
3724
+ const hasUploadedFileParam = method.getParameters().some(
3725
+ (p) => p.getDecorators().some((d) => {
3726
+ const name = d.getName();
3727
+ return name === "UploadedFile" || name === "UploadedFiles";
3728
+ })
3729
+ );
3730
+ for (const decorator of method.getDecorators()) {
3731
+ if (decorator.getName() !== "UseInterceptors") continue;
3732
+ for (const arg of decorator.getArguments()) {
3733
+ if (!Node6.isCallExpression(arg)) continue;
3734
+ const interceptor = arg.getExpression().getText();
3735
+ const callArgs = arg.getArguments();
3736
+ const firstArg2 = callArgs[0];
3737
+ if (interceptor === "FileInterceptor") {
3738
+ if (firstArg2 && Node6.isStringLiteral(firstArg2)) {
3739
+ entries.push(`${firstArg2.getLiteralValue()}: ${FILE}`);
3740
+ multipart = true;
3741
+ }
3742
+ } else if (interceptor === "FilesInterceptor") {
3743
+ if (firstArg2 && Node6.isStringLiteral(firstArg2)) {
3744
+ entries.push(`${firstArg2.getLiteralValue()}: Array<${FILE}>`);
3745
+ multipart = true;
3746
+ }
3747
+ } else if (interceptor === "FileFieldsInterceptor") {
3748
+ if (firstArg2 && Node6.isArrayLiteralExpression(firstArg2)) {
3749
+ for (const el of firstArg2.getElements()) {
3750
+ if (!Node6.isObjectLiteralExpression(el)) continue;
3751
+ const nameProp = el.getProperty("name");
3752
+ if (nameProp && Node6.isPropertyAssignment(nameProp)) {
3753
+ const init = nameProp.getInitializer();
3754
+ if (init && Node6.isStringLiteral(init)) {
3755
+ entries.push(`${init.getLiteralValue()}: Array<${FILE}>`);
3756
+ }
3757
+ }
3758
+ }
3759
+ multipart = true;
3760
+ }
3761
+ } else if (interceptor === "AnyFilesInterceptor") {
3762
+ multipart = true;
3763
+ }
3764
+ }
3765
+ }
3766
+ if (hasUploadedFileParam) multipart = true;
3767
+ return { fields: entries.length > 0 ? entries.join("; ") : null, multipart };
3768
+ }
3692
3769
  function extractResponseType(method, sourceFile, project) {
3693
3770
  const apiResponseDecorator = method.getDecorators().find((d) => d.getName() === "ApiResponse" && (apiResponseStatus(d) ?? 0) < 400);
3694
3771
  if (apiResponseDecorator) {
@@ -3823,6 +3900,8 @@ function extractDtoContract(method, sourceFile, project) {
3823
3900
  let body = extractBodyType(method, sourceFile, project);
3824
3901
  const filterInfo = extractApplyFilterInfo(method, sourceFile, project);
3825
3902
  const query = extractQueryType(method, sourceFile, project);
3903
+ const uploads = extractUploadedFiles(method);
3904
+ const multipartBody = uploads.fields ? `{ ${uploads.fields} }` : null;
3826
3905
  const streamElement = detectStreamElement(method);
3827
3906
  const isStream = streamElement !== null;
3828
3907
  if (filterInfo && filterInfo.source === "body") {
@@ -3832,7 +3911,7 @@ function extractDtoContract(method, sourceFile, project) {
3832
3911
  const paramsType = extractParamsType(method, sourceFile, project);
3833
3912
  const response = isStream ? resolveTypeNodeToString(streamElement, sourceFile, project, 3) : extractResponseType(method, sourceFile, project);
3834
3913
  const errorInfo = extractErrorType(method, sourceFile, project);
3835
- if (body === null && query === null && paramsType === null && response === "unknown" && errorInfo === null && filterInfo === null && !isStream) {
3914
+ if (body === null && query === null && paramsType === null && response === "unknown" && errorInfo === null && filterInfo === null && !isStream && !uploads.multipart) {
3836
3915
  return null;
3837
3916
  }
3838
3917
  let bodyRef = null;
@@ -3905,7 +3984,9 @@ function extractDtoContract(method, sourceFile, project) {
3905
3984
  formWarnings,
3906
3985
  bodySchema,
3907
3986
  querySchema,
3908
- stream: isStream
3987
+ stream: isStream,
3988
+ multipart: uploads.multipart,
3989
+ multipartBody
3909
3990
  };
3910
3991
  }
3911
3992
  function resolveParamClass(method, decoratorName, sourceFile, project) {
@@ -4390,7 +4471,9 @@ function extractDtoRoute(args) {
4390
4471
  formWarnings: dtoContract?.formWarnings ?? [],
4391
4472
  bodySchema: dtoContract?.bodySchema ?? null,
4392
4473
  querySchema: dtoContract?.querySchema ?? null,
4393
- stream: dtoContract?.stream ?? false
4474
+ stream: dtoContract?.stream ?? false,
4475
+ multipart: dtoContract?.multipart ?? false,
4476
+ multipartBody: dtoContract?.multipartBody ?? null
4394
4477
  }
4395
4478
  });
4396
4479
  }
@@ -4703,7 +4786,7 @@ function createChainModuleRenderer(opts) {
4703
4786
  }
4704
4787
 
4705
4788
  // src/index.ts
4706
- var VERSION = "0.12.0";
4789
+ var VERSION = "0.13.1";
4707
4790
  export {
4708
4791
  CodegenError,
4709
4792
  ConfigError,