@nestia/sdk 8.1.0 → 9.0.0-dev.20251107

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.
Files changed (112) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +93 -93
  3. package/assets/bundle/api/HttpError.ts +1 -1
  4. package/assets/bundle/api/IConnection.ts +1 -1
  5. package/assets/bundle/api/Primitive.ts +1 -1
  6. package/assets/bundle/api/Resolved.ts +1 -1
  7. package/assets/bundle/api/index.ts +4 -4
  8. package/assets/bundle/api/module.ts +6 -6
  9. package/assets/bundle/distribute/README.md +37 -37
  10. package/assets/bundle/distribute/package.json +28 -28
  11. package/assets/bundle/distribute/tsconfig.json +109 -109
  12. package/assets/bundle/e2e/index.ts +42 -42
  13. package/assets/config/nestia.config.ts +97 -97
  14. package/lib/executable/internal/NestiaConfigLoader.js +4 -4
  15. package/lib/executable/sdk.js +12 -12
  16. package/package.json +7 -7
  17. package/src/INestiaConfig.ts +267 -267
  18. package/src/NestiaSdkApplication.ts +307 -307
  19. package/src/NestiaSwaggerComposer.ts +138 -138
  20. package/src/analyses/AccessorAnalyzer.ts +67 -67
  21. package/src/analyses/ConfigAnalyzer.ts +155 -155
  22. package/src/analyses/DtoAnalyzer.ts +246 -246
  23. package/src/analyses/ExceptionAnalyzer.ts +154 -154
  24. package/src/analyses/GenericAnalyzer.ts +49 -49
  25. package/src/analyses/ImportAnalyzer.ts +126 -126
  26. package/src/analyses/PathAnalyzer.ts +69 -69
  27. package/src/analyses/ReflectControllerAnalyzer.ts +105 -105
  28. package/src/analyses/ReflectHttpOperationAnalyzer.ts +183 -183
  29. package/src/analyses/ReflectHttpOperationExceptionAnalyzer.ts +71 -71
  30. package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +348 -348
  31. package/src/analyses/ReflectHttpOperationResponseAnalyzer.ts +127 -127
  32. package/src/analyses/ReflectMetadataAnalyzer.ts +44 -44
  33. package/src/analyses/ReflectWebSocketOperationAnalyzer.ts +172 -172
  34. package/src/analyses/SecurityAnalyzer.ts +25 -25
  35. package/src/analyses/TypedHttpRouteAnalyzer.ts +204 -204
  36. package/src/analyses/TypedWebSocketRouteAnalyzer.ts +33 -33
  37. package/src/decorators/OperationMetadata.ts +15 -15
  38. package/src/executable/internal/CommandParser.ts +15 -15
  39. package/src/executable/internal/NestiaConfigLoader.ts +78 -78
  40. package/src/executable/internal/NestiaSdkCommand.ts +103 -103
  41. package/src/executable/sdk.ts +75 -75
  42. package/src/generates/CloneGenerator.ts +66 -66
  43. package/src/generates/E2eGenerator.ts +32 -32
  44. package/src/generates/SdkGenerator.ts +160 -160
  45. package/src/generates/SwaggerGenerator.ts +284 -284
  46. package/src/generates/internal/E2eFileProgrammer.ts +197 -197
  47. package/src/generates/internal/FilePrinter.ts +53 -53
  48. package/src/generates/internal/ImportDictionary.ts +192 -192
  49. package/src/generates/internal/SdkAliasCollection.ts +261 -261
  50. package/src/generates/internal/SdkDistributionComposer.ts +103 -103
  51. package/src/generates/internal/SdkFileProgrammer.ts +110 -110
  52. package/src/generates/internal/SdkHttpCloneProgrammer.ts +124 -124
  53. package/src/generates/internal/SdkHttpCloneReferencer.ts +77 -77
  54. package/src/generates/internal/SdkHttpFunctionProgrammer.ts +279 -279
  55. package/src/generates/internal/SdkHttpNamespaceProgrammer.ts +500 -500
  56. package/src/generates/internal/SdkHttpParameterProgrammer.ts +178 -178
  57. package/src/generates/internal/SdkHttpRouteProgrammer.ts +108 -108
  58. package/src/generates/internal/SdkHttpSimulationProgrammer.ts +310 -310
  59. package/src/generates/internal/SdkImportWizard.ts +62 -62
  60. package/src/generates/internal/SdkRouteDirectory.ts +18 -18
  61. package/src/generates/internal/SdkTypeProgrammer.ts +385 -385
  62. package/src/generates/internal/SdkTypeTagProgrammer.ts +104 -104
  63. package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +381 -381
  64. package/src/generates/internal/SdkWebSocketParameterProgrammer.ts +87 -87
  65. package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +302 -302
  66. package/src/generates/internal/SwaggerDescriptionComposer.ts +64 -64
  67. package/src/generates/internal/SwaggerOperationComposer.ts +119 -119
  68. package/src/generates/internal/SwaggerOperationParameterComposer.ts +177 -177
  69. package/src/generates/internal/SwaggerOperationResponseComposer.ts +110 -110
  70. package/src/index.ts +4 -4
  71. package/src/module.ts +3 -3
  72. package/src/structures/INestiaProject.ts +13 -13
  73. package/src/structures/INestiaSdkInput.ts +20 -20
  74. package/src/structures/IReflectApplication.ts +8 -8
  75. package/src/structures/IReflectController.ts +15 -15
  76. package/src/structures/IReflectHttpOperation.ts +26 -26
  77. package/src/structures/IReflectHttpOperationException.ts +19 -19
  78. package/src/structures/IReflectHttpOperationParameter.ts +77 -77
  79. package/src/structures/IReflectHttpOperationSuccess.ts +22 -22
  80. package/src/structures/IReflectImport.ts +6 -6
  81. package/src/structures/IReflectOperationError.ts +26 -26
  82. package/src/structures/IReflectType.ts +4 -4
  83. package/src/structures/IReflectWebSocketOperation.ts +17 -17
  84. package/src/structures/IReflectWebSocketOperationParameter.ts +36 -36
  85. package/src/structures/ITypedApplication.ts +11 -11
  86. package/src/structures/ITypedHttpRoute.ts +41 -41
  87. package/src/structures/ITypedHttpRouteException.ts +15 -15
  88. package/src/structures/ITypedHttpRouteParameter.ts +41 -41
  89. package/src/structures/ITypedHttpRouteSuccess.ts +22 -22
  90. package/src/structures/ITypedWebSocketRoute.ts +24 -24
  91. package/src/structures/ITypedWebSocketRouteParameter.ts +3 -3
  92. package/src/structures/MethodType.ts +5 -5
  93. package/src/structures/ParamCategory.ts +1 -1
  94. package/src/structures/TypeEntry.ts +22 -22
  95. package/src/transform.ts +9 -9
  96. package/src/transformers/IOperationMetadata.ts +44 -44
  97. package/src/transformers/ISdkOperationTransformerContext.ts +8 -8
  98. package/src/transformers/SdkOperationProgrammer.ts +238 -238
  99. package/src/transformers/SdkOperationTransformer.ts +252 -252
  100. package/src/transformers/TextPlainValidator.ts +17 -17
  101. package/src/typings/get-function-location.d.ts +7 -7
  102. package/src/utils/ArrayUtil.ts +26 -26
  103. package/src/utils/FileRetriever.ts +22 -22
  104. package/src/utils/MapUtil.ts +14 -14
  105. package/src/utils/MetadataUtil.ts +26 -26
  106. package/src/utils/PathUtil.ts +10 -10
  107. package/src/utils/SourceFinder.ts +63 -63
  108. package/src/utils/StringUtil.ts +17 -17
  109. package/src/utils/StripEnums.ts +5 -5
  110. package/src/utils/VersioningStrategy.ts +28 -28
  111. package/src/validators/HttpHeadersValidator.ts +34 -34
  112. package/src/validators/HttpQueryValidator.ts +34 -34
@@ -1,238 +1,238 @@
1
- import { Singleton } from "tstl";
2
- import ts from "typescript";
3
- import { CommentFactory } from "typia/lib/factories/CommentFactory";
4
- import { MetadataCollection } from "typia/lib/factories/MetadataCollection";
5
- import { MetadataFactory } from "typia/lib/factories/MetadataFactory";
6
- import { TypeFactory } from "typia/lib/factories/TypeFactory";
7
- import { Metadata } from "typia/lib/schemas/metadata/Metadata";
8
- import { MetadataObjectType } from "typia/lib/schemas/metadata/MetadataObjectType";
9
- import { ValidationPipe } from "typia/lib/typings/ValidationPipe";
10
- import { Escaper } from "typia/lib/utils/Escaper";
11
-
12
- import { DtoAnalyzer } from "../analyses/DtoAnalyzer";
13
- import { IReflectImport } from "../structures/IReflectImport";
14
- import { MetadataUtil } from "../utils/MetadataUtil";
15
- import { IOperationMetadata } from "./IOperationMetadata";
16
- import { ISdkOperationTransformerContext } from "./ISdkOperationTransformerContext";
17
-
18
- export namespace SdkOperationProgrammer {
19
- export interface IProps {
20
- context: ISdkOperationTransformerContext;
21
- imports: Singleton<IReflectImport[]>;
22
- node: ts.MethodDeclaration;
23
- symbol: ts.Symbol | undefined;
24
- exceptions: ts.TypeNode[];
25
- }
26
- export const write = (p: IProps): IOperationMetadata => {
27
- return {
28
- parameters: p.node.parameters.map((parameter, index) =>
29
- writeParameter({
30
- context: p.context,
31
- imports: p.imports,
32
- parameter,
33
- index,
34
- }),
35
- ),
36
- success: writeResponse({
37
- context: p.context,
38
- imports: p.imports,
39
- typeNode: p.node.type ? getReturnTypeNode(p.node.type) : null,
40
- type: getReturnType({
41
- checker: p.context.checker,
42
- signature: p.context.checker.getSignatureFromDeclaration(p.node),
43
- }),
44
- }),
45
- exceptions: p.exceptions.map((e) =>
46
- writeResponse({
47
- context: p.context,
48
- imports: p.imports,
49
- typeNode: e,
50
- type: p.context.checker.getTypeFromTypeNode(e),
51
- }),
52
- ),
53
- jsDocTags: p.symbol?.getJsDocTags() ?? [],
54
- description: p.symbol
55
- ? (CommentFactory.description(p.symbol) ?? null)
56
- : null,
57
- };
58
- };
59
-
60
- const writeParameter = (props: {
61
- context: ISdkOperationTransformerContext;
62
- imports: Singleton<IReflectImport[]>;
63
- parameter: ts.ParameterDeclaration;
64
- index: number;
65
- }): IOperationMetadata.IParameter => {
66
- const symbol: ts.Symbol | undefined =
67
- props.context.checker.getSymbolAtLocation(props.parameter);
68
- const common: IOperationMetadata.IResponse = writeResponse({
69
- context: props.context,
70
- imports: props.imports,
71
- typeNode: props.parameter.type ?? null,
72
- type:
73
- props.context.checker.getTypeFromTypeNode(
74
- props.parameter.type ?? TypeFactory.keyword("any"),
75
- ) ?? null,
76
- });
77
- const optional: boolean = props.parameter.questionToken !== undefined;
78
- if (common.primitive.success)
79
- common.primitive.data.metadata.optional = optional;
80
- if (common.resolved.success)
81
- common.resolved.data.metadata.optional = optional;
82
-
83
- return {
84
- ...common,
85
- name: props.parameter.name.getText(),
86
- index: props.index,
87
- description: (symbol && CommentFactory.description(symbol)) ?? null,
88
- jsDocTags: symbol?.getJsDocTags() ?? [],
89
- };
90
- };
91
-
92
- const writeResponse = (p: {
93
- context: ISdkOperationTransformerContext;
94
- imports: Singleton<IReflectImport[]>;
95
- typeNode: ts.TypeNode | null;
96
- type: ts.Type | null;
97
- }): IOperationMetadata.IResponse => {
98
- const analyzed: DtoAnalyzer.IOutput | null = p.typeNode
99
- ? DtoAnalyzer.analyzeNode({
100
- checker: p.context.checker,
101
- imports: p.imports.get(),
102
- typeNode: p.typeNode,
103
- })
104
- : p.type
105
- ? DtoAnalyzer.analyzeType({
106
- checker: p.context.checker,
107
- imports: p.imports.get(),
108
- type: p.type,
109
- })
110
- : {
111
- type: { name: "any" },
112
- imports: [],
113
- };
114
- const [primitive, resolved] = [true, false].map((escape) =>
115
- MetadataFactory.analyze({
116
- checker: p.context.checker,
117
- transformer: p.context.transformer,
118
- options: {
119
- escape,
120
- constant: true,
121
- absorb: true,
122
- },
123
- collection: p.context.collection,
124
- type: p.type,
125
- }),
126
- );
127
- return {
128
- ...(analyzed
129
- ? analyzed
130
- : {
131
- imports: [],
132
- type: null,
133
- }),
134
- primitive: writeSchema({
135
- collection: p.context.collection,
136
- result: primitive,
137
- }),
138
- resolved: writeSchema({
139
- collection: p.context.collection,
140
- result: resolved,
141
- }),
142
- };
143
- };
144
-
145
- const writeSchema = (p: {
146
- collection: MetadataCollection;
147
- result: ValidationPipe<Metadata, MetadataFactory.IError>;
148
- }): ValidationPipe<IOperationMetadata.ISchema, IOperationMetadata.IError> => {
149
- if (p.result.success === false)
150
- return {
151
- success: false,
152
- errors: p.result.errors.map((e) => ({
153
- name: e.name,
154
- accessor:
155
- e.explore.object !== null
156
- ? join({
157
- object: e.explore.object,
158
- key: e.explore.property,
159
- })
160
- : null,
161
- messages: e.messages,
162
- })),
163
- };
164
- const visited: Set<string> = iterateVisited(p.result.data);
165
- return {
166
- success: true,
167
- data: {
168
- components: {
169
- objects: p.collection
170
- .objects()
171
- .filter((o) => visited.has(o.name))
172
- .map((o) => o.toJSON()),
173
- aliases: p.collection
174
- .aliases()
175
- .filter((a) => visited.has(a.name))
176
- .map((a) => a.toJSON()),
177
- arrays: p.collection
178
- .arrays()
179
- .filter((a) => visited.has(a.name))
180
- .map((a) => a.toJSON()),
181
- tuples: p.collection
182
- .tuples()
183
- .filter((t) => visited.has(t.name))
184
- .map((t) => t.toJSON()),
185
- },
186
- metadata: p.result.data.toJSON(),
187
- },
188
- };
189
- };
190
- }
191
-
192
- const iterateVisited = (metadata: Metadata): Set<string> => {
193
- const names: Set<string> = new Set();
194
- MetadataUtil.visit((m) => {
195
- for (const alias of m.aliases) names.add(alias.type.name);
196
- for (const array of m.arrays) names.add(array.type.name);
197
- for (const tuple of m.tuples) names.add(tuple.type.name);
198
- for (const object of m.objects) names.add(object.type.name);
199
- })(metadata);
200
- return names;
201
- };
202
-
203
- const join = ({
204
- object,
205
- key,
206
- }: {
207
- object: MetadataObjectType;
208
- key: string | object | null;
209
- }) => {
210
- if (key === null) return object.name;
211
- else if (typeof key === "object") return `${object.name}[key]`;
212
- else if (Escaper.variable(key)) return `${object.name}.${key}`;
213
- return `${object.name}[${JSON.stringify(key)}]`;
214
- };
215
-
216
- const getReturnTypeNode = (node: ts.TypeNode): ts.TypeNode | null => {
217
- if (ts.isTypeReferenceNode(node)) {
218
- const typeName: string = node.typeName.getText();
219
- if (typeName === "Promise") return node.typeArguments?.[0] ?? null;
220
- }
221
- return node;
222
- };
223
-
224
- const getReturnType = (p: {
225
- checker: ts.TypeChecker;
226
- signature: ts.Signature | undefined;
227
- }): ts.Type | null => {
228
- const type: ts.Type | null =
229
- (p.signature && p.checker.getReturnTypeOfSignature(p.signature)) ?? null;
230
- if (type === null) return null;
231
- else if (type.symbol?.name === "Promise") {
232
- const generic: readonly ts.Type[] = p.checker.getTypeArguments(
233
- type as ts.TypeReference,
234
- );
235
- return generic[0] ?? null;
236
- }
237
- return type;
238
- };
1
+ import { Singleton } from "tstl";
2
+ import ts from "typescript";
3
+ import { CommentFactory } from "typia/lib/factories/CommentFactory";
4
+ import { MetadataCollection } from "typia/lib/factories/MetadataCollection";
5
+ import { MetadataFactory } from "typia/lib/factories/MetadataFactory";
6
+ import { TypeFactory } from "typia/lib/factories/TypeFactory";
7
+ import { Metadata } from "typia/lib/schemas/metadata/Metadata";
8
+ import { MetadataObjectType } from "typia/lib/schemas/metadata/MetadataObjectType";
9
+ import { ValidationPipe } from "typia/lib/typings/ValidationPipe";
10
+ import { Escaper } from "typia/lib/utils/Escaper";
11
+
12
+ import { DtoAnalyzer } from "../analyses/DtoAnalyzer";
13
+ import { IReflectImport } from "../structures/IReflectImport";
14
+ import { MetadataUtil } from "../utils/MetadataUtil";
15
+ import { IOperationMetadata } from "./IOperationMetadata";
16
+ import { ISdkOperationTransformerContext } from "./ISdkOperationTransformerContext";
17
+
18
+ export namespace SdkOperationProgrammer {
19
+ export interface IProps {
20
+ context: ISdkOperationTransformerContext;
21
+ imports: Singleton<IReflectImport[]>;
22
+ node: ts.MethodDeclaration;
23
+ symbol: ts.Symbol | undefined;
24
+ exceptions: ts.TypeNode[];
25
+ }
26
+ export const write = (p: IProps): IOperationMetadata => {
27
+ return {
28
+ parameters: p.node.parameters.map((parameter, index) =>
29
+ writeParameter({
30
+ context: p.context,
31
+ imports: p.imports,
32
+ parameter,
33
+ index,
34
+ }),
35
+ ),
36
+ success: writeResponse({
37
+ context: p.context,
38
+ imports: p.imports,
39
+ typeNode: p.node.type ? getReturnTypeNode(p.node.type) : null,
40
+ type: getReturnType({
41
+ checker: p.context.checker,
42
+ signature: p.context.checker.getSignatureFromDeclaration(p.node),
43
+ }),
44
+ }),
45
+ exceptions: p.exceptions.map((e) =>
46
+ writeResponse({
47
+ context: p.context,
48
+ imports: p.imports,
49
+ typeNode: e,
50
+ type: p.context.checker.getTypeFromTypeNode(e),
51
+ }),
52
+ ),
53
+ jsDocTags: p.symbol?.getJsDocTags() ?? [],
54
+ description: p.symbol
55
+ ? (CommentFactory.description(p.symbol) ?? null)
56
+ : null,
57
+ };
58
+ };
59
+
60
+ const writeParameter = (props: {
61
+ context: ISdkOperationTransformerContext;
62
+ imports: Singleton<IReflectImport[]>;
63
+ parameter: ts.ParameterDeclaration;
64
+ index: number;
65
+ }): IOperationMetadata.IParameter => {
66
+ const symbol: ts.Symbol | undefined =
67
+ props.context.checker.getSymbolAtLocation(props.parameter);
68
+ const common: IOperationMetadata.IResponse = writeResponse({
69
+ context: props.context,
70
+ imports: props.imports,
71
+ typeNode: props.parameter.type ?? null,
72
+ type:
73
+ props.context.checker.getTypeFromTypeNode(
74
+ props.parameter.type ?? TypeFactory.keyword("any"),
75
+ ) ?? null,
76
+ });
77
+ const optional: boolean = props.parameter.questionToken !== undefined;
78
+ if (common.primitive.success)
79
+ common.primitive.data.metadata.optional = optional;
80
+ if (common.resolved.success)
81
+ common.resolved.data.metadata.optional = optional;
82
+
83
+ return {
84
+ ...common,
85
+ name: props.parameter.name.getText(),
86
+ index: props.index,
87
+ description: (symbol && CommentFactory.description(symbol)) ?? null,
88
+ jsDocTags: symbol?.getJsDocTags() ?? [],
89
+ };
90
+ };
91
+
92
+ const writeResponse = (p: {
93
+ context: ISdkOperationTransformerContext;
94
+ imports: Singleton<IReflectImport[]>;
95
+ typeNode: ts.TypeNode | null;
96
+ type: ts.Type | null;
97
+ }): IOperationMetadata.IResponse => {
98
+ const analyzed: DtoAnalyzer.IOutput | null = p.typeNode
99
+ ? DtoAnalyzer.analyzeNode({
100
+ checker: p.context.checker,
101
+ imports: p.imports.get(),
102
+ typeNode: p.typeNode,
103
+ })
104
+ : p.type
105
+ ? DtoAnalyzer.analyzeType({
106
+ checker: p.context.checker,
107
+ imports: p.imports.get(),
108
+ type: p.type,
109
+ })
110
+ : {
111
+ type: { name: "any" },
112
+ imports: [],
113
+ };
114
+ const [primitive, resolved] = [true, false].map((escape) =>
115
+ MetadataFactory.analyze({
116
+ checker: p.context.checker,
117
+ transformer: p.context.transformer,
118
+ options: {
119
+ escape,
120
+ constant: true,
121
+ absorb: true,
122
+ },
123
+ collection: p.context.collection,
124
+ type: p.type,
125
+ }),
126
+ );
127
+ return {
128
+ ...(analyzed
129
+ ? analyzed
130
+ : {
131
+ imports: [],
132
+ type: null,
133
+ }),
134
+ primitive: writeSchema({
135
+ collection: p.context.collection,
136
+ result: primitive,
137
+ }),
138
+ resolved: writeSchema({
139
+ collection: p.context.collection,
140
+ result: resolved,
141
+ }),
142
+ };
143
+ };
144
+
145
+ const writeSchema = (p: {
146
+ collection: MetadataCollection;
147
+ result: ValidationPipe<Metadata, MetadataFactory.IError>;
148
+ }): ValidationPipe<IOperationMetadata.ISchema, IOperationMetadata.IError> => {
149
+ if (p.result.success === false)
150
+ return {
151
+ success: false,
152
+ errors: p.result.errors.map((e) => ({
153
+ name: e.name,
154
+ accessor:
155
+ e.explore.object !== null
156
+ ? join({
157
+ object: e.explore.object,
158
+ key: e.explore.property,
159
+ })
160
+ : null,
161
+ messages: e.messages,
162
+ })),
163
+ };
164
+ const visited: Set<string> = iterateVisited(p.result.data);
165
+ return {
166
+ success: true,
167
+ data: {
168
+ components: {
169
+ objects: p.collection
170
+ .objects()
171
+ .filter((o) => visited.has(o.name))
172
+ .map((o) => o.toJSON()),
173
+ aliases: p.collection
174
+ .aliases()
175
+ .filter((a) => visited.has(a.name))
176
+ .map((a) => a.toJSON()),
177
+ arrays: p.collection
178
+ .arrays()
179
+ .filter((a) => visited.has(a.name))
180
+ .map((a) => a.toJSON()),
181
+ tuples: p.collection
182
+ .tuples()
183
+ .filter((t) => visited.has(t.name))
184
+ .map((t) => t.toJSON()),
185
+ },
186
+ metadata: p.result.data.toJSON(),
187
+ },
188
+ };
189
+ };
190
+ }
191
+
192
+ const iterateVisited = (metadata: Metadata): Set<string> => {
193
+ const names: Set<string> = new Set();
194
+ MetadataUtil.visit((m) => {
195
+ for (const alias of m.aliases) names.add(alias.type.name);
196
+ for (const array of m.arrays) names.add(array.type.name);
197
+ for (const tuple of m.tuples) names.add(tuple.type.name);
198
+ for (const object of m.objects) names.add(object.type.name);
199
+ })(metadata);
200
+ return names;
201
+ };
202
+
203
+ const join = ({
204
+ object,
205
+ key,
206
+ }: {
207
+ object: MetadataObjectType;
208
+ key: string | object | null;
209
+ }) => {
210
+ if (key === null) return object.name;
211
+ else if (typeof key === "object") return `${object.name}[key]`;
212
+ else if (Escaper.variable(key)) return `${object.name}.${key}`;
213
+ return `${object.name}[${JSON.stringify(key)}]`;
214
+ };
215
+
216
+ const getReturnTypeNode = (node: ts.TypeNode): ts.TypeNode | null => {
217
+ if (ts.isTypeReferenceNode(node)) {
218
+ const typeName: string = node.typeName.getText();
219
+ if (typeName === "Promise") return node.typeArguments?.[0] ?? null;
220
+ }
221
+ return node;
222
+ };
223
+
224
+ const getReturnType = (p: {
225
+ checker: ts.TypeChecker;
226
+ signature: ts.Signature | undefined;
227
+ }): ts.Type | null => {
228
+ const type: ts.Type | null =
229
+ (p.signature && p.checker.getReturnTypeOfSignature(p.signature)) ?? null;
230
+ if (type === null) return null;
231
+ else if (type.symbol?.name === "Promise") {
232
+ const generic: readonly ts.Type[] = p.checker.getTypeArguments(
233
+ type as ts.TypeReference,
234
+ );
235
+ return generic[0] ?? null;
236
+ }
237
+ return type;
238
+ };