@dudousxd/nestjs-codegen 0.13.0 → 0.13.2
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 +26 -0
- package/dist/cli/main.cjs +47 -8
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +47 -8
- 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-DvUzPXdh.d.cts → index-D8RIMVpU.d.cts} +10 -2
- package/dist/{index-DvUzPXdh.d.ts → index-D8RIMVpU.d.ts} +10 -2
- package/dist/index.cjs +47 -8
- 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 +47 -8
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +47 -8
- 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 +47 -8
- 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-D8RIMVpU.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-D8RIMVpU.js';
|
|
2
2
|
import 'ts-morph';
|
|
@@ -492,10 +492,18 @@ interface ContractSource {
|
|
|
492
492
|
/**
|
|
493
493
|
* True when the route consumes `multipart/form-data` — its handler takes an
|
|
494
494
|
* `@UploadedFile()` / `@UploadedFiles()` (via a Multer interceptor). The
|
|
495
|
-
* uploaded-file field(s) are
|
|
496
|
-
*
|
|
495
|
+
* uploaded-file field(s) are carried in `multipartBody` (typed `File | Blob`)
|
|
496
|
+
* and intersected onto `body` at emit time, and the generated client
|
|
497
|
+
* serializes the body to a `FormData` instead of JSON.
|
|
497
498
|
*/
|
|
498
499
|
multipart?: boolean;
|
|
500
|
+
/**
|
|
501
|
+
* The uploaded-file field(s) for a multipart route, as an object-type string
|
|
502
|
+
* (e.g. `{ file: File | Blob }`). Kept separate from `body` so the emitter can
|
|
503
|
+
* intersect it onto whichever body representation it picks — a named `bodyRef`
|
|
504
|
+
* or the inline `body` text — preserving the import when there is one.
|
|
505
|
+
*/
|
|
506
|
+
multipartBody?: string | null;
|
|
499
507
|
}
|
|
500
508
|
interface ContractDescriptor {
|
|
501
509
|
contractSource: ContractSource;
|
|
@@ -492,10 +492,18 @@ interface ContractSource {
|
|
|
492
492
|
/**
|
|
493
493
|
* True when the route consumes `multipart/form-data` — its handler takes an
|
|
494
494
|
* `@UploadedFile()` / `@UploadedFiles()` (via a Multer interceptor). The
|
|
495
|
-
* uploaded-file field(s) are
|
|
496
|
-
*
|
|
495
|
+
* uploaded-file field(s) are carried in `multipartBody` (typed `File | Blob`)
|
|
496
|
+
* and intersected onto `body` at emit time, and the generated client
|
|
497
|
+
* serializes the body to a `FormData` instead of JSON.
|
|
497
498
|
*/
|
|
498
499
|
multipart?: boolean;
|
|
500
|
+
/**
|
|
501
|
+
* The uploaded-file field(s) for a multipart route, as an object-type string
|
|
502
|
+
* (e.g. `{ file: File | Blob }`). Kept separate from `body` so the emitter can
|
|
503
|
+
* intersect it onto whichever body representation it picks — a named `bodyRef`
|
|
504
|
+
* or the inline `body` text — preserving the import when there is one.
|
|
505
|
+
*/
|
|
506
|
+
multipartBody?: string | null;
|
|
499
507
|
}
|
|
500
508
|
interface ContractDescriptor {
|
|
501
509
|
contractSource: ContractSource;
|
package/dist/index.cjs
CHANGED
|
@@ -816,7 +816,15 @@ function emitRouterTypeBlock(tree, indent, outDir, serialization) {
|
|
|
816
816
|
const isFilterQuery = c.contractSource.filterSource === "query" && !!c.contractSource.filterFields?.length;
|
|
817
817
|
const query = queryRef ? queryRef.isArray ? `Array<${queryRef.name}>` : queryRef.name : isFilterQuery ? emitFilterQueryType(c) : c.contractSource.query ?? "never";
|
|
818
818
|
const bodyRef = c.contractSource.bodyRef;
|
|
819
|
-
|
|
819
|
+
let body = method === "GET" ? "never" : bodyRef ? bodyRef.isArray ? `Array<${bodyRef.name}>` : bodyRef.name : c.contractSource.body ?? "never";
|
|
820
|
+
const multipartBody = c.contractSource.multipartBody;
|
|
821
|
+
if (c.contractSource.multipart && multipartBody) {
|
|
822
|
+
if (body === "never") {
|
|
823
|
+
body = multipartBody;
|
|
824
|
+
} else if (!bodyAcceptsAnything(body)) {
|
|
825
|
+
body = `(${body}) & ${multipartBody}`;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
820
828
|
const response = buildResponseType(c, outDir, serialization);
|
|
821
829
|
const error = buildErrorType(c);
|
|
822
830
|
const params = buildParamsType(c.params);
|
|
@@ -835,6 +843,25 @@ function emitRouterTypeBlock(tree, indent, outDir, serialization) {
|
|
|
835
843
|
}
|
|
836
844
|
return lines;
|
|
837
845
|
}
|
|
846
|
+
function topLevelUnionArms(type) {
|
|
847
|
+
const arms = [];
|
|
848
|
+
let depth = 0;
|
|
849
|
+
let start = 0;
|
|
850
|
+
for (let i = 0; i < type.length; i++) {
|
|
851
|
+
const ch = type[i];
|
|
852
|
+
if (ch === "{" || ch === "[" || ch === "<" || ch === "(") depth++;
|
|
853
|
+
else if (ch === "}" || ch === "]" || ch === ">" || ch === ")") depth--;
|
|
854
|
+
else if (ch === "|" && depth === 0) {
|
|
855
|
+
arms.push(type.slice(start, i).trim());
|
|
856
|
+
start = i + 1;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
arms.push(type.slice(start).trim());
|
|
860
|
+
return arms;
|
|
861
|
+
}
|
|
862
|
+
function bodyAcceptsAnything(body) {
|
|
863
|
+
return topLevelUnionArms(body).some((arm) => arm === "unknown" || arm === "any");
|
|
864
|
+
}
|
|
838
865
|
function buildRequestModel(c) {
|
|
839
866
|
const m = c.method.toLowerCase();
|
|
840
867
|
const flat = JSON.stringify(c.name);
|
|
@@ -3613,6 +3640,19 @@ function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /
|
|
|
3613
3640
|
dbg("unresolvable type:", name, "in", sourceFile.getFilePath());
|
|
3614
3641
|
return "unknown";
|
|
3615
3642
|
}
|
|
3643
|
+
if (import_ts_morph7.Node.isTypeLiteral(typeNode)) {
|
|
3644
|
+
const members = [];
|
|
3645
|
+
for (const member of typeNode.getMembers()) {
|
|
3646
|
+
if (import_ts_morph7.Node.isPropertySignature(member)) {
|
|
3647
|
+
const memberTypeNode = member.getTypeNode();
|
|
3648
|
+
const memberType = memberTypeNode ? resolveTypeNodeToString(memberTypeNode, sourceFile, project, depth, subst) : "unknown";
|
|
3649
|
+
members.push(`${member.getName()}${member.hasQuestionToken() ? "?" : ""}: ${memberType}`);
|
|
3650
|
+
} else {
|
|
3651
|
+
members.push(member.getText());
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3654
|
+
return members.length > 0 ? `{ ${members.join("; ")} }` : "{}";
|
|
3655
|
+
}
|
|
3616
3656
|
const kind = typeNode.getKind();
|
|
3617
3657
|
if (kind === import_ts_morph7.SyntaxKind.StringKeyword) return "string";
|
|
3618
3658
|
if (kind === import_ts_morph7.SyntaxKind.NumberKeyword) return "number";
|
|
@@ -3919,10 +3959,7 @@ function extractDtoContract(method, sourceFile, project) {
|
|
|
3919
3959
|
const filterInfo = extractApplyFilterInfo(method, sourceFile, project);
|
|
3920
3960
|
const query = extractQueryType(method, sourceFile, project);
|
|
3921
3961
|
const uploads = extractUploadedFiles(method);
|
|
3922
|
-
|
|
3923
|
-
const fileObject = `{ ${uploads.fields} }`;
|
|
3924
|
-
body = body ? `(${body}) & ${fileObject}` : fileObject;
|
|
3925
|
-
}
|
|
3962
|
+
const multipartBody = uploads.fields ? `{ ${uploads.fields} }` : null;
|
|
3926
3963
|
const streamElement = detectStreamElement(method);
|
|
3927
3964
|
const isStream = streamElement !== null;
|
|
3928
3965
|
if (filterInfo && filterInfo.source === "body") {
|
|
@@ -4006,7 +4043,8 @@ function extractDtoContract(method, sourceFile, project) {
|
|
|
4006
4043
|
bodySchema,
|
|
4007
4044
|
querySchema,
|
|
4008
4045
|
stream: isStream,
|
|
4009
|
-
multipart: uploads.multipart
|
|
4046
|
+
multipart: uploads.multipart,
|
|
4047
|
+
multipartBody
|
|
4010
4048
|
};
|
|
4011
4049
|
}
|
|
4012
4050
|
function resolveParamClass(method, decoratorName, sourceFile, project) {
|
|
@@ -4492,7 +4530,8 @@ function extractDtoRoute(args) {
|
|
|
4492
4530
|
bodySchema: dtoContract?.bodySchema ?? null,
|
|
4493
4531
|
querySchema: dtoContract?.querySchema ?? null,
|
|
4494
4532
|
stream: dtoContract?.stream ?? false,
|
|
4495
|
-
multipart: dtoContract?.multipart ?? false
|
|
4533
|
+
multipart: dtoContract?.multipart ?? false,
|
|
4534
|
+
multipartBody: dtoContract?.multipartBody ?? null
|
|
4496
4535
|
}
|
|
4497
4536
|
});
|
|
4498
4537
|
}
|
|
@@ -4805,7 +4844,7 @@ function createChainModuleRenderer(opts) {
|
|
|
4805
4844
|
}
|
|
4806
4845
|
|
|
4807
4846
|
// src/index.ts
|
|
4808
|
-
var VERSION = "0.13.
|
|
4847
|
+
var VERSION = "0.13.2";
|
|
4809
4848
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4810
4849
|
0 && (module.exports = {
|
|
4811
4850
|
CodegenError,
|