@dudousxd/nestjs-codegen 0.12.0 → 0.13.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/cli/main.js CHANGED
@@ -786,6 +786,7 @@ function buildRequestModel(c) {
786
786
  const optsParts = [];
787
787
  if (hasQuery) optsParts.push("query: input?.query as Record<string, unknown> | undefined");
788
788
  if (hasBody) optsParts.push("body: input?.body");
789
+ if (hasBody && c.contractSource.multipart) optsParts.push("multipart: true");
789
790
  const optsExpr = optsParts.length ? `{ ${optsParts.join(", ")} }` : "{}";
790
791
  return {
791
792
  routeName: c.name,
@@ -3681,6 +3682,55 @@ function extractParamsType(method, sourceFile, project) {
3681
3682
  }
3682
3683
  return entries.length > 0 ? `{ ${entries.join("; ")} }` : null;
3683
3684
  }
3685
+ function extractUploadedFiles(method) {
3686
+ const FILE = "File | Blob";
3687
+ const entries = [];
3688
+ let multipart = false;
3689
+ const hasUploadedFileParam = method.getParameters().some(
3690
+ (p) => p.getDecorators().some((d) => {
3691
+ const name = d.getName();
3692
+ return name === "UploadedFile" || name === "UploadedFiles";
3693
+ })
3694
+ );
3695
+ for (const decorator of method.getDecorators()) {
3696
+ if (decorator.getName() !== "UseInterceptors") continue;
3697
+ for (const arg of decorator.getArguments()) {
3698
+ if (!Node6.isCallExpression(arg)) continue;
3699
+ const interceptor = arg.getExpression().getText();
3700
+ const callArgs = arg.getArguments();
3701
+ const firstArg2 = callArgs[0];
3702
+ if (interceptor === "FileInterceptor") {
3703
+ if (firstArg2 && Node6.isStringLiteral(firstArg2)) {
3704
+ entries.push(`${firstArg2.getLiteralValue()}: ${FILE}`);
3705
+ multipart = true;
3706
+ }
3707
+ } else if (interceptor === "FilesInterceptor") {
3708
+ if (firstArg2 && Node6.isStringLiteral(firstArg2)) {
3709
+ entries.push(`${firstArg2.getLiteralValue()}: Array<${FILE}>`);
3710
+ multipart = true;
3711
+ }
3712
+ } else if (interceptor === "FileFieldsInterceptor") {
3713
+ if (firstArg2 && Node6.isArrayLiteralExpression(firstArg2)) {
3714
+ for (const el of firstArg2.getElements()) {
3715
+ if (!Node6.isObjectLiteralExpression(el)) continue;
3716
+ const nameProp = el.getProperty("name");
3717
+ if (nameProp && Node6.isPropertyAssignment(nameProp)) {
3718
+ const init = nameProp.getInitializer();
3719
+ if (init && Node6.isStringLiteral(init)) {
3720
+ entries.push(`${init.getLiteralValue()}: Array<${FILE}>`);
3721
+ }
3722
+ }
3723
+ }
3724
+ multipart = true;
3725
+ }
3726
+ } else if (interceptor === "AnyFilesInterceptor") {
3727
+ multipart = true;
3728
+ }
3729
+ }
3730
+ }
3731
+ if (hasUploadedFileParam) multipart = true;
3732
+ return { fields: entries.length > 0 ? entries.join("; ") : null, multipart };
3733
+ }
3684
3734
  function extractResponseType(method, sourceFile, project) {
3685
3735
  const apiResponseDecorator = method.getDecorators().find((d) => d.getName() === "ApiResponse" && (apiResponseStatus(d) ?? 0) < 400);
3686
3736
  if (apiResponseDecorator) {
@@ -3815,6 +3865,11 @@ function extractDtoContract(method, sourceFile, project) {
3815
3865
  let body = extractBodyType(method, sourceFile, project);
3816
3866
  const filterInfo = extractApplyFilterInfo(method, sourceFile, project);
3817
3867
  const query = extractQueryType(method, sourceFile, project);
3868
+ const uploads = extractUploadedFiles(method);
3869
+ if (uploads.fields) {
3870
+ const fileObject = `{ ${uploads.fields} }`;
3871
+ body = body ? `(${body}) & ${fileObject}` : fileObject;
3872
+ }
3818
3873
  const streamElement = detectStreamElement(method);
3819
3874
  const isStream = streamElement !== null;
3820
3875
  if (filterInfo && filterInfo.source === "body") {
@@ -3824,7 +3879,7 @@ function extractDtoContract(method, sourceFile, project) {
3824
3879
  const paramsType = extractParamsType(method, sourceFile, project);
3825
3880
  const response = isStream ? resolveTypeNodeToString(streamElement, sourceFile, project, 3) : extractResponseType(method, sourceFile, project);
3826
3881
  const errorInfo = extractErrorType(method, sourceFile, project);
3827
- if (body === null && query === null && paramsType === null && response === "unknown" && errorInfo === null && filterInfo === null && !isStream) {
3882
+ if (body === null && query === null && paramsType === null && response === "unknown" && errorInfo === null && filterInfo === null && !isStream && !uploads.multipart) {
3828
3883
  return null;
3829
3884
  }
3830
3885
  let bodyRef = null;
@@ -3897,7 +3952,8 @@ function extractDtoContract(method, sourceFile, project) {
3897
3952
  formWarnings,
3898
3953
  bodySchema,
3899
3954
  querySchema,
3900
- stream: isStream
3955
+ stream: isStream,
3956
+ multipart: uploads.multipart
3901
3957
  };
3902
3958
  }
3903
3959
  function resolveParamClass(method, decoratorName, sourceFile, project) {
@@ -4382,7 +4438,8 @@ function extractDtoRoute(args) {
4382
4438
  formWarnings: dtoContract?.formWarnings ?? [],
4383
4439
  bodySchema: dtoContract?.bodySchema ?? null,
4384
4440
  querySchema: dtoContract?.querySchema ?? null,
4385
- stream: dtoContract?.stream ?? false
4441
+ stream: dtoContract?.stream ?? false,
4442
+ multipart: dtoContract?.multipart ?? false
4386
4443
  }
4387
4444
  });
4388
4445
  }
@@ -4612,7 +4669,7 @@ async function watch(config, onChange, options = {}) {
4612
4669
  }
4613
4670
 
4614
4671
  // src/index.ts
4615
- var VERSION = "0.12.0";
4672
+ var VERSION = "0.13.0";
4616
4673
 
4617
4674
  // src/cli/codegen.ts
4618
4675
  async function runCodegen(opts = {}) {