@nestia/sdk 2.5.0-dev.20240130 → 2.5.0-dev.20240130-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.
@@ -1,191 +1,191 @@
1
- import fs from "fs";
2
- import ts from "typescript";
3
- import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";
4
-
5
- import { INestiaConfig } from "../../INestiaConfig";
6
- import { IRoute } from "../../structures/IRoute";
7
- import { FormatUtil } from "../../utils/FormatUtil";
8
- import { ImportDictionary } from "../../utils/ImportDictionary";
9
- import { SdkAliasCollection } from "./SdkAliasCollection";
10
- import { SdkImportWizard } from "./SdkImportWizard";
11
- import { SdkTypeProgrammer } from "./SdkTypeProgrammer";
12
-
13
- export namespace E2eFileProgrammer {
14
- export const generate =
15
- (checker: ts.TypeChecker) =>
16
- (config: INestiaConfig) =>
17
- (props: { api: string; current: string }) =>
18
- async (route: IRoute): Promise<void> => {
19
- const importer: ImportDictionary = new ImportDictionary(
20
- `${props.current}/${getFunctionName(route)}.ts`,
21
- );
22
- if (config.clone !== true)
23
- for (const tuple of route.imports)
24
- for (const instance of tuple[1])
25
- importer.internal({
26
- file: tuple[0],
27
- type: true,
28
- instance,
29
- });
30
- importer.internal({
31
- type: false,
32
- file: props.api,
33
- instance: null,
34
- name: "api",
35
- });
36
-
37
- const functor = generate_function(checker)(config)(importer)(route);
38
-
39
- await fs.promises.writeFile(
40
- importer.file,
41
- await FormatUtil.beautify(
42
- ts
43
- .createPrinter()
44
- .printFile(
45
- ts.factory.createSourceFile(
46
- [
47
- ...importer.toStatements(props.current),
48
- FormatUtil.enter(),
49
- functor,
50
- ],
51
- ts.factory.createToken(ts.SyntaxKind.EndOfFileToken),
52
- ts.NodeFlags.None,
53
- ),
54
- ),
55
- ),
56
- "utf8",
57
- );
58
- };
59
-
60
- const generate_function =
61
- (checker: ts.TypeChecker) =>
62
- (config: INestiaConfig) =>
63
- (importer: ImportDictionary) =>
64
- (route: IRoute): ts.Statement =>
65
- ts.factory.createVariableStatement(
66
- [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
67
- ts.factory.createVariableDeclarationList(
68
- [
69
- ts.factory.createVariableDeclaration(
70
- ts.factory.createIdentifier(getFunctionName(route)),
71
- undefined,
72
- undefined,
73
- generate_arrow(checker)(config)(importer)(route),
74
- ),
75
- ],
76
- ts.NodeFlags.Const,
77
- ),
78
- );
79
-
80
- const generate_arrow =
81
- (checker: ts.TypeChecker) =>
82
- (config: INestiaConfig) =>
83
- (importer: ImportDictionary) =>
84
- (route: IRoute) => {
85
- const headers = route.parameters.find(
86
- (p) => p.category === "headers" && p.field === undefined,
87
- );
88
- const connection = headers
89
- ? ts.factory.createObjectLiteralExpression(
90
- [
91
- ts.factory.createSpreadAssignment(
92
- ts.factory.createIdentifier("connection"),
93
- ),
94
- ts.factory.createPropertyAssignment(
95
- "headers",
96
- ts.factory.createObjectLiteralExpression(
97
- [
98
- ts.factory.createSpreadAssignment(
99
- IdentifierFactory.access(
100
- ts.factory.createIdentifier("connection"),
101
- )("headers"),
102
- ),
103
- ts.factory.createSpreadAssignment(
104
- ts.factory.createCallExpression(
105
- IdentifierFactory.access(
106
- ts.factory.createIdentifier(
107
- SdkImportWizard.typia(importer),
108
- ),
109
- )("random"),
110
- [getTypeName(config)(importer)(headers)],
111
- undefined,
112
- ),
113
- ),
114
- ],
115
- true,
116
- ),
117
- ),
118
- ],
119
- true,
120
- )
121
- : ts.factory.createIdentifier("connection");
122
- const caller = ts.factory.createCallExpression(
123
- ts.factory.createIdentifier(
124
- ["api", "functional", ...route.accessors].join("."),
125
- ),
126
- undefined,
127
- [
128
- connection,
129
- ...route.parameters
130
- .filter((p) => p.category !== "headers")
131
- .map((p) =>
132
- ts.factory.createCallExpression(
133
- IdentifierFactory.access(
134
- ts.factory.createIdentifier(SdkImportWizard.typia(importer)),
135
- )("random"),
136
- [getTypeName(config)(importer)(p)],
137
- undefined,
138
- ),
139
- ),
140
- ],
141
- );
142
- const assert = ts.factory.createCallExpression(
143
- IdentifierFactory.access(
144
- ts.factory.createIdentifier(SdkImportWizard.typia(importer)),
145
- )("assert"),
146
- undefined,
147
- [ts.factory.createIdentifier("output")],
148
- );
149
-
150
- return ts.factory.createArrowFunction(
151
- [ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword)],
152
- undefined,
153
- [
154
- IdentifierFactory.parameter(
155
- "connection",
156
- ts.factory.createTypeReferenceNode("api.IConnection"),
157
- ),
158
- ],
159
- undefined,
160
- undefined,
161
- ts.factory.createBlock([
162
- ts.factory.createVariableStatement(
163
- [],
164
- ts.factory.createVariableDeclarationList(
165
- [
166
- ts.factory.createVariableDeclaration(
167
- "output",
168
- undefined,
169
- SdkAliasCollection.output(checker)(config)(importer)(route),
170
- ts.factory.createAwaitExpression(caller),
171
- ),
172
- ],
173
- ts.NodeFlags.Const,
174
- ),
175
- ),
176
- ts.factory.createExpressionStatement(assert),
177
- ]),
178
- );
179
- };
180
- }
181
-
182
- const getFunctionName = (route: IRoute): string =>
183
- ["test", "api", ...route.accessors].join("_");
184
-
185
- const getTypeName =
186
- (config: INestiaConfig) =>
187
- (importer: ImportDictionary) =>
188
- (p: IRoute.IParameter | IRoute.IOutput) =>
189
- p.metadata
190
- ? SdkTypeProgrammer.decode(config)(importer)(p.metadata)
191
- : ts.factory.createTypeReferenceNode(p.typeName);
1
+ import fs from "fs";
2
+ import ts from "typescript";
3
+ import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";
4
+
5
+ import { INestiaConfig } from "../../INestiaConfig";
6
+ import { IRoute } from "../../structures/IRoute";
7
+ import { FormatUtil } from "../../utils/FormatUtil";
8
+ import { ImportDictionary } from "../../utils/ImportDictionary";
9
+ import { SdkAliasCollection } from "./SdkAliasCollection";
10
+ import { SdkImportWizard } from "./SdkImportWizard";
11
+ import { SdkTypeProgrammer } from "./SdkTypeProgrammer";
12
+
13
+ export namespace E2eFileProgrammer {
14
+ export const generate =
15
+ (checker: ts.TypeChecker) =>
16
+ (config: INestiaConfig) =>
17
+ (props: { api: string; current: string }) =>
18
+ async (route: IRoute): Promise<void> => {
19
+ const importer: ImportDictionary = new ImportDictionary(
20
+ `${props.current}/${getFunctionName(route)}.ts`,
21
+ );
22
+ if (config.clone !== true)
23
+ for (const tuple of route.imports)
24
+ for (const instance of tuple[1])
25
+ importer.internal({
26
+ file: tuple[0],
27
+ type: true,
28
+ instance,
29
+ });
30
+ importer.internal({
31
+ type: false,
32
+ file: props.api,
33
+ instance: null,
34
+ name: "api",
35
+ });
36
+
37
+ const functor = generate_function(checker)(config)(importer)(route);
38
+
39
+ await fs.promises.writeFile(
40
+ importer.file,
41
+ await FormatUtil.beautify(
42
+ ts
43
+ .createPrinter()
44
+ .printFile(
45
+ ts.factory.createSourceFile(
46
+ [
47
+ ...importer.toStatements(props.current),
48
+ FormatUtil.enter(),
49
+ functor,
50
+ ],
51
+ ts.factory.createToken(ts.SyntaxKind.EndOfFileToken),
52
+ ts.NodeFlags.None,
53
+ ),
54
+ ),
55
+ ),
56
+ "utf8",
57
+ );
58
+ };
59
+
60
+ const generate_function =
61
+ (checker: ts.TypeChecker) =>
62
+ (config: INestiaConfig) =>
63
+ (importer: ImportDictionary) =>
64
+ (route: IRoute): ts.Statement =>
65
+ ts.factory.createVariableStatement(
66
+ [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
67
+ ts.factory.createVariableDeclarationList(
68
+ [
69
+ ts.factory.createVariableDeclaration(
70
+ ts.factory.createIdentifier(getFunctionName(route)),
71
+ undefined,
72
+ undefined,
73
+ generate_arrow(checker)(config)(importer)(route),
74
+ ),
75
+ ],
76
+ ts.NodeFlags.Const,
77
+ ),
78
+ );
79
+
80
+ const generate_arrow =
81
+ (checker: ts.TypeChecker) =>
82
+ (config: INestiaConfig) =>
83
+ (importer: ImportDictionary) =>
84
+ (route: IRoute) => {
85
+ const headers = route.parameters.find(
86
+ (p) => p.category === "headers" && p.field === undefined,
87
+ );
88
+ const connection = headers
89
+ ? ts.factory.createObjectLiteralExpression(
90
+ [
91
+ ts.factory.createSpreadAssignment(
92
+ ts.factory.createIdentifier("connection"),
93
+ ),
94
+ ts.factory.createPropertyAssignment(
95
+ "headers",
96
+ ts.factory.createObjectLiteralExpression(
97
+ [
98
+ ts.factory.createSpreadAssignment(
99
+ IdentifierFactory.access(
100
+ ts.factory.createIdentifier("connection"),
101
+ )("headers"),
102
+ ),
103
+ ts.factory.createSpreadAssignment(
104
+ ts.factory.createCallExpression(
105
+ IdentifierFactory.access(
106
+ ts.factory.createIdentifier(
107
+ SdkImportWizard.typia(importer),
108
+ ),
109
+ )("random"),
110
+ [getTypeName(config)(importer)(headers)],
111
+ undefined,
112
+ ),
113
+ ),
114
+ ],
115
+ true,
116
+ ),
117
+ ),
118
+ ],
119
+ true,
120
+ )
121
+ : ts.factory.createIdentifier("connection");
122
+ const caller = ts.factory.createCallExpression(
123
+ ts.factory.createIdentifier(
124
+ ["api", "functional", ...route.accessors].join("."),
125
+ ),
126
+ undefined,
127
+ [
128
+ connection,
129
+ ...route.parameters
130
+ .filter((p) => p.category !== "headers")
131
+ .map((p) =>
132
+ ts.factory.createCallExpression(
133
+ IdentifierFactory.access(
134
+ ts.factory.createIdentifier(SdkImportWizard.typia(importer)),
135
+ )("random"),
136
+ [getTypeName(config)(importer)(p)],
137
+ undefined,
138
+ ),
139
+ ),
140
+ ],
141
+ );
142
+ const assert = ts.factory.createCallExpression(
143
+ IdentifierFactory.access(
144
+ ts.factory.createIdentifier(SdkImportWizard.typia(importer)),
145
+ )("assert"),
146
+ undefined,
147
+ [ts.factory.createIdentifier("output")],
148
+ );
149
+
150
+ return ts.factory.createArrowFunction(
151
+ [ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword)],
152
+ undefined,
153
+ [
154
+ IdentifierFactory.parameter(
155
+ "connection",
156
+ ts.factory.createTypeReferenceNode("api.IConnection"),
157
+ ),
158
+ ],
159
+ undefined,
160
+ undefined,
161
+ ts.factory.createBlock([
162
+ ts.factory.createVariableStatement(
163
+ [],
164
+ ts.factory.createVariableDeclarationList(
165
+ [
166
+ ts.factory.createVariableDeclaration(
167
+ "output",
168
+ undefined,
169
+ SdkAliasCollection.output(checker)(config)(importer)(route),
170
+ ts.factory.createAwaitExpression(caller),
171
+ ),
172
+ ],
173
+ ts.NodeFlags.Const,
174
+ ),
175
+ ),
176
+ ts.factory.createExpressionStatement(assert),
177
+ ]),
178
+ );
179
+ };
180
+ }
181
+
182
+ const getFunctionName = (route: IRoute): string =>
183
+ ["test", "api", ...route.accessors].join("_");
184
+
185
+ const getTypeName =
186
+ (config: INestiaConfig) =>
187
+ (importer: ImportDictionary) =>
188
+ (p: IRoute.IParameter | IRoute.IOutput) =>
189
+ p.metadata
190
+ ? SdkTypeProgrammer.decode(config)(importer)(p.metadata)
191
+ : ts.factory.createTypeReferenceNode(p.typeName);
@@ -1,145 +1,145 @@
1
- import ts from "typescript";
2
-
3
- import { INestiaConfig } from "../../INestiaConfig";
4
- import { IRoute } from "../../structures/IRoute";
5
- import { ImportDictionary } from "../../utils/ImportDictionary";
6
- import { SdkTypeProgrammer } from "./SdkTypeProgrammer";
7
-
8
- export namespace SdkAliasCollection {
9
- export const name =
10
- (config: INestiaConfig) =>
11
- (importer: ImportDictionary) =>
12
- (p: IRoute.IParameter | IRoute.IOutput): ts.TypeNode =>
13
- p.metadata
14
- ? SdkTypeProgrammer.decode(config)(importer)(p.metadata)
15
- : ts.factory.createTypeReferenceNode(p.typeName);
16
-
17
- export const headers =
18
- (config: INestiaConfig) =>
19
- (importer: ImportDictionary) =>
20
- (param: IRoute.IParameter): ts.TypeNode => {
21
- const type: ts.TypeNode = name(config)(importer)(param);
22
- if (config.primitive === false) return type;
23
- return ts.factory.createTypeReferenceNode(
24
- importer.external({
25
- type: true,
26
- library: "@nestia/fetcher",
27
- instance: "Resolved",
28
- }),
29
- [type],
30
- );
31
- };
32
-
33
- export const query =
34
- (config: INestiaConfig) =>
35
- (importer: ImportDictionary) =>
36
- (param: IRoute.IParameter): ts.TypeNode => {
37
- const type: ts.TypeNode = name(config)(importer)(param);
38
- if (config.primitive === false) return type;
39
- return ts.factory.createTypeReferenceNode(
40
- importer.external({
41
- type: true,
42
- library: "@nestia/fetcher",
43
- instance: "Resolved",
44
- }),
45
- [type],
46
- );
47
- };
48
-
49
- export const input =
50
- (config: INestiaConfig) =>
51
- (importer: ImportDictionary) =>
52
- (param: IRoute.IParameter): ts.TypeNode => {
53
- const type: ts.TypeNode = name(config)(importer)(param);
54
- if (config.primitive === false) return type;
55
- return ts.factory.createTypeReferenceNode(
56
- importer.external({
57
- type: true,
58
- library: "@nestia/fetcher",
59
- instance: "Primitive",
60
- }),
61
- [type],
62
- );
63
- };
64
-
65
- export const output =
66
- (checker: ts.TypeChecker) =>
67
- (config: INestiaConfig) =>
68
- (importer: ImportDictionary) =>
69
- (route: IRoute): ts.TypeNode => {
70
- if (config.propagate !== true) {
71
- const node: ts.TypeNode = name(config)(importer)(route.output);
72
- const type = checker.getTypeAtLocation(node);
73
- const filter = (flag: ts.TypeFlags) => (type.getFlags() & flag) !== 0;
74
-
75
- if (
76
- filter(ts.TypeFlags.Undefined) ||
77
- filter(ts.TypeFlags.Never) ||
78
- filter(ts.TypeFlags.Void) ||
79
- filter(ts.TypeFlags.VoidLike) ||
80
- config.primitive === false
81
- )
82
- return node;
83
- return ts.factory.createTypeReferenceNode(
84
- importer.external({
85
- type: true,
86
- library: "@nestia/fetcher",
87
- instance:
88
- route.output.contentType === "application/x-www-form-urlencoded"
89
- ? "Resolved"
90
- : "Primitive",
91
- }),
92
- [node],
93
- );
94
- }
95
-
96
- const branches: IBranch[] = [
97
- {
98
- status: String(route.status ?? (route.method === "POST" ? 201 : 200)),
99
- type: name(config)(importer)(route.output),
100
- },
101
- ...Object.entries(route.exceptions).map(([status, value]) => ({
102
- status,
103
- type: name(config)(importer)(value),
104
- })),
105
- ];
106
- return ts.factory.createTypeReferenceNode(
107
- importer.external({
108
- type: true,
109
- library: "@nestia/fetcher",
110
- instance: "IPropagation",
111
- }),
112
- [
113
- ts.factory.createTypeLiteralNode(
114
- branches.map((b) =>
115
- ts.factory.createPropertySignature(
116
- undefined,
117
- ts.factory.createNumericLiteral(b.status),
118
- undefined,
119
- b.type,
120
- ),
121
- ),
122
- ),
123
- ...(route.status
124
- ? [
125
- ts.factory.createLiteralTypeNode(
126
- ts.factory.createNumericLiteral(route.status),
127
- ),
128
- ]
129
- : []),
130
- ],
131
- );
132
- };
133
-
134
- export const responseBody =
135
- (checker: ts.TypeChecker) =>
136
- (config: INestiaConfig) =>
137
- (importer: ImportDictionary) =>
138
- (route: IRoute): ts.TypeNode =>
139
- output(checker)({ ...config, propagate: false })(importer)(route);
140
- }
141
-
142
- interface IBranch {
143
- status: string;
144
- type: ts.TypeNode;
145
- }
1
+ import ts from "typescript";
2
+
3
+ import { INestiaConfig } from "../../INestiaConfig";
4
+ import { IRoute } from "../../structures/IRoute";
5
+ import { ImportDictionary } from "../../utils/ImportDictionary";
6
+ import { SdkTypeProgrammer } from "./SdkTypeProgrammer";
7
+
8
+ export namespace SdkAliasCollection {
9
+ export const name =
10
+ (config: INestiaConfig) =>
11
+ (importer: ImportDictionary) =>
12
+ (p: IRoute.IParameter | IRoute.IOutput): ts.TypeNode =>
13
+ p.metadata
14
+ ? SdkTypeProgrammer.decode(config)(importer)(p.metadata)
15
+ : ts.factory.createTypeReferenceNode(p.typeName);
16
+
17
+ export const headers =
18
+ (config: INestiaConfig) =>
19
+ (importer: ImportDictionary) =>
20
+ (param: IRoute.IParameter): ts.TypeNode => {
21
+ const type: ts.TypeNode = name(config)(importer)(param);
22
+ if (config.primitive === false) return type;
23
+ return ts.factory.createTypeReferenceNode(
24
+ importer.external({
25
+ type: true,
26
+ library: "@nestia/fetcher",
27
+ instance: "Resolved",
28
+ }),
29
+ [type],
30
+ );
31
+ };
32
+
33
+ export const query =
34
+ (config: INestiaConfig) =>
35
+ (importer: ImportDictionary) =>
36
+ (param: IRoute.IParameter): ts.TypeNode => {
37
+ const type: ts.TypeNode = name(config)(importer)(param);
38
+ if (config.primitive === false) return type;
39
+ return ts.factory.createTypeReferenceNode(
40
+ importer.external({
41
+ type: true,
42
+ library: "@nestia/fetcher",
43
+ instance: "Resolved",
44
+ }),
45
+ [type],
46
+ );
47
+ };
48
+
49
+ export const input =
50
+ (config: INestiaConfig) =>
51
+ (importer: ImportDictionary) =>
52
+ (param: IRoute.IParameter): ts.TypeNode => {
53
+ const type: ts.TypeNode = name(config)(importer)(param);
54
+ if (config.primitive === false) return type;
55
+ return ts.factory.createTypeReferenceNode(
56
+ importer.external({
57
+ type: true,
58
+ library: "@nestia/fetcher",
59
+ instance: "Primitive",
60
+ }),
61
+ [type],
62
+ );
63
+ };
64
+
65
+ export const output =
66
+ (checker: ts.TypeChecker) =>
67
+ (config: INestiaConfig) =>
68
+ (importer: ImportDictionary) =>
69
+ (route: IRoute): ts.TypeNode => {
70
+ if (config.propagate !== true) {
71
+ const node: ts.TypeNode = name(config)(importer)(route.output);
72
+ const type = checker.getTypeAtLocation(node);
73
+ const filter = (flag: ts.TypeFlags) => (type.getFlags() & flag) !== 0;
74
+
75
+ if (
76
+ filter(ts.TypeFlags.Undefined) ||
77
+ filter(ts.TypeFlags.Never) ||
78
+ filter(ts.TypeFlags.Void) ||
79
+ filter(ts.TypeFlags.VoidLike) ||
80
+ config.primitive === false
81
+ )
82
+ return node;
83
+ return ts.factory.createTypeReferenceNode(
84
+ importer.external({
85
+ type: true,
86
+ library: "@nestia/fetcher",
87
+ instance:
88
+ route.output.contentType === "application/x-www-form-urlencoded"
89
+ ? "Resolved"
90
+ : "Primitive",
91
+ }),
92
+ [node],
93
+ );
94
+ }
95
+
96
+ const branches: IBranch[] = [
97
+ {
98
+ status: String(route.status ?? (route.method === "POST" ? 201 : 200)),
99
+ type: name(config)(importer)(route.output),
100
+ },
101
+ ...Object.entries(route.exceptions).map(([status, value]) => ({
102
+ status,
103
+ type: name(config)(importer)(value),
104
+ })),
105
+ ];
106
+ return ts.factory.createTypeReferenceNode(
107
+ importer.external({
108
+ type: true,
109
+ library: "@nestia/fetcher",
110
+ instance: "IPropagation",
111
+ }),
112
+ [
113
+ ts.factory.createTypeLiteralNode(
114
+ branches.map((b) =>
115
+ ts.factory.createPropertySignature(
116
+ undefined,
117
+ ts.factory.createNumericLiteral(b.status),
118
+ undefined,
119
+ b.type,
120
+ ),
121
+ ),
122
+ ),
123
+ ...(route.status
124
+ ? [
125
+ ts.factory.createLiteralTypeNode(
126
+ ts.factory.createNumericLiteral(route.status),
127
+ ),
128
+ ]
129
+ : []),
130
+ ],
131
+ );
132
+ };
133
+
134
+ export const responseBody =
135
+ (checker: ts.TypeChecker) =>
136
+ (config: INestiaConfig) =>
137
+ (importer: ImportDictionary) =>
138
+ (route: IRoute): ts.TypeNode =>
139
+ output(checker)({ ...config, propagate: false })(importer)(route);
140
+ }
141
+
142
+ interface IBranch {
143
+ status: string;
144
+ type: ts.TypeNode;
145
+ }