@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/CHANGELOG.md +31 -0
- package/dist/cli/main.cjs +61 -4
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +61 -4
- package/dist/cli/main.js.map +1 -1
- package/dist/extension/index.d.cts +1 -1
- package/dist/extension/index.d.ts +1 -1
- package/dist/{index-CxkGbILp.d.cts → index-DvUzPXdh.d.cts} +7 -0
- package/dist/{index-CxkGbILp.d.ts → index-DvUzPXdh.d.ts} +7 -0
- package/dist/index.cjs +61 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +61 -4
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +61 -4
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.d.cts +1 -1
- package/dist/nest/index.d.ts +1 -1
- package/dist/nest/index.js +61 -4
- package/dist/nest/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { m as ApiClientLayer, n as ApiHeaderContribution, o as ApiModuleDeps, C as CodegenExtension, p as EmittedFile, E as ExtensionContext, L as LeafModel, q as RequestModel, s as RequestShape, t as defineExtension, u as requestShape } from '../index-
|
|
1
|
+
export { m as ApiClientLayer, n as ApiHeaderContribution, o as ApiModuleDeps, C as CodegenExtension, p as EmittedFile, E as ExtensionContext, L as LeafModel, q as RequestModel, s as RequestShape, t as defineExtension, u as requestShape } from '../index-DvUzPXdh.cjs';
|
|
2
2
|
import 'ts-morph';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { m as ApiClientLayer, n as ApiHeaderContribution, o as ApiModuleDeps, C as CodegenExtension, p as EmittedFile, E as ExtensionContext, L as LeafModel, q as RequestModel, s as RequestShape, t as defineExtension, u as requestShape } from '../index-
|
|
1
|
+
export { m as ApiClientLayer, n as ApiHeaderContribution, o as ApiModuleDeps, C as CodegenExtension, p as EmittedFile, E as ExtensionContext, L as LeafModel, q as RequestModel, s as RequestShape, t as defineExtension, u as requestShape } from '../index-DvUzPXdh.js';
|
|
2
2
|
import 'ts-morph';
|
|
@@ -489,6 +489,13 @@ interface ContractSource {
|
|
|
489
489
|
* `AsyncIterable<T>` stream rather than a single awaited value.
|
|
490
490
|
*/
|
|
491
491
|
stream?: boolean;
|
|
492
|
+
/**
|
|
493
|
+
* True when the route consumes `multipart/form-data` — its handler takes an
|
|
494
|
+
* `@UploadedFile()` / `@UploadedFiles()` (via a Multer interceptor). The
|
|
495
|
+
* uploaded-file field(s) are merged into `body` as `File | Blob`, and the
|
|
496
|
+
* generated client serializes the body to a `FormData` instead of JSON.
|
|
497
|
+
*/
|
|
498
|
+
multipart?: boolean;
|
|
492
499
|
}
|
|
493
500
|
interface ContractDescriptor {
|
|
494
501
|
contractSource: ContractSource;
|
|
@@ -489,6 +489,13 @@ interface ContractSource {
|
|
|
489
489
|
* `AsyncIterable<T>` stream rather than a single awaited value.
|
|
490
490
|
*/
|
|
491
491
|
stream?: boolean;
|
|
492
|
+
/**
|
|
493
|
+
* True when the route consumes `multipart/form-data` — its handler takes an
|
|
494
|
+
* `@UploadedFile()` / `@UploadedFiles()` (via a Multer interceptor). The
|
|
495
|
+
* uploaded-file field(s) are merged into `body` as `File | Blob`, and the
|
|
496
|
+
* generated client serializes the body to a `FormData` instead of JSON.
|
|
497
|
+
*/
|
|
498
|
+
multipart?: boolean;
|
|
492
499
|
}
|
|
493
500
|
interface ContractDescriptor {
|
|
494
501
|
contractSource: ContractSource;
|
package/dist/index.cjs
CHANGED
|
@@ -851,6 +851,7 @@ function buildRequestModel(c) {
|
|
|
851
851
|
const optsParts = [];
|
|
852
852
|
if (hasQuery) optsParts.push("query: input?.query as Record<string, unknown> | undefined");
|
|
853
853
|
if (hasBody) optsParts.push("body: input?.body");
|
|
854
|
+
if (hasBody && c.contractSource.multipart) optsParts.push("multipart: true");
|
|
854
855
|
const optsExpr = optsParts.length ? `{ ${optsParts.join(", ")} }` : "{}";
|
|
855
856
|
return {
|
|
856
857
|
routeName: c.name,
|
|
@@ -3734,6 +3735,55 @@ function extractParamsType(method, sourceFile, project) {
|
|
|
3734
3735
|
}
|
|
3735
3736
|
return entries.length > 0 ? `{ ${entries.join("; ")} }` : null;
|
|
3736
3737
|
}
|
|
3738
|
+
function extractUploadedFiles(method) {
|
|
3739
|
+
const FILE = "File | Blob";
|
|
3740
|
+
const entries = [];
|
|
3741
|
+
let multipart = false;
|
|
3742
|
+
const hasUploadedFileParam = method.getParameters().some(
|
|
3743
|
+
(p) => p.getDecorators().some((d) => {
|
|
3744
|
+
const name = d.getName();
|
|
3745
|
+
return name === "UploadedFile" || name === "UploadedFiles";
|
|
3746
|
+
})
|
|
3747
|
+
);
|
|
3748
|
+
for (const decorator of method.getDecorators()) {
|
|
3749
|
+
if (decorator.getName() !== "UseInterceptors") continue;
|
|
3750
|
+
for (const arg of decorator.getArguments()) {
|
|
3751
|
+
if (!import_ts_morph7.Node.isCallExpression(arg)) continue;
|
|
3752
|
+
const interceptor = arg.getExpression().getText();
|
|
3753
|
+
const callArgs = arg.getArguments();
|
|
3754
|
+
const firstArg2 = callArgs[0];
|
|
3755
|
+
if (interceptor === "FileInterceptor") {
|
|
3756
|
+
if (firstArg2 && import_ts_morph7.Node.isStringLiteral(firstArg2)) {
|
|
3757
|
+
entries.push(`${firstArg2.getLiteralValue()}: ${FILE}`);
|
|
3758
|
+
multipart = true;
|
|
3759
|
+
}
|
|
3760
|
+
} else if (interceptor === "FilesInterceptor") {
|
|
3761
|
+
if (firstArg2 && import_ts_morph7.Node.isStringLiteral(firstArg2)) {
|
|
3762
|
+
entries.push(`${firstArg2.getLiteralValue()}: Array<${FILE}>`);
|
|
3763
|
+
multipart = true;
|
|
3764
|
+
}
|
|
3765
|
+
} else if (interceptor === "FileFieldsInterceptor") {
|
|
3766
|
+
if (firstArg2 && import_ts_morph7.Node.isArrayLiteralExpression(firstArg2)) {
|
|
3767
|
+
for (const el of firstArg2.getElements()) {
|
|
3768
|
+
if (!import_ts_morph7.Node.isObjectLiteralExpression(el)) continue;
|
|
3769
|
+
const nameProp = el.getProperty("name");
|
|
3770
|
+
if (nameProp && import_ts_morph7.Node.isPropertyAssignment(nameProp)) {
|
|
3771
|
+
const init = nameProp.getInitializer();
|
|
3772
|
+
if (init && import_ts_morph7.Node.isStringLiteral(init)) {
|
|
3773
|
+
entries.push(`${init.getLiteralValue()}: Array<${FILE}>`);
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3776
|
+
}
|
|
3777
|
+
multipart = true;
|
|
3778
|
+
}
|
|
3779
|
+
} else if (interceptor === "AnyFilesInterceptor") {
|
|
3780
|
+
multipart = true;
|
|
3781
|
+
}
|
|
3782
|
+
}
|
|
3783
|
+
}
|
|
3784
|
+
if (hasUploadedFileParam) multipart = true;
|
|
3785
|
+
return { fields: entries.length > 0 ? entries.join("; ") : null, multipart };
|
|
3786
|
+
}
|
|
3737
3787
|
function extractResponseType(method, sourceFile, project) {
|
|
3738
3788
|
const apiResponseDecorator = method.getDecorators().find((d) => d.getName() === "ApiResponse" && (apiResponseStatus(d) ?? 0) < 400);
|
|
3739
3789
|
if (apiResponseDecorator) {
|
|
@@ -3868,6 +3918,11 @@ function extractDtoContract(method, sourceFile, project) {
|
|
|
3868
3918
|
let body = extractBodyType(method, sourceFile, project);
|
|
3869
3919
|
const filterInfo = extractApplyFilterInfo(method, sourceFile, project);
|
|
3870
3920
|
const query = extractQueryType(method, sourceFile, project);
|
|
3921
|
+
const uploads = extractUploadedFiles(method);
|
|
3922
|
+
if (uploads.fields) {
|
|
3923
|
+
const fileObject = `{ ${uploads.fields} }`;
|
|
3924
|
+
body = body ? `(${body}) & ${fileObject}` : fileObject;
|
|
3925
|
+
}
|
|
3871
3926
|
const streamElement = detectStreamElement(method);
|
|
3872
3927
|
const isStream = streamElement !== null;
|
|
3873
3928
|
if (filterInfo && filterInfo.source === "body") {
|
|
@@ -3877,7 +3932,7 @@ function extractDtoContract(method, sourceFile, project) {
|
|
|
3877
3932
|
const paramsType = extractParamsType(method, sourceFile, project);
|
|
3878
3933
|
const response = isStream ? resolveTypeNodeToString(streamElement, sourceFile, project, 3) : extractResponseType(method, sourceFile, project);
|
|
3879
3934
|
const errorInfo = extractErrorType(method, sourceFile, project);
|
|
3880
|
-
if (body === null && query === null && paramsType === null && response === "unknown" && errorInfo === null && filterInfo === null && !isStream) {
|
|
3935
|
+
if (body === null && query === null && paramsType === null && response === "unknown" && errorInfo === null && filterInfo === null && !isStream && !uploads.multipart) {
|
|
3881
3936
|
return null;
|
|
3882
3937
|
}
|
|
3883
3938
|
let bodyRef = null;
|
|
@@ -3950,7 +4005,8 @@ function extractDtoContract(method, sourceFile, project) {
|
|
|
3950
4005
|
formWarnings,
|
|
3951
4006
|
bodySchema,
|
|
3952
4007
|
querySchema,
|
|
3953
|
-
stream: isStream
|
|
4008
|
+
stream: isStream,
|
|
4009
|
+
multipart: uploads.multipart
|
|
3954
4010
|
};
|
|
3955
4011
|
}
|
|
3956
4012
|
function resolveParamClass(method, decoratorName, sourceFile, project) {
|
|
@@ -4435,7 +4491,8 @@ function extractDtoRoute(args) {
|
|
|
4435
4491
|
formWarnings: dtoContract?.formWarnings ?? [],
|
|
4436
4492
|
bodySchema: dtoContract?.bodySchema ?? null,
|
|
4437
4493
|
querySchema: dtoContract?.querySchema ?? null,
|
|
4438
|
-
stream: dtoContract?.stream ?? false
|
|
4494
|
+
stream: dtoContract?.stream ?? false,
|
|
4495
|
+
multipart: dtoContract?.multipart ?? false
|
|
4439
4496
|
}
|
|
4440
4497
|
});
|
|
4441
4498
|
}
|
|
@@ -4748,7 +4805,7 @@ function createChainModuleRenderer(opts) {
|
|
|
4748
4805
|
}
|
|
4749
4806
|
|
|
4750
4807
|
// src/index.ts
|
|
4751
|
-
var VERSION = "0.
|
|
4808
|
+
var VERSION = "0.13.0";
|
|
4752
4809
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4753
4810
|
0 && (module.exports = {
|
|
4754
4811
|
CodegenError,
|