@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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @dudousxd/nestjs-codegen
|
|
2
2
|
|
|
3
|
+
## 0.13.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 889af1f: Resolve the members of an inline object-literal type (`{ a: Foo; b: Bar }`) in response/stream types instead of emitting the node's raw text. A named type nested in an object literal — most commonly an SSE payload's `Observable<{ data: SomeType }>`, where `SomeType` is imported from another package — was previously copied verbatim, leaving a bare, unimported identifier that is undefined in the generated file. Each member's type is now resolved (expanded inline, or reduced to `unknown` when unresolvable) like any other named reference.
|
|
8
|
+
|
|
9
|
+
## 0.13.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 6b51c7b: fix(multipart): intersect the uploaded-file field at emit time so it survives a named `bodyRef`, and leave deliberately-loose bodies untouched.
|
|
14
|
+
|
|
15
|
+
Two fixes to the multipart upload routes shipped in 0.13.0:
|
|
16
|
+
|
|
17
|
+
- **Named body refs now include the file field.** Discovery carries the uploaded-file
|
|
18
|
+
field(s) in a new `multipartBody` (kept off `body`), and the emitter intersects it onto
|
|
19
|
+
whichever body expression it picks — a named `bodyRef` (`BaseFileUploadDto`) or the inline
|
|
20
|
+
text. Previously the merge lived on the inline `body` string, so a route whose `@Body`
|
|
21
|
+
resolved to an imported DTO emitted the plain `BaseFileUploadDto` and dropped the file
|
|
22
|
+
field (`api.X({ body: { ...fields, file } })` failed to type-check).
|
|
23
|
+
|
|
24
|
+
- **Deliberately-loose bodies are left alone.** A `@Body() x: SomeDto | any` handler resolves
|
|
25
|
+
to a top-level `unknown`/`any` union arm; intersecting `(Dto | unknown) & { file }` collapses
|
|
26
|
+
it and wrongly tightens the type. The emitter now detects a permissive body and skips the
|
|
27
|
+
intersection, keeping the author's loose `@Body()` (the route is still flagged `multipart`).
|
|
28
|
+
|
|
3
29
|
## 0.13.0
|
|
4
30
|
|
|
5
31
|
### Minor Changes
|
package/dist/cli/main.cjs
CHANGED
|
@@ -785,7 +785,15 @@ function emitRouterTypeBlock(tree, indent, outDir, serialization) {
|
|
|
785
785
|
const isFilterQuery = c.contractSource.filterSource === "query" && !!c.contractSource.filterFields?.length;
|
|
786
786
|
const query = queryRef ? queryRef.isArray ? `Array<${queryRef.name}>` : queryRef.name : isFilterQuery ? emitFilterQueryType(c) : c.contractSource.query ?? "never";
|
|
787
787
|
const bodyRef = c.contractSource.bodyRef;
|
|
788
|
-
|
|
788
|
+
let body = method === "GET" ? "never" : bodyRef ? bodyRef.isArray ? `Array<${bodyRef.name}>` : bodyRef.name : c.contractSource.body ?? "never";
|
|
789
|
+
const multipartBody = c.contractSource.multipartBody;
|
|
790
|
+
if (c.contractSource.multipart && multipartBody) {
|
|
791
|
+
if (body === "never") {
|
|
792
|
+
body = multipartBody;
|
|
793
|
+
} else if (!bodyAcceptsAnything(body)) {
|
|
794
|
+
body = `(${body}) & ${multipartBody}`;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
789
797
|
const response = buildResponseType(c, outDir, serialization);
|
|
790
798
|
const error = buildErrorType(c);
|
|
791
799
|
const params = buildParamsType(c.params);
|
|
@@ -804,6 +812,25 @@ function emitRouterTypeBlock(tree, indent, outDir, serialization) {
|
|
|
804
812
|
}
|
|
805
813
|
return lines;
|
|
806
814
|
}
|
|
815
|
+
function topLevelUnionArms(type) {
|
|
816
|
+
const arms = [];
|
|
817
|
+
let depth = 0;
|
|
818
|
+
let start = 0;
|
|
819
|
+
for (let i = 0; i < type.length; i++) {
|
|
820
|
+
const ch = type[i];
|
|
821
|
+
if (ch === "{" || ch === "[" || ch === "<" || ch === "(") depth++;
|
|
822
|
+
else if (ch === "}" || ch === "]" || ch === ">" || ch === ")") depth--;
|
|
823
|
+
else if (ch === "|" && depth === 0) {
|
|
824
|
+
arms.push(type.slice(start, i).trim());
|
|
825
|
+
start = i + 1;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
arms.push(type.slice(start).trim());
|
|
829
|
+
return arms;
|
|
830
|
+
}
|
|
831
|
+
function bodyAcceptsAnything(body) {
|
|
832
|
+
return topLevelUnionArms(body).some((arm) => arm === "unknown" || arm === "any");
|
|
833
|
+
}
|
|
807
834
|
function buildRequestModel(c) {
|
|
808
835
|
const m = c.method.toLowerCase();
|
|
809
836
|
const flat = JSON.stringify(c.name);
|
|
@@ -3579,6 +3606,19 @@ function resolveTypeNodeToString(typeNode, sourceFile, project, depth, subst = /
|
|
|
3579
3606
|
dbg("unresolvable type:", name, "in", sourceFile.getFilePath());
|
|
3580
3607
|
return "unknown";
|
|
3581
3608
|
}
|
|
3609
|
+
if (import_ts_morph7.Node.isTypeLiteral(typeNode)) {
|
|
3610
|
+
const members = [];
|
|
3611
|
+
for (const member of typeNode.getMembers()) {
|
|
3612
|
+
if (import_ts_morph7.Node.isPropertySignature(member)) {
|
|
3613
|
+
const memberTypeNode = member.getTypeNode();
|
|
3614
|
+
const memberType = memberTypeNode ? resolveTypeNodeToString(memberTypeNode, sourceFile, project, depth, subst) : "unknown";
|
|
3615
|
+
members.push(`${member.getName()}${member.hasQuestionToken() ? "?" : ""}: ${memberType}`);
|
|
3616
|
+
} else {
|
|
3617
|
+
members.push(member.getText());
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3620
|
+
return members.length > 0 ? `{ ${members.join("; ")} }` : "{}";
|
|
3621
|
+
}
|
|
3582
3622
|
const kind = typeNode.getKind();
|
|
3583
3623
|
if (kind === import_ts_morph7.SyntaxKind.StringKeyword) return "string";
|
|
3584
3624
|
if (kind === import_ts_morph7.SyntaxKind.NumberKeyword) return "number";
|
|
@@ -3885,10 +3925,7 @@ function extractDtoContract(method, sourceFile, project) {
|
|
|
3885
3925
|
const filterInfo = extractApplyFilterInfo(method, sourceFile, project);
|
|
3886
3926
|
const query = extractQueryType(method, sourceFile, project);
|
|
3887
3927
|
const uploads = extractUploadedFiles(method);
|
|
3888
|
-
|
|
3889
|
-
const fileObject = `{ ${uploads.fields} }`;
|
|
3890
|
-
body = body ? `(${body}) & ${fileObject}` : fileObject;
|
|
3891
|
-
}
|
|
3928
|
+
const multipartBody = uploads.fields ? `{ ${uploads.fields} }` : null;
|
|
3892
3929
|
const streamElement = detectStreamElement(method);
|
|
3893
3930
|
const isStream = streamElement !== null;
|
|
3894
3931
|
if (filterInfo && filterInfo.source === "body") {
|
|
@@ -3972,7 +4009,8 @@ function extractDtoContract(method, sourceFile, project) {
|
|
|
3972
4009
|
bodySchema,
|
|
3973
4010
|
querySchema,
|
|
3974
4011
|
stream: isStream,
|
|
3975
|
-
multipart: uploads.multipart
|
|
4012
|
+
multipart: uploads.multipart,
|
|
4013
|
+
multipartBody
|
|
3976
4014
|
};
|
|
3977
4015
|
}
|
|
3978
4016
|
function resolveParamClass(method, decoratorName, sourceFile, project) {
|
|
@@ -4458,7 +4496,8 @@ function extractDtoRoute(args) {
|
|
|
4458
4496
|
bodySchema: dtoContract?.bodySchema ?? null,
|
|
4459
4497
|
querySchema: dtoContract?.querySchema ?? null,
|
|
4460
4498
|
stream: dtoContract?.stream ?? false,
|
|
4461
|
-
multipart: dtoContract?.multipart ?? false
|
|
4499
|
+
multipart: dtoContract?.multipart ?? false,
|
|
4500
|
+
multipartBody: dtoContract?.multipartBody ?? null
|
|
4462
4501
|
}
|
|
4463
4502
|
});
|
|
4464
4503
|
}
|
|
@@ -4688,7 +4727,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
4688
4727
|
}
|
|
4689
4728
|
|
|
4690
4729
|
// src/index.ts
|
|
4691
|
-
var VERSION = "0.13.
|
|
4730
|
+
var VERSION = "0.13.2";
|
|
4692
4731
|
|
|
4693
4732
|
// src/cli/codegen.ts
|
|
4694
4733
|
async function runCodegen(opts = {}) {
|