@nestia/sdk 12.0.0-dev.20260601.1 → 12.0.0-dev.20260612.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/LICENSE +21 -21
- package/README.md +93 -93
- package/assets/bundle/api/HttpError.ts +1 -1
- package/assets/bundle/api/IConnection.ts +1 -1
- package/assets/bundle/api/Primitive.ts +1 -1
- package/assets/bundle/api/Resolved.ts +1 -1
- package/assets/bundle/api/index.ts +4 -4
- package/assets/bundle/api/module.ts +6 -6
- package/assets/bundle/distribute/README.md +37 -37
- package/assets/bundle/distribute/package.json +28 -28
- package/assets/bundle/distribute/tsconfig.json +109 -109
- package/assets/bundle/e2e/index.ts +42 -42
- package/assets/config/nestia.config.ts +97 -97
- package/lib/NestiaSdkApplication.js +29 -7
- package/lib/NestiaSdkApplication.js.map +1 -1
- package/lib/NestiaSwaggerComposer.js +21 -13
- package/lib/NestiaSwaggerComposer.js.map +1 -1
- package/lib/analyses/AccessorAnalyzer.d.ts +4 -1
- package/lib/analyses/AccessorAnalyzer.js.map +1 -1
- package/lib/analyses/ConfigAnalyzer.js +1 -1
- package/lib/analyses/PathAnalyzer.d.ts +18 -3
- package/lib/analyses/PathAnalyzer.js +32 -0
- package/lib/analyses/PathAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectControllerAnalyzer.js +3 -2
- package/lib/analyses/ReflectControllerAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationAnalyzer.d.ts +1 -1
- package/lib/analyses/ReflectHttpOperationAnalyzer.js +1 -1
- package/lib/analyses/ReflectHttpOperationAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationResponseAnalyzer.d.ts +1 -1
- package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js +53 -20
- package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectMcpOperationAnalyzer.d.ts +14 -0
- package/lib/analyses/ReflectMcpOperationAnalyzer.js +79 -0
- package/lib/analyses/ReflectMcpOperationAnalyzer.js.map +1 -0
- package/lib/analyses/TypedMcpRouteAnalyzer.d.ts +9 -0
- package/lib/analyses/TypedMcpRouteAnalyzer.js +31 -0
- package/lib/analyses/TypedMcpRouteAnalyzer.js.map +1 -0
- package/lib/executable/internal/NestiaConfigLoader.js +5 -1
- package/lib/executable/internal/NestiaConfigLoader.js.map +1 -1
- package/lib/executable/internal/NestiaSdkCommand.js +30 -14
- package/lib/executable/internal/NestiaSdkCommand.js.map +1 -1
- package/lib/executable/internal/NestiaSdkWatcher.d.ts +10 -0
- package/lib/executable/internal/NestiaSdkWatcher.js +322 -0
- package/lib/executable/internal/NestiaSdkWatcher.js.map +1 -0
- package/lib/executable/sdk.js +12 -12
- package/lib/executable/sdk.js.map +1 -1
- package/lib/generates/CloneGenerator.js +4 -2
- package/lib/generates/CloneGenerator.js.map +1 -1
- package/lib/generates/SdkGenerator.js +50 -1
- package/lib/generates/SdkGenerator.js.map +1 -1
- package/lib/generates/SwaggerGenerator.js +18 -2
- package/lib/generates/SwaggerGenerator.js.map +1 -1
- package/lib/generates/internal/E2eFileProgrammer.js +3 -1
- package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
- package/lib/generates/internal/ImportDictionary.d.ts +1 -0
- package/lib/generates/internal/ImportDictionary.js +9 -4
- package/lib/generates/internal/ImportDictionary.js.map +1 -1
- package/lib/generates/internal/SdkAliasCollection.d.ts +2 -0
- package/lib/generates/internal/SdkAliasCollection.js +11 -2
- package/lib/generates/internal/SdkAliasCollection.js.map +1 -1
- package/lib/generates/internal/SdkDistributionComposer.d.ts +1 -0
- package/lib/generates/internal/SdkDistributionComposer.js +3 -0
- package/lib/generates/internal/SdkDistributionComposer.js.map +1 -1
- package/lib/generates/internal/SdkFileProgrammer.js +4 -1
- package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpCloneReferencer.d.ts +1 -1
- package/lib/generates/internal/SdkHttpCloneReferencer.js +42 -9
- package/lib/generates/internal/SdkHttpCloneReferencer.js.map +1 -1
- package/lib/generates/internal/SdkHttpFunctionProgrammer.js +3 -4
- package/lib/generates/internal/SdkHttpFunctionProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.js +2 -1
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpSimulationProgrammer.js +6 -3
- package/lib/generates/internal/SdkHttpSimulationProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkMcpRouteProgrammer.d.ts +15 -0
- package/lib/generates/internal/SdkMcpRouteProgrammer.js +148 -0
- package/lib/generates/internal/SdkMcpRouteProgrammer.js.map +1 -0
- package/lib/generates/internal/SdkRouteDirectory.d.ts +2 -1
- package/lib/generates/internal/SdkRouteDirectory.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketCloneProgrammer.d.ts +6 -0
- package/lib/generates/internal/SdkWebSocketCloneProgrammer.js +283 -0
- package/lib/generates/internal/SdkWebSocketCloneProgrammer.js.map +1 -0
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.js +11 -9
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.js.map +1 -1
- package/lib/generates/internal/SwaggerOperationParameterComposer.js +10 -2
- package/lib/generates/internal/SwaggerOperationParameterComposer.js.map +1 -1
- package/lib/generates/internal/SwaggerOperationResponseComposer.d.ts +1 -1
- package/lib/generates/internal/SwaggerOperationResponseComposer.js +6 -1
- package/lib/generates/internal/SwaggerOperationResponseComposer.js.map +1 -1
- package/lib/generates/internal/SwaggerReadonlyArrayEmender.d.ts +9 -0
- package/lib/generates/internal/SwaggerReadonlyArrayEmender.js +174 -0
- package/lib/generates/internal/SwaggerReadonlyArrayEmender.js.map +1 -0
- package/lib/structures/INestiaSdkInput.d.ts +9 -2
- package/lib/structures/IReflectController.d.ts +2 -1
- package/lib/structures/IReflectHttpOperationSuccess.d.ts +4 -2
- package/lib/structures/IReflectMcpOperation.d.ts +35 -0
- package/lib/structures/IReflectMcpOperation.js +3 -0
- package/lib/structures/IReflectMcpOperation.js.map +1 -0
- package/lib/structures/IReflectMcpOperationParameter.d.ts +19 -0
- package/lib/structures/IReflectMcpOperationParameter.js +3 -0
- package/lib/structures/IReflectMcpOperationParameter.js.map +1 -0
- package/lib/structures/ITypedApplication.d.ts +2 -1
- package/lib/structures/ITypedHttpRouteSuccess.d.ts +3 -1
- package/lib/structures/ITypedMcpRoute.d.ts +31 -0
- package/lib/structures/ITypedMcpRoute.js +3 -0
- package/lib/structures/ITypedMcpRoute.js.map +1 -0
- package/lib/utils/HttpResponseContentTypeUtil.d.ts +5 -0
- package/lib/utils/HttpResponseContentTypeUtil.js +22 -0
- package/lib/utils/HttpResponseContentTypeUtil.js.map +1 -0
- package/native/go.mod +52 -52
- package/native/go.sum +84 -54
- package/native/sdk/register.go +322 -165
- package/native/sdk/sdk.go +17 -17
- package/native/sdk/sdk_metadata_json.go +327 -327
- package/native/sdk/sdk_transform.go +1879 -1549
- package/package.json +11 -9
- package/src/INestiaConfig.ts +267 -267
- package/src/NestiaSdkApplication.ts +39 -8
- package/src/NestiaSwaggerComposer.ts +153 -142
- package/src/analyses/AccessorAnalyzer.ts +64 -67
- package/src/analyses/ConfigAnalyzer.ts +330 -330
- package/src/analyses/ImportAnalyzer.ts +92 -92
- package/src/analyses/PathAnalyzer.ts +130 -69
- package/src/analyses/ReflectControllerAnalyzer.ts +112 -105
- package/src/analyses/ReflectHttpOperationAnalyzer.ts +183 -183
- package/src/analyses/ReflectHttpOperationExceptionAnalyzer.ts +90 -90
- package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +350 -350
- package/src/analyses/ReflectHttpOperationResponseAnalyzer.ts +163 -130
- package/src/analyses/ReflectMcpOperationAnalyzer.ts +124 -0
- package/src/analyses/ReflectMetadataAnalyzer.ts +44 -44
- package/src/analyses/SecurityAnalyzer.ts +25 -25
- package/src/analyses/TypedMcpRouteAnalyzer.ts +34 -0
- package/src/decorators/OperationMetadata.ts +29 -29
- package/src/executable/internal/CommandParser.ts +15 -15
- package/src/executable/internal/NestiaConfigLoader.ts +451 -446
- package/src/executable/internal/NestiaSdkCommand.ts +124 -106
- package/src/executable/internal/NestiaSdkWatcher.ts +342 -0
- package/src/executable/sdk.ts +90 -88
- package/src/generates/CloneGenerator.ts +73 -66
- package/src/generates/E2eGenerator.ts +32 -32
- package/src/generates/SdkGenerator.ts +176 -118
- package/src/generates/SwaggerGenerator.ts +342 -310
- package/src/generates/internal/E2eFileProgrammer.ts +240 -233
- package/src/generates/internal/FilePrinter.ts +65 -65
- package/src/generates/internal/ImportDictionary.ts +209 -204
- package/src/generates/internal/SdkAliasCollection.ts +274 -261
- package/src/generates/internal/SdkDistributionComposer.ts +123 -116
- package/src/generates/internal/SdkFileProgrammer.ts +116 -112
- package/src/generates/internal/SdkHttpCloneProgrammer.ts +126 -126
- package/src/generates/internal/SdkHttpCloneReferencer.ts +131 -77
- package/src/generates/internal/SdkHttpFunctionProgrammer.ts +301 -301
- package/src/generates/internal/SdkHttpNamespaceProgrammer.ts +520 -510
- package/src/generates/internal/SdkHttpParameterProgrammer.ts +165 -165
- package/src/generates/internal/SdkHttpRouteProgrammer.ts +109 -109
- package/src/generates/internal/SdkHttpSimulationProgrammer.ts +331 -314
- package/src/generates/internal/SdkImportWizard.ts +62 -62
- package/src/generates/internal/SdkMcpRouteProgrammer.ts +452 -0
- package/src/generates/internal/SdkRouteDirectory.ts +21 -18
- package/src/generates/internal/SdkTypeTagProgrammer.ts +114 -114
- package/src/generates/internal/SdkWebSocketCloneProgrammer.ts +319 -0
- package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +389 -389
- package/src/generates/internal/SdkWebSocketParameterProgrammer.ts +89 -89
- package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +331 -323
- package/src/generates/internal/SwaggerDescriptionComposer.ts +64 -64
- package/src/generates/internal/SwaggerOperationComposer.ts +119 -119
- package/src/generates/internal/SwaggerOperationParameterComposer.ts +175 -162
- package/src/generates/internal/SwaggerOperationResponseComposer.ts +115 -110
- package/src/generates/internal/SwaggerReadonlyArrayEmender.ts +262 -0
- package/src/index.ts +4 -4
- package/src/internal/legacy.ts +492 -492
- package/src/module.ts +4 -4
- package/src/structures/INestiaProject.ts +10 -10
- package/src/structures/INestiaSdkInput.ts +27 -20
- package/src/structures/IOperationMetadata.ts +41 -41
- package/src/structures/IReflectController.ts +18 -15
- package/src/structures/IReflectHttpOperation.ts +26 -26
- package/src/structures/IReflectHttpOperationException.ts +18 -18
- package/src/structures/IReflectHttpOperationParameter.ts +79 -79
- package/src/structures/IReflectHttpOperationSuccess.ts +18 -21
- package/src/structures/IReflectImport.ts +6 -6
- package/src/structures/IReflectMcpOperation.ts +38 -0
- package/src/structures/IReflectMcpOperationParameter.ts +27 -0
- package/src/structures/IReflectOperationError.ts +26 -26
- package/src/structures/IReflectType.ts +4 -4
- package/src/structures/IReflectWebSocketOperation.ts +17 -17
- package/src/structures/ITypedApplication.ts +12 -11
- package/src/structures/ITypedHttpRoute.ts +41 -41
- package/src/structures/ITypedHttpRouteException.ts +15 -15
- package/src/structures/ITypedHttpRouteParameter.ts +41 -41
- package/src/structures/ITypedHttpRouteSuccess.ts +18 -22
- package/src/structures/ITypedMcpRoute.ts +33 -0
- package/src/structures/ITypedWebSocketRoute.ts +24 -24
- package/src/structures/ITypedWebSocketRouteParameter.ts +3 -3
- package/src/transform.ts +59 -59
- package/src/typings/get-function-location.d.ts +7 -7
- package/src/utils/ArrayUtil.ts +26 -26
- package/src/utils/EmittedJavaScriptPatcher.ts +88 -88
- package/src/utils/FileRetriever.ts +22 -22
- package/src/utils/HttpResponseContentTypeUtil.ts +30 -0
- package/src/utils/MapUtil.ts +14 -14
- package/src/utils/PathUtil.ts +10 -10
- package/src/utils/SourceFinder.ts +63 -63
- package/src/utils/StringUtil.ts +17 -17
- package/src/utils/TsConfigReader.ts +108 -108
- package/src/utils/TtscExecutor.ts +68 -68
- package/src/utils/VersioningStrategy.ts +28 -28
- package/src/validators/HttpHeadersValidator.ts +11 -11
- package/src/validators/HttpQueryValidator.ts +11 -11
- package/src/validators/TextPlainValidator.ts +17 -17
|
@@ -1,1549 +1,1879 @@
|
|
|
1
|
-
package sdk
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"encoding/json"
|
|
5
|
-
"fmt"
|
|
6
|
-
"os"
|
|
7
|
-
"path/filepath"
|
|
8
|
-
"regexp"
|
|
9
|
-
"sort"
|
|
10
|
-
"strings"
|
|
11
|
-
|
|
12
|
-
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
13
|
-
shimchecker "github.com/microsoft/typescript-go/shim/checker"
|
|
14
|
-
shimscanner "github.com/microsoft/typescript-go/shim/scanner"
|
|
15
|
-
"github.com/samchon/nestia/packages/core/native/plugin"
|
|
16
|
-
"github.com/samchon/nestia/packages/core/native/transform"
|
|
17
|
-
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
18
|
-
nativecontext "github.com/samchon/typia/packages/typia/native/core/context"
|
|
19
|
-
nativefactories "github.com/samchon/typia/packages/typia/native/core/factories"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
out
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
insert,
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
0,
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
"
|
|
262
|
-
"
|
|
263
|
-
"
|
|
264
|
-
"
|
|
265
|
-
"
|
|
266
|
-
"
|
|
267
|
-
"
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
"
|
|
277
|
-
"
|
|
278
|
-
"
|
|
279
|
-
"
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
text
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
text
|
|
320
|
-
text = strings.
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
"
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
"
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
"
|
|
583
|
-
"
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
"
|
|
623
|
-
"
|
|
624
|
-
"
|
|
625
|
-
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
"
|
|
642
|
-
"
|
|
643
|
-
"
|
|
644
|
-
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
"
|
|
680
|
-
"
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
"
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
//
|
|
693
|
-
//
|
|
694
|
-
//
|
|
695
|
-
//
|
|
696
|
-
|
|
697
|
-
metadataLiteral
|
|
698
|
-
metadataLiteral["
|
|
699
|
-
metadataLiteral["
|
|
700
|
-
|
|
701
|
-
//
|
|
702
|
-
//
|
|
703
|
-
//
|
|
704
|
-
//
|
|
705
|
-
//
|
|
706
|
-
//
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
"
|
|
713
|
-
|
|
714
|
-
"
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
//
|
|
723
|
-
//
|
|
724
|
-
//
|
|
725
|
-
// `
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
"
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
func
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
return
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
"
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
}
|
|
1341
|
-
}
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
}
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
ref
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
return
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
}
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
}
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
}
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
return
|
|
1467
|
-
}
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
}
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
}
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
}
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
}
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
}
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
}
|
|
1
|
+
package sdk
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"encoding/json"
|
|
5
|
+
"fmt"
|
|
6
|
+
"os"
|
|
7
|
+
"path/filepath"
|
|
8
|
+
"regexp"
|
|
9
|
+
"sort"
|
|
10
|
+
"strings"
|
|
11
|
+
|
|
12
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
13
|
+
shimchecker "github.com/microsoft/typescript-go/shim/checker"
|
|
14
|
+
shimscanner "github.com/microsoft/typescript-go/shim/scanner"
|
|
15
|
+
"github.com/samchon/nestia/packages/core/native/plugin"
|
|
16
|
+
"github.com/samchon/nestia/packages/core/native/transform"
|
|
17
|
+
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
18
|
+
nativecontext "github.com/samchon/typia/packages/typia/native/core/context"
|
|
19
|
+
nativefactories "github.com/samchon/typia/packages/typia/native/core/factories"
|
|
20
|
+
nativeiterate "github.com/samchon/typia/packages/typia/native/core/programmers/iterate"
|
|
21
|
+
nativejson "github.com/samchon/typia/packages/typia/native/core/programmers/json"
|
|
22
|
+
schemametadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
type nestiaSDKSite struct {
|
|
26
|
+
File *shimast.SourceFile
|
|
27
|
+
FilePath string
|
|
28
|
+
ClassName string
|
|
29
|
+
MethodName string
|
|
30
|
+
Method *shimast.Node
|
|
31
|
+
Metadata string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
type nestiaSDKBuildRewriteSet struct {
|
|
35
|
+
byPath map[string][]nestiaSDKSite
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
type nestiaSDKContext struct {
|
|
39
|
+
prog *driver.Program
|
|
40
|
+
collection *schemametadata.MetadataCollection
|
|
41
|
+
importsByFile map[string][]nestiaSDKImportInfo
|
|
42
|
+
schemaCache map[nestiaSDKSchemaCacheKey]any
|
|
43
|
+
schemaHits int
|
|
44
|
+
schemaMisses int
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type nestiaSDKSchemaCacheKey struct {
|
|
48
|
+
Type *shimchecker.Type
|
|
49
|
+
Text string
|
|
50
|
+
Escape bool
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
func newNestiaSDKContext(prog *driver.Program) *nestiaSDKContext {
|
|
54
|
+
return &nestiaSDKContext{
|
|
55
|
+
prog: prog,
|
|
56
|
+
collection: newNestiaSDKMetadataCollection(),
|
|
57
|
+
importsByFile: map[string][]nestiaSDKImportInfo{},
|
|
58
|
+
schemaCache: map[nestiaSDKSchemaCacheKey]any{},
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
func newNestiaSDKMetadataCollection() *schemametadata.MetadataCollection {
|
|
63
|
+
return schemametadata.NewMetadataCollection(
|
|
64
|
+
&schemametadata.MetadataCollection_IOptions{
|
|
65
|
+
Replace: schemametadata.MetadataCollection_replace,
|
|
66
|
+
},
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
func (ctx *nestiaSDKContext) imports(file *shimast.SourceFile) []nestiaSDKImportInfo {
|
|
71
|
+
if file == nil {
|
|
72
|
+
return nil
|
|
73
|
+
}
|
|
74
|
+
name := filepath.ToSlash(file.FileName())
|
|
75
|
+
if imports, ok := ctx.importsByFile[name]; ok {
|
|
76
|
+
return imports
|
|
77
|
+
}
|
|
78
|
+
imports := nestiaSDKAnalyzeImports(file)
|
|
79
|
+
ctx.importsByFile[name] = imports
|
|
80
|
+
return imports
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
func newNestiaSDKBuildRewriteSet() *nestiaSDKBuildRewriteSet {
|
|
84
|
+
return &nestiaSDKBuildRewriteSet{byPath: map[string][]nestiaSDKSite{}}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
func (rs *nestiaSDKBuildRewriteSet) Add(site nestiaSDKSite) {
|
|
88
|
+
if site.FilePath == "" {
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
path := filepath.ToSlash(site.FilePath)
|
|
92
|
+
rs.byPath[path] = append(rs.byPath[path], site)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
func (rs *nestiaSDKBuildRewriteSet) Len() int {
|
|
96
|
+
if rs == nil {
|
|
97
|
+
return 0
|
|
98
|
+
}
|
|
99
|
+
count := 0
|
|
100
|
+
for _, sites := range rs.byPath {
|
|
101
|
+
count += len(sites)
|
|
102
|
+
}
|
|
103
|
+
return count
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
func (rs *nestiaSDKBuildRewriteSet) Apply(outputName string, text string) (string, error) {
|
|
107
|
+
if rs == nil || len(rs.byPath) == 0 {
|
|
108
|
+
return text, nil
|
|
109
|
+
}
|
|
110
|
+
srcPath, ok := rs.findSourceForOutput(outputName)
|
|
111
|
+
if !ok {
|
|
112
|
+
return text, nil
|
|
113
|
+
}
|
|
114
|
+
out := text
|
|
115
|
+
out = insertSDKOperationMetadataDecorators(out, rs.byPath[srcPath])
|
|
116
|
+
return injectSDKOperationMetadataImport(out), nil
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
func (rs *nestiaSDKBuildRewriteSet) findSourceForOutput(outputName string) (string, bool) {
|
|
120
|
+
outSlash := strings.TrimSuffix(filepath.ToSlash(outputName), filepath.Ext(outputName))
|
|
121
|
+
for path := range rs.byPath {
|
|
122
|
+
srcStem := strings.TrimSuffix(filepath.ToSlash(path), filepath.Ext(path))
|
|
123
|
+
if transform.OutputMatchesSourceStem(outSlash, srcStem) {
|
|
124
|
+
return path, true
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return "", false
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
func collectNestiaSDKSourceRewriteMap(
|
|
131
|
+
prog *driver.Program,
|
|
132
|
+
plan plugin.Plan,
|
|
133
|
+
onlyFile string,
|
|
134
|
+
) (map[string][]transform.SourceRewrite, []transform.Diagnostic) {
|
|
135
|
+
if plan.SDK == false {
|
|
136
|
+
return map[string][]transform.SourceRewrite{}, nil
|
|
137
|
+
}
|
|
138
|
+
sites, diagnostics := collectNestiaSDKSites(prog)
|
|
139
|
+
rewrites := map[string][]transform.SourceRewrite{}
|
|
140
|
+
touched := map[string]bool{}
|
|
141
|
+
for _, site := range sites {
|
|
142
|
+
file := filepath.ToSlash(site.FilePath)
|
|
143
|
+
if onlyFile != "" && file != filepath.ToSlash(onlyFile) {
|
|
144
|
+
continue
|
|
145
|
+
}
|
|
146
|
+
source, ok := transform.SourceFileText(site.File)
|
|
147
|
+
if !ok {
|
|
148
|
+
diagnostics = append(diagnostics, nestiaSDKDiagnostic(site, "source text is unavailable"))
|
|
149
|
+
continue
|
|
150
|
+
}
|
|
151
|
+
insert := site.Method.Pos()
|
|
152
|
+
if decorators := site.Method.Decorators(); len(decorators) != 0 {
|
|
153
|
+
insert = decorators[0].Pos()
|
|
154
|
+
}
|
|
155
|
+
indent := sourceLineIndent(source, insert)
|
|
156
|
+
rewrites[file] = append(rewrites[file], transform.NewSourceRewrite(
|
|
157
|
+
insert,
|
|
158
|
+
insert,
|
|
159
|
+
"\n"+indent+"@__OperationMetadata.OperationMetadata("+site.Metadata+" as any)\n",
|
|
160
|
+
))
|
|
161
|
+
touched[file] = true
|
|
162
|
+
}
|
|
163
|
+
for file := range touched {
|
|
164
|
+
rewrites[file] = append(rewrites[file], transform.NewSourceRewrite(
|
|
165
|
+
0,
|
|
166
|
+
0,
|
|
167
|
+
"import * as __OperationMetadata from \"@nestia/sdk\";\n",
|
|
168
|
+
))
|
|
169
|
+
}
|
|
170
|
+
return rewrites, diagnostics
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
func collectNestiaSDKBuildRewrites(
|
|
174
|
+
prog *driver.Program,
|
|
175
|
+
plan plugin.Plan,
|
|
176
|
+
) (*nestiaSDKBuildRewriteSet, []transform.Diagnostic) {
|
|
177
|
+
set := newNestiaSDKBuildRewriteSet()
|
|
178
|
+
if plan.SDK == false {
|
|
179
|
+
return set, nil
|
|
180
|
+
}
|
|
181
|
+
sites, diagnostics := collectNestiaSDKSites(prog)
|
|
182
|
+
for _, site := range sites {
|
|
183
|
+
set.Add(site)
|
|
184
|
+
}
|
|
185
|
+
return set, diagnostics
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
func collectNestiaSDKSites(prog *driver.Program) ([]nestiaSDKSite, []transform.Diagnostic) {
|
|
189
|
+
sites := []nestiaSDKSite{}
|
|
190
|
+
diagnostics := []transform.Diagnostic{}
|
|
191
|
+
context := newNestiaSDKContext(prog)
|
|
192
|
+
for _, file := range prog.SourceFiles() {
|
|
193
|
+
if file == nil || file.IsDeclarationFile {
|
|
194
|
+
continue
|
|
195
|
+
}
|
|
196
|
+
visited := map[string]bool{}
|
|
197
|
+
file.ForEachChild(func(node *shimast.Node) bool {
|
|
198
|
+
visitNestiaSDKNode(context, file, node, visited, &sites, &diagnostics)
|
|
199
|
+
return false
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
if os.Getenv("TTSC_NESTIA_PROFILE") != "" {
|
|
203
|
+
fmt.Fprintf(stderr, "ttsc-nestia profile: sdk-schema-cache hits=%d misses=%d\n", context.schemaHits, context.schemaMisses)
|
|
204
|
+
}
|
|
205
|
+
return sites, diagnostics
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
func visitNestiaSDKNode(
|
|
209
|
+
context *nestiaSDKContext,
|
|
210
|
+
file *shimast.SourceFile,
|
|
211
|
+
node *shimast.Node,
|
|
212
|
+
visited map[string]bool,
|
|
213
|
+
sites *[]nestiaSDKSite,
|
|
214
|
+
diagnostics *[]transform.Diagnostic,
|
|
215
|
+
) {
|
|
216
|
+
if node == nil {
|
|
217
|
+
return
|
|
218
|
+
}
|
|
219
|
+
if node.Kind == shimast.KindMethodDeclaration && len(node.Decorators()) != 0 {
|
|
220
|
+
className := nestiaSDKParentClassName(node)
|
|
221
|
+
methodName := nestiaSDKMethodName(node)
|
|
222
|
+
if className != "" && methodName != "" {
|
|
223
|
+
key := className + "." + methodName
|
|
224
|
+
if visited[key] == false {
|
|
225
|
+
visited[key] = true
|
|
226
|
+
metadata, err := nestiaSDKMetadataText(context, file, node)
|
|
227
|
+
site := nestiaSDKSite{
|
|
228
|
+
File: file,
|
|
229
|
+
FilePath: file.FileName(),
|
|
230
|
+
ClassName: className,
|
|
231
|
+
MethodName: methodName,
|
|
232
|
+
Method: node,
|
|
233
|
+
Metadata: metadata,
|
|
234
|
+
}
|
|
235
|
+
if err != nil {
|
|
236
|
+
*diagnostics = append(*diagnostics, nestiaSDKDiagnostic(site, err.Error()))
|
|
237
|
+
} else {
|
|
238
|
+
*sites = append(*sites, site)
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
node.ForEachChild(func(child *shimast.Node) bool {
|
|
244
|
+
visitNestiaSDKNode(context, file, child, visited, sites, diagnostics)
|
|
245
|
+
return false
|
|
246
|
+
})
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
func nestiaSDKMetadataText(context *nestiaSDKContext, file *shimast.SourceFile, method *shimast.Node) (string, error) {
|
|
250
|
+
prog := context.prog
|
|
251
|
+
methodDecl := method.AsMethodDeclaration()
|
|
252
|
+
imports := context.imports(file)
|
|
253
|
+
doc := nestiaSDKMethodJSDoc(file, method)
|
|
254
|
+
parameters := []any{}
|
|
255
|
+
if methodDecl.Parameters != nil {
|
|
256
|
+
for index, param := range methodDecl.Parameters.Nodes {
|
|
257
|
+
typ := prog.Checker.GetTypeAtLocation(param)
|
|
258
|
+
name := nestiaSDKParameterName(param)
|
|
259
|
+
response := nestiaSDKResponse(context, imports, typ, nestiaSDKParameterTypeNode(param))
|
|
260
|
+
parameters = append(parameters, map[string]any{
|
|
261
|
+
"name": name,
|
|
262
|
+
"index": index,
|
|
263
|
+
"description": nestiaSDKNullableString(doc.Params[name]),
|
|
264
|
+
"jsDocTags": []any{},
|
|
265
|
+
"type": response["type"],
|
|
266
|
+
"imports": response["imports"],
|
|
267
|
+
"primitive": response["primitive"],
|
|
268
|
+
"resolved": response["resolved"],
|
|
269
|
+
})
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
returnType := transform.NestiaCoreMethodReturnType(prog, method)
|
|
273
|
+
returnTypeNode := nestiaSDKMethodReturnTypeNode(prog, method)
|
|
274
|
+
exceptions := nestiaSDKExceptionResponses(context, imports, method)
|
|
275
|
+
metadata := map[string]any{
|
|
276
|
+
"parameters": parameters,
|
|
277
|
+
"success": nestiaSDKResponse(context, imports, returnType, returnTypeNode),
|
|
278
|
+
"exceptions": exceptions,
|
|
279
|
+
"description": nestiaSDKNullableString(doc.Description),
|
|
280
|
+
"jsDocTags": doc.Tags,
|
|
281
|
+
}
|
|
282
|
+
return nestiaSDKMetadataLiteralText(metadata)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const nestiaSDKLiteralNull = "__NESTIA_LITERAL_NULL__"
|
|
286
|
+
|
|
287
|
+
func nestiaSDKMetadataLiteralText(metadata map[string]any) (string, error) {
|
|
288
|
+
data, err := json.Marshal(metadata)
|
|
289
|
+
if err != nil {
|
|
290
|
+
return "", err
|
|
291
|
+
}
|
|
292
|
+
text := string(data)
|
|
293
|
+
text = strings.ReplaceAll(text, `"`+nestiaSDKLiteralNull+`"`, "null")
|
|
294
|
+
return text, nil
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
type nestiaSDKJSDoc struct {
|
|
298
|
+
Description string
|
|
299
|
+
Tags []any
|
|
300
|
+
Params map[string]string
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
func nestiaSDKMethodJSDoc(file *shimast.SourceFile, method *shimast.Node) nestiaSDKJSDoc {
|
|
304
|
+
doc := nestiaSDKJSDoc{
|
|
305
|
+
Tags: []any{},
|
|
306
|
+
Params: map[string]string{},
|
|
307
|
+
}
|
|
308
|
+
source, ok := transform.SourceFileText(file)
|
|
309
|
+
if ok == false || method == nil {
|
|
310
|
+
return doc
|
|
311
|
+
}
|
|
312
|
+
comment := nestiaSDKLeadingJSDoc(source, method)
|
|
313
|
+
if comment == "" {
|
|
314
|
+
return doc
|
|
315
|
+
}
|
|
316
|
+
description := []string{}
|
|
317
|
+
inTags := false
|
|
318
|
+
for _, line := range strings.Split(comment, "\n") {
|
|
319
|
+
text := strings.TrimSpace(line)
|
|
320
|
+
text = strings.TrimPrefix(text, "*")
|
|
321
|
+
text = strings.TrimSpace(text)
|
|
322
|
+
if text == "" {
|
|
323
|
+
if inTags == false && len(description) != 0 {
|
|
324
|
+
description = append(description, "")
|
|
325
|
+
}
|
|
326
|
+
continue
|
|
327
|
+
}
|
|
328
|
+
if strings.HasPrefix(text, "@") {
|
|
329
|
+
inTags = true
|
|
330
|
+
name, body := nestiaSDKParseJSDocTag(text)
|
|
331
|
+
doc.Tags = append(doc.Tags, nestiaSDKJSDocTag(name, body))
|
|
332
|
+
if name == "param" {
|
|
333
|
+
param, desc := nestiaSDKParseParamTag(body)
|
|
334
|
+
if param != "" {
|
|
335
|
+
doc.Params[param] = desc
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
continue
|
|
339
|
+
}
|
|
340
|
+
if inTags == false {
|
|
341
|
+
description = append(description, text)
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
doc.Description = strings.TrimSpace(strings.Join(description, "\n"))
|
|
345
|
+
return doc
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
func nestiaSDKLeadingJSDoc(source string, method *shimast.Node) string {
|
|
349
|
+
positions := []int{method.Pos()}
|
|
350
|
+
if decorators := method.Decorators(); len(decorators) != 0 {
|
|
351
|
+
positions = append(positions, decorators[0].Pos())
|
|
352
|
+
}
|
|
353
|
+
for _, pos := range positions {
|
|
354
|
+
if pos < 0 || pos > len(source) {
|
|
355
|
+
continue
|
|
356
|
+
}
|
|
357
|
+
if comment := nestiaSDKJSDocAtOrBefore(source, pos); comment != "" {
|
|
358
|
+
return comment
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return ""
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
func nestiaSDKJSDocAtOrBefore(source string, pos int) string {
|
|
365
|
+
cursor := pos
|
|
366
|
+
for cursor < len(source) && (source[cursor] == ' ' || source[cursor] == '\t' || source[cursor] == '\r' || source[cursor] == '\n') {
|
|
367
|
+
cursor++
|
|
368
|
+
}
|
|
369
|
+
if strings.HasPrefix(source[cursor:], "/**") {
|
|
370
|
+
if end := strings.Index(source[cursor:], "*/"); end >= 0 {
|
|
371
|
+
return source[cursor+3 : cursor+end]
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
left := pos
|
|
375
|
+
for left > 0 && (source[left-1] == ' ' || source[left-1] == '\t' || source[left-1] == '\r' || source[left-1] == '\n') {
|
|
376
|
+
left--
|
|
377
|
+
}
|
|
378
|
+
if left < 2 || source[left-2:left] != "*/" {
|
|
379
|
+
return ""
|
|
380
|
+
}
|
|
381
|
+
start := strings.LastIndex(source[:left-2], "/**")
|
|
382
|
+
if start < 0 {
|
|
383
|
+
return ""
|
|
384
|
+
}
|
|
385
|
+
return source[start+3 : left-2]
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
func nestiaSDKParseJSDocTag(text string) (string, string) {
|
|
389
|
+
text = strings.TrimPrefix(text, "@")
|
|
390
|
+
parts := strings.Fields(text)
|
|
391
|
+
if len(parts) == 0 {
|
|
392
|
+
return "", ""
|
|
393
|
+
}
|
|
394
|
+
name := parts[0]
|
|
395
|
+
body := strings.TrimSpace(strings.TrimPrefix(text, name))
|
|
396
|
+
return name, body
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
func nestiaSDKParseParamTag(body string) (string, string) {
|
|
400
|
+
parts := strings.Fields(body)
|
|
401
|
+
if len(parts) == 0 {
|
|
402
|
+
return "", ""
|
|
403
|
+
}
|
|
404
|
+
param := parts[0]
|
|
405
|
+
desc := strings.TrimSpace(strings.TrimPrefix(body, param))
|
|
406
|
+
return param, desc
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
func nestiaSDKJSDocTag(name string, text string) map[string]any {
|
|
410
|
+
if text == "" {
|
|
411
|
+
return map[string]any{
|
|
412
|
+
"name": name,
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return map[string]any{
|
|
416
|
+
"name": name,
|
|
417
|
+
"text": []any{
|
|
418
|
+
map[string]any{
|
|
419
|
+
"text": text,
|
|
420
|
+
"kind": "text",
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
func nestiaSDKNullableString(value string) any {
|
|
427
|
+
value = strings.TrimSpace(value)
|
|
428
|
+
if value == "" {
|
|
429
|
+
return nestiaSDKLiteralNull
|
|
430
|
+
}
|
|
431
|
+
return value
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
func nestiaSDKExceptionResponses(
|
|
435
|
+
context *nestiaSDKContext,
|
|
436
|
+
imports []nestiaSDKImportInfo,
|
|
437
|
+
method *shimast.Node,
|
|
438
|
+
) []any {
|
|
439
|
+
prog := context.prog
|
|
440
|
+
responses := []any{}
|
|
441
|
+
for _, decorator := range method.Decorators() {
|
|
442
|
+
exception := nestiaSDKTypedExceptionInfo(prog, decorator)
|
|
443
|
+
if exception == nil {
|
|
444
|
+
continue
|
|
445
|
+
}
|
|
446
|
+
responses = append(responses, nestiaSDKResponse(context, imports, exception.Type, exception.Node))
|
|
447
|
+
}
|
|
448
|
+
return responses
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
type nestiaSDKTypedException struct {
|
|
452
|
+
Type *shimchecker.Type
|
|
453
|
+
Node *shimast.Node
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
func nestiaSDKTypedExceptionInfo(prog *driver.Program, decorator *shimast.Node) *nestiaSDKTypedException {
|
|
457
|
+
if decorator == nil || decorator.Kind != transform.NestiaCoreKindDecorator {
|
|
458
|
+
return nil
|
|
459
|
+
}
|
|
460
|
+
expression := decorator.AsDecorator().Expression
|
|
461
|
+
if expression == nil || expression.Kind != shimast.KindCallExpression {
|
|
462
|
+
return nil
|
|
463
|
+
}
|
|
464
|
+
call := expression.AsCallExpression()
|
|
465
|
+
segments := transform.NestiaCoreExpressionSegments(call.Expression)
|
|
466
|
+
if len(segments) == 0 || segments[len(segments)-1] != "TypedException" {
|
|
467
|
+
return nil
|
|
468
|
+
}
|
|
469
|
+
if transform.IsNestiaCoreCall(prog, expression) == false {
|
|
470
|
+
return nil
|
|
471
|
+
}
|
|
472
|
+
if call.TypeArguments == nil || len(call.TypeArguments.Nodes) != 1 {
|
|
473
|
+
return nil
|
|
474
|
+
}
|
|
475
|
+
node := call.TypeArguments.Nodes[0]
|
|
476
|
+
return &nestiaSDKTypedException{
|
|
477
|
+
Type: prog.Checker.GetTypeFromTypeNode(node),
|
|
478
|
+
Node: node,
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
type nestiaSDKImportInfo struct {
|
|
483
|
+
File string
|
|
484
|
+
Asterisk string
|
|
485
|
+
Default string
|
|
486
|
+
Elements []string
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
func nestiaSDKAnalyzeImports(file *shimast.SourceFile) []nestiaSDKImportInfo {
|
|
490
|
+
if file == nil || file.Statements == nil {
|
|
491
|
+
return nil
|
|
492
|
+
}
|
|
493
|
+
output := []nestiaSDKImportInfo{}
|
|
494
|
+
for _, stmt := range file.Statements.Nodes {
|
|
495
|
+
if stmt == nil || stmt.Kind != shimast.KindImportDeclaration {
|
|
496
|
+
continue
|
|
497
|
+
}
|
|
498
|
+
decl := stmt.AsImportDeclaration()
|
|
499
|
+
if decl == nil || decl.ImportClause == nil || decl.ModuleSpecifier == nil || decl.ModuleSpecifier.Kind != shimast.KindStringLiteral {
|
|
500
|
+
continue
|
|
501
|
+
}
|
|
502
|
+
clause := decl.ImportClause.AsImportClause()
|
|
503
|
+
if clause == nil {
|
|
504
|
+
continue
|
|
505
|
+
}
|
|
506
|
+
info := nestiaSDKImportInfo{
|
|
507
|
+
File: nestiaSDKNormalizeImportPath(file.FileName(), decl.ModuleSpecifier.Text()),
|
|
508
|
+
Elements: []string{},
|
|
509
|
+
}
|
|
510
|
+
if name := clause.Name(); name != nil {
|
|
511
|
+
info.Default = name.Text()
|
|
512
|
+
}
|
|
513
|
+
if clause.NamedBindings != nil {
|
|
514
|
+
if clause.NamedBindings.Kind == shimast.KindNamespaceImport {
|
|
515
|
+
if name := clause.NamedBindings.Name(); name != nil {
|
|
516
|
+
info.Asterisk = name.Text()
|
|
517
|
+
}
|
|
518
|
+
} else if clause.NamedBindings.Kind == shimast.KindNamedImports {
|
|
519
|
+
named := clause.NamedBindings.AsNamedImports()
|
|
520
|
+
if named != nil && named.Elements != nil {
|
|
521
|
+
for _, elem := range named.Elements.Nodes {
|
|
522
|
+
if elem == nil {
|
|
523
|
+
continue
|
|
524
|
+
}
|
|
525
|
+
spec := elem.AsImportSpecifier()
|
|
526
|
+
if spec == nil {
|
|
527
|
+
continue
|
|
528
|
+
}
|
|
529
|
+
if name := spec.Name(); name != nil {
|
|
530
|
+
info.Elements = append(info.Elements, name.Text())
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
output = append(output, info)
|
|
537
|
+
}
|
|
538
|
+
return output
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
func nestiaSDKNormalizeImportPath(fileName string, module string) string {
|
|
542
|
+
if strings.HasPrefix(module, ".") {
|
|
543
|
+
return filepath.ToSlash(filepath.Clean(filepath.Join(filepath.Dir(fileName), module)))
|
|
544
|
+
}
|
|
545
|
+
return filepath.ToSlash(filepath.Join("node_modules", module))
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
func nestiaSDKReflectImports(name string, imports []nestiaSDKImportInfo) []any {
|
|
549
|
+
prefixes := nestiaSDKTypePrefixes(name)
|
|
550
|
+
output := []any{}
|
|
551
|
+
seen := map[string]bool{}
|
|
552
|
+
for _, imp := range imports {
|
|
553
|
+
if nestiaSDKImportMatches(prefixes, imp) == false {
|
|
554
|
+
continue
|
|
555
|
+
}
|
|
556
|
+
item := nestiaSDKImportLiteral(imp, prefixes)
|
|
557
|
+
key := fmt.Sprintf("%v", item)
|
|
558
|
+
if seen[key] {
|
|
559
|
+
continue
|
|
560
|
+
}
|
|
561
|
+
seen[key] = true
|
|
562
|
+
output = append(output, item)
|
|
563
|
+
}
|
|
564
|
+
return output
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
func nestiaSDKTypePrefixes(name string) map[string]bool {
|
|
568
|
+
output := map[string]bool{}
|
|
569
|
+
re := regexp.MustCompile(`[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*`)
|
|
570
|
+
for _, match := range re.FindAllString(name, -1) {
|
|
571
|
+
prefix := strings.Split(match, ".")[0]
|
|
572
|
+
if nestiaSDKIsGlobalTypePrefix(prefix) == false {
|
|
573
|
+
output[prefix] = true
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
return output
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
func nestiaSDKIsGlobalTypePrefix(prefix string) bool {
|
|
580
|
+
switch prefix {
|
|
581
|
+
case "any", "unknown", "never", "void", "null", "undefined",
|
|
582
|
+
"string", "number", "boolean", "bigint", "symbol", "object",
|
|
583
|
+
"Array", "ReadonlyArray", "Promise", "Record", "Partial", "Pick", "Omit",
|
|
584
|
+
"Date", "File", "Blob", "Uint8Array", "ArrayBuffer", "Error":
|
|
585
|
+
return true
|
|
586
|
+
default:
|
|
587
|
+
return false
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
func nestiaSDKImportMatches(prefixes map[string]bool, imp nestiaSDKImportInfo) bool {
|
|
592
|
+
if imp.Default != "" && prefixes[imp.Default] {
|
|
593
|
+
return true
|
|
594
|
+
}
|
|
595
|
+
if imp.Asterisk != "" && prefixes[imp.Asterisk] {
|
|
596
|
+
return true
|
|
597
|
+
}
|
|
598
|
+
for _, elem := range imp.Elements {
|
|
599
|
+
if prefixes[elem] {
|
|
600
|
+
return true
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return false
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
func nestiaSDKImportLiteral(imp nestiaSDKImportInfo, prefixes map[string]bool) map[string]any {
|
|
607
|
+
elements := []string{}
|
|
608
|
+
for _, elem := range imp.Elements {
|
|
609
|
+
if prefixes[elem] {
|
|
610
|
+
elements = append(elements, elem)
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
asterisk := any(nestiaSDKLiteralNull)
|
|
614
|
+
if imp.Asterisk != "" && prefixes[imp.Asterisk] {
|
|
615
|
+
asterisk = imp.Asterisk
|
|
616
|
+
}
|
|
617
|
+
def := any(nestiaSDKLiteralNull)
|
|
618
|
+
if imp.Default != "" && prefixes[imp.Default] {
|
|
619
|
+
def = imp.Default
|
|
620
|
+
}
|
|
621
|
+
return map[string]any{
|
|
622
|
+
"file": imp.File,
|
|
623
|
+
"asterisk": asterisk,
|
|
624
|
+
"default": def,
|
|
625
|
+
"elements": elements,
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
func nestiaSDKResponse(
|
|
630
|
+
context *nestiaSDKContext,
|
|
631
|
+
imports []nestiaSDKImportInfo,
|
|
632
|
+
typ *shimchecker.Type,
|
|
633
|
+
typeNode *shimast.Node,
|
|
634
|
+
) map[string]any {
|
|
635
|
+
prog := context.prog
|
|
636
|
+
refType, refImports := nestiaSDKReflectType(prog, imports, typ, typeNode)
|
|
637
|
+
if refImports == nil {
|
|
638
|
+
refImports = []any{}
|
|
639
|
+
}
|
|
640
|
+
return map[string]any{
|
|
641
|
+
"type": refType,
|
|
642
|
+
"imports": refImports,
|
|
643
|
+
"primitive": nestiaSDKSchemaPipe(context, typ, typeNode, true),
|
|
644
|
+
"resolved": nestiaSDKSchemaPipe(context, typ, typeNode, false),
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
func nestiaSDKSchemaPipe(context *nestiaSDKContext, typ *shimchecker.Type, typeNode *shimast.Node, escape bool) any {
|
|
649
|
+
prog := context.prog
|
|
650
|
+
key := nestiaSDKSchemaCacheKey{
|
|
651
|
+
Type: typ,
|
|
652
|
+
Text: nestiaSDKTypeNodeText(typeNode),
|
|
653
|
+
Escape: escape,
|
|
654
|
+
}
|
|
655
|
+
if cached, ok := context.schemaCache[key]; ok {
|
|
656
|
+
context.schemaHits++
|
|
657
|
+
return cached
|
|
658
|
+
}
|
|
659
|
+
context.schemaMisses++
|
|
660
|
+
if nestiaSDKIsTypeGuardError(prog, typ, typeNode) {
|
|
661
|
+
value := nestiaSDKTypeGuardErrorSchemaPipe()
|
|
662
|
+
context.schemaCache[key] = value
|
|
663
|
+
return value
|
|
664
|
+
}
|
|
665
|
+
result := nativefactories.MetadataFactory.Analyze(nativefactories.MetadataFactory_IProps{
|
|
666
|
+
Checker: prog.Checker,
|
|
667
|
+
Options: nativefactories.MetadataFactory_IOptions{
|
|
668
|
+
Escape: escape,
|
|
669
|
+
Constant: true,
|
|
670
|
+
Absorb: true,
|
|
671
|
+
},
|
|
672
|
+
Components: context.collection,
|
|
673
|
+
Type: typ,
|
|
674
|
+
})
|
|
675
|
+
if result.Success == false {
|
|
676
|
+
errors := []any{}
|
|
677
|
+
for _, err := range result.Errors {
|
|
678
|
+
errors = append(errors, map[string]any{
|
|
679
|
+
"name": err.Name,
|
|
680
|
+
"accessor": nestiaSDKLiteralNull,
|
|
681
|
+
"messages": err.Messages,
|
|
682
|
+
})
|
|
683
|
+
}
|
|
684
|
+
failure := map[string]any{
|
|
685
|
+
"success": false,
|
|
686
|
+
"errors": errors,
|
|
687
|
+
}
|
|
688
|
+
context.schemaCache[key] = failure
|
|
689
|
+
return failure
|
|
690
|
+
}
|
|
691
|
+
nestiaSDKRestoreUnionOrder(typeNode, result.Data)
|
|
692
|
+
// Pre-bake the values that the legacy `@typia/core` 12.x `MetadataSchema`
|
|
693
|
+
// class exposed as runtime methods (.size(), .getName(), .empty()) and
|
|
694
|
+
// the OpenAPI 3.1 schema typia v13 only produces on the Go side. nestia
|
|
695
|
+
// reads them through the `packages/sdk/src/internal/legacy.ts` namespace
|
|
696
|
+
// utilities so no JS-side class wrapper or vendored package is needed.
|
|
697
|
+
metadataLiteral := nestiaSDKMetadataSchemaLiteral(result.Data.ToJSON()).(map[string]any)
|
|
698
|
+
metadataLiteral["size"] = result.Data.Size()
|
|
699
|
+
metadataLiteral["name"] = result.Data.GetName()
|
|
700
|
+
metadataLiteral["empty"] = result.Data.Empty()
|
|
701
|
+
// `JsonSchemasProgrammer.WriteSchemas` panics on metadata that has no
|
|
702
|
+
// JSON-schema representation (e.g. a `void` route return or a parameter
|
|
703
|
+
// whose only members are functions). The legacy reader on the JS side
|
|
704
|
+
// already treats a missing `jsonSchema` as "skip", so swallow the panic
|
|
705
|
+
// and omit the field — the sdk generator falls back to its own derived
|
|
706
|
+
// schema path. This must never mask a real bug, so re-raise anything we
|
|
707
|
+
// don't recognize as a transformer error from the typia runtime.
|
|
708
|
+
if baked := nestiaSDKTryBakeJsonSchema(prog, typeNode, result.Data); baked != nil {
|
|
709
|
+
metadataLiteral["jsonSchema"] = baked
|
|
710
|
+
}
|
|
711
|
+
value := map[string]any{
|
|
712
|
+
"success": true,
|
|
713
|
+
"data": map[string]any{
|
|
714
|
+
"components": nestiaSDKMetadataComponentsLiteral(nestiaSDKVisitedMetadataComponents(context.collection, result.Data)),
|
|
715
|
+
"metadata": metadataLiteral,
|
|
716
|
+
},
|
|
717
|
+
}
|
|
718
|
+
context.schemaCache[key] = value
|
|
719
|
+
return value
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
// nestiaSDKTryBakeJsonSchema runs `JsonSchemasProgrammer.WriteSchemas` for a
|
|
723
|
+
// single metadata and returns the OpenAPI 3.1 schema literal. Returns nil
|
|
724
|
+
// when typia signals the metadata has no JSON-schema representation (e.g.
|
|
725
|
+
// `void` returns, function-only types) — the JS-side reader handles missing
|
|
726
|
+
// `jsonSchema` fields. Any other panic is re-raised so real bugs surface.
|
|
727
|
+
func nestiaSDKTryBakeJsonSchema(
|
|
728
|
+
prog *driver.Program,
|
|
729
|
+
typeNode *shimast.Node,
|
|
730
|
+
metadata *schemametadata.MetadataSchema,
|
|
731
|
+
) (baked map[string]any) {
|
|
732
|
+
defer func() {
|
|
733
|
+
if r := recover(); r != nil {
|
|
734
|
+
if _, ok := r.(*nativecontext.TransformerError); ok {
|
|
735
|
+
baked = nil
|
|
736
|
+
return
|
|
737
|
+
}
|
|
738
|
+
panic(r)
|
|
739
|
+
}
|
|
740
|
+
}()
|
|
741
|
+
collection := nativejson.JsonSchemasProgrammer.WriteSchemas(struct {
|
|
742
|
+
Version string
|
|
743
|
+
Metadatas []*schemametadata.MetadataSchema
|
|
744
|
+
}{
|
|
745
|
+
Version: "3.1",
|
|
746
|
+
Metadatas: []*schemametadata.MetadataSchema{metadata},
|
|
747
|
+
})
|
|
748
|
+
if len(collection.Schemas) == 0 {
|
|
749
|
+
return nil
|
|
750
|
+
}
|
|
751
|
+
// `iterate.OpenApi_IComponents` has no JSON tags on its Schemas field,
|
|
752
|
+
// so default Go marshaling would emit `"Schemas"` (capital). The JS
|
|
753
|
+
// side reads `components.schemas`, so flatten to a plain map here.
|
|
754
|
+
componentsLiteral := map[string]any{"schemas": map[string]any{}}
|
|
755
|
+
if collection.Components != nil && collection.Components.Schemas != nil {
|
|
756
|
+
schemasLiteral := map[string]any{}
|
|
757
|
+
for key, val := range collection.Components.Schemas {
|
|
758
|
+
schemasLiteral[key] = map[string]any(val)
|
|
759
|
+
}
|
|
760
|
+
componentsLiteral["schemas"] = schemasLiteral
|
|
761
|
+
}
|
|
762
|
+
baked = map[string]any{
|
|
763
|
+
"version": collection.Version,
|
|
764
|
+
"components": componentsLiteral,
|
|
765
|
+
"schema": map[string]any(collection.Schemas[0]),
|
|
766
|
+
}
|
|
767
|
+
nestiaSDKMarkReadonlyArrayJsonSchema(prog, typeNode, baked)
|
|
768
|
+
return baked
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
func nestiaSDKMarkReadonlyArrayJsonSchema(prog *driver.Program, typeNode *shimast.Node, baked map[string]any) {
|
|
772
|
+
components, _ := baked["components"].(map[string]any)
|
|
773
|
+
schemas, _ := components["schemas"].(map[string]any)
|
|
774
|
+
schema := nestiaSDKSchemaMap(baked["schema"])
|
|
775
|
+
nestiaSDKMarkReadonlyArraySchemaNode(
|
|
776
|
+
prog,
|
|
777
|
+
typeNode,
|
|
778
|
+
schema,
|
|
779
|
+
schemas,
|
|
780
|
+
map[*shimast.Node]bool{},
|
|
781
|
+
)
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
func nestiaSDKMarkReadonlyArraySchemaNode(
|
|
785
|
+
prog *driver.Program,
|
|
786
|
+
typeNode *shimast.Node,
|
|
787
|
+
schema map[string]any,
|
|
788
|
+
components map[string]any,
|
|
789
|
+
visiting map[*shimast.Node]bool,
|
|
790
|
+
) {
|
|
791
|
+
if typeNode == nil || schema == nil {
|
|
792
|
+
return
|
|
793
|
+
}
|
|
794
|
+
if visiting[typeNode] {
|
|
795
|
+
return
|
|
796
|
+
}
|
|
797
|
+
visiting[typeNode] = true
|
|
798
|
+
defer delete(visiting, typeNode)
|
|
799
|
+
|
|
800
|
+
switch typeNode.Kind {
|
|
801
|
+
case shimast.KindArrayType:
|
|
802
|
+
child := nestiaSDKSchemaMap(schema["items"])
|
|
803
|
+
nestiaSDKMarkReadonlyArraySchemaNode(
|
|
804
|
+
prog,
|
|
805
|
+
typeNode.AsArrayTypeNode().ElementType,
|
|
806
|
+
child,
|
|
807
|
+
components,
|
|
808
|
+
visiting,
|
|
809
|
+
)
|
|
810
|
+
case shimast.KindTupleType:
|
|
811
|
+
tuple := typeNode.AsTupleTypeNode()
|
|
812
|
+
items := nestiaSDKSchemaList(schema["prefixItems"])
|
|
813
|
+
if tuple.Elements != nil {
|
|
814
|
+
for i, elem := range tuple.Elements.Nodes {
|
|
815
|
+
if i >= len(items) {
|
|
816
|
+
break
|
|
817
|
+
}
|
|
818
|
+
child := nestiaSDKSchemaMap(items[i])
|
|
819
|
+
nestiaSDKMarkReadonlyArraySchemaNode(prog, elem, child, components, visiting)
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
case shimast.KindParenthesizedType:
|
|
823
|
+
nestiaSDKMarkReadonlyArraySchemaNode(
|
|
824
|
+
prog,
|
|
825
|
+
typeNode.AsParenthesizedTypeNode().Type,
|
|
826
|
+
schema,
|
|
827
|
+
components,
|
|
828
|
+
visiting,
|
|
829
|
+
)
|
|
830
|
+
case shimast.KindTypeOperator:
|
|
831
|
+
operator := typeNode.AsTypeOperatorNode()
|
|
832
|
+
if nestiaSDKTypeOperatorPrefix(typeNode, operator.Type) == "readonly" &&
|
|
833
|
+
nestiaSDKReadonlyArrayOperand(operator.Type) {
|
|
834
|
+
schema["x-readonly-array"] = true
|
|
835
|
+
}
|
|
836
|
+
nestiaSDKMarkReadonlyArraySchemaNode(
|
|
837
|
+
prog,
|
|
838
|
+
operator.Type,
|
|
839
|
+
schema,
|
|
840
|
+
components,
|
|
841
|
+
visiting,
|
|
842
|
+
)
|
|
843
|
+
case shimast.KindTypeReference:
|
|
844
|
+
nestiaSDKMarkReadonlyArrayTypeReference(
|
|
845
|
+
prog,
|
|
846
|
+
typeNode,
|
|
847
|
+
schema,
|
|
848
|
+
components,
|
|
849
|
+
visiting,
|
|
850
|
+
)
|
|
851
|
+
case shimast.KindTypeLiteral:
|
|
852
|
+
nestiaSDKMarkReadonlyArrayTypeElements(
|
|
853
|
+
prog,
|
|
854
|
+
typeNode.AsTypeLiteralNode().Members,
|
|
855
|
+
schema,
|
|
856
|
+
components,
|
|
857
|
+
visiting,
|
|
858
|
+
)
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
func nestiaSDKMarkReadonlyArrayTypeReference(
|
|
863
|
+
prog *driver.Program,
|
|
864
|
+
typeNode *shimast.Node,
|
|
865
|
+
schema map[string]any,
|
|
866
|
+
components map[string]any,
|
|
867
|
+
visiting map[*shimast.Node]bool,
|
|
868
|
+
) {
|
|
869
|
+
ref := typeNode.AsTypeReferenceNode()
|
|
870
|
+
name := nestiaSDKEntityNameText(ref.TypeName)
|
|
871
|
+
if name == "ReadonlyArray" {
|
|
872
|
+
schema["x-readonly-array"] = true
|
|
873
|
+
}
|
|
874
|
+
if (name == "Array" || name == "ReadonlyArray") && ref.TypeArguments != nil &&
|
|
875
|
+
len(ref.TypeArguments.Nodes) != 0 {
|
|
876
|
+
child := nestiaSDKSchemaMap(schema["items"])
|
|
877
|
+
nestiaSDKMarkReadonlyArraySchemaNode(
|
|
878
|
+
prog,
|
|
879
|
+
ref.TypeArguments.Nodes[0],
|
|
880
|
+
child,
|
|
881
|
+
components,
|
|
882
|
+
visiting,
|
|
883
|
+
)
|
|
884
|
+
}
|
|
885
|
+
for _, decl := range nestiaSDKTypeReferenceDeclarations(prog, ref.TypeName) {
|
|
886
|
+
switch decl.Kind {
|
|
887
|
+
case shimast.KindInterfaceDeclaration:
|
|
888
|
+
target := nestiaSDKReferencedSchema(schema, components, name)
|
|
889
|
+
nestiaSDKMarkReadonlyArrayTypeElements(
|
|
890
|
+
prog,
|
|
891
|
+
decl.AsInterfaceDeclaration().Members,
|
|
892
|
+
target,
|
|
893
|
+
components,
|
|
894
|
+
visiting,
|
|
895
|
+
)
|
|
896
|
+
case shimast.KindTypeAliasDeclaration:
|
|
897
|
+
target := nestiaSDKReferencedSchema(schema, components, name)
|
|
898
|
+
nestiaSDKMarkReadonlyArraySchemaNode(
|
|
899
|
+
prog,
|
|
900
|
+
decl.AsTypeAliasDeclaration().Type,
|
|
901
|
+
target,
|
|
902
|
+
components,
|
|
903
|
+
visiting,
|
|
904
|
+
)
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
func nestiaSDKMarkReadonlyArrayTypeElements(
|
|
910
|
+
prog *driver.Program,
|
|
911
|
+
members *shimast.TypeElementList,
|
|
912
|
+
schema map[string]any,
|
|
913
|
+
components map[string]any,
|
|
914
|
+
visiting map[*shimast.Node]bool,
|
|
915
|
+
) {
|
|
916
|
+
if members == nil || schema == nil {
|
|
917
|
+
return
|
|
918
|
+
}
|
|
919
|
+
properties := nestiaSDKSchemaMap(schema["properties"])
|
|
920
|
+
if properties == nil {
|
|
921
|
+
return
|
|
922
|
+
}
|
|
923
|
+
for _, member := range members.Nodes {
|
|
924
|
+
if member == nil || member.Kind != shimast.KindPropertySignature {
|
|
925
|
+
continue
|
|
926
|
+
}
|
|
927
|
+
property := member.AsPropertySignatureDeclaration()
|
|
928
|
+
name := nestiaSDKSchemaPropertyName(property.Name())
|
|
929
|
+
child := nestiaSDKSchemaMap(properties[name])
|
|
930
|
+
nestiaSDKMarkReadonlyArraySchemaNode(
|
|
931
|
+
prog,
|
|
932
|
+
property.Type,
|
|
933
|
+
child,
|
|
934
|
+
components,
|
|
935
|
+
visiting,
|
|
936
|
+
)
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
func nestiaSDKTypeReferenceDeclarations(prog *driver.Program, node *shimast.Node) []*shimast.Node {
|
|
941
|
+
if prog == nil || prog.Checker == nil || node == nil {
|
|
942
|
+
return nil
|
|
943
|
+
}
|
|
944
|
+
symbol := prog.Checker.GetSymbolAtLocation(node)
|
|
945
|
+
if symbol == nil {
|
|
946
|
+
typ := prog.Checker.GetTypeFromTypeNode(node)
|
|
947
|
+
if typ != nil {
|
|
948
|
+
symbol = typ.Symbol()
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
if symbol == nil {
|
|
952
|
+
return nil
|
|
953
|
+
}
|
|
954
|
+
return symbol.Declarations
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
func nestiaSDKReferencedSchema(schema map[string]any, components map[string]any, name string) map[string]any {
|
|
958
|
+
ref, _ := schema["$ref"].(string)
|
|
959
|
+
if ref == "" {
|
|
960
|
+
return schema
|
|
961
|
+
}
|
|
962
|
+
const prefix = "#/components/schemas/"
|
|
963
|
+
if strings.HasPrefix(ref, prefix) {
|
|
964
|
+
name = strings.TrimPrefix(ref, prefix)
|
|
965
|
+
}
|
|
966
|
+
target := nestiaSDKSchemaMap(components[name])
|
|
967
|
+
if target != nil {
|
|
968
|
+
return target
|
|
969
|
+
}
|
|
970
|
+
return schema
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
func nestiaSDKSchemaMap(input any) map[string]any {
|
|
974
|
+
switch value := input.(type) {
|
|
975
|
+
case map[string]any:
|
|
976
|
+
return value
|
|
977
|
+
case nativeiterate.JsonSchema:
|
|
978
|
+
return map[string]any(value)
|
|
979
|
+
default:
|
|
980
|
+
return nil
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
func nestiaSDKSchemaList(input any) []any {
|
|
985
|
+
switch value := input.(type) {
|
|
986
|
+
case []any:
|
|
987
|
+
return value
|
|
988
|
+
case []nativeiterate.JsonSchema:
|
|
989
|
+
output := make([]any, len(value))
|
|
990
|
+
for i, elem := range value {
|
|
991
|
+
output[i] = elem
|
|
992
|
+
}
|
|
993
|
+
return output
|
|
994
|
+
default:
|
|
995
|
+
return nil
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
func nestiaSDKReadonlyArrayOperand(node *shimast.Node) bool {
|
|
1000
|
+
if node == nil {
|
|
1001
|
+
return false
|
|
1002
|
+
}
|
|
1003
|
+
switch node.Kind {
|
|
1004
|
+
case shimast.KindArrayType, shimast.KindTupleType:
|
|
1005
|
+
return true
|
|
1006
|
+
case shimast.KindTypeReference:
|
|
1007
|
+
return nestiaSDKEntityNameText(node.AsTypeReferenceNode().TypeName) == "Array"
|
|
1008
|
+
case shimast.KindParenthesizedType:
|
|
1009
|
+
return nestiaSDKReadonlyArrayOperand(node.AsParenthesizedTypeNode().Type)
|
|
1010
|
+
default:
|
|
1011
|
+
return false
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
func nestiaSDKSchemaPropertyName(node *shimast.Node) string {
|
|
1016
|
+
text := nestiaSDKTypeNodeText(node)
|
|
1017
|
+
return strings.Trim(text, "\"'")
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
func nestiaSDKRestoreUnionOrder(typeNode *shimast.Node, metadata *schemametadata.MetadataSchema) {
|
|
1021
|
+
if typeNode == nil || metadata == nil || typeNode.Kind != shimast.KindUnionType {
|
|
1022
|
+
return
|
|
1023
|
+
}
|
|
1024
|
+
types := typeNode.AsUnionTypeNode().Types
|
|
1025
|
+
if types == nil || len(types.Nodes) == 0 {
|
|
1026
|
+
return
|
|
1027
|
+
}
|
|
1028
|
+
order := map[string]int{}
|
|
1029
|
+
for index, child := range types.Nodes {
|
|
1030
|
+
for _, name := range nestiaSDKUnionTypeNames(child) {
|
|
1031
|
+
if _, ok := order[name]; ok == false {
|
|
1032
|
+
order[name] = index
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
if len(order) == 0 {
|
|
1037
|
+
return
|
|
1038
|
+
}
|
|
1039
|
+
sort.SliceStable(metadata.Objects, func(i, j int) bool {
|
|
1040
|
+
return nestiaSDKUnionRank(order, metadata.Objects[i].Type.Name) < nestiaSDKUnionRank(order, metadata.Objects[j].Type.Name)
|
|
1041
|
+
})
|
|
1042
|
+
sort.SliceStable(metadata.Aliases, func(i, j int) bool {
|
|
1043
|
+
return nestiaSDKUnionRank(order, metadata.Aliases[i].Type.Name) < nestiaSDKUnionRank(order, metadata.Aliases[j].Type.Name)
|
|
1044
|
+
})
|
|
1045
|
+
sort.SliceStable(metadata.Arrays, func(i, j int) bool {
|
|
1046
|
+
return nestiaSDKUnionRank(order, metadata.Arrays[i].Type.Name) < nestiaSDKUnionRank(order, metadata.Arrays[j].Type.Name)
|
|
1047
|
+
})
|
|
1048
|
+
sort.SliceStable(metadata.Tuples, func(i, j int) bool {
|
|
1049
|
+
return nestiaSDKUnionRank(order, metadata.Tuples[i].Type.Name) < nestiaSDKUnionRank(order, metadata.Tuples[j].Type.Name)
|
|
1050
|
+
})
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
func nestiaSDKVisitedMetadataComponents(
|
|
1054
|
+
collection *schemametadata.MetadataCollection,
|
|
1055
|
+
metadata *schemametadata.MetadataSchema,
|
|
1056
|
+
) schemametadata.IMetadataComponents {
|
|
1057
|
+
visited := map[string]bool{}
|
|
1058
|
+
nestiaSDKVisitMetadataSchema(metadata, visited, map[*schemametadata.MetadataSchema]bool{})
|
|
1059
|
+
filtered := schemametadata.IMetadataComponents{
|
|
1060
|
+
Objects: []schemametadata.IMetadataSchema_IObjectType{},
|
|
1061
|
+
Aliases: []schemametadata.IMetadataSchema_IAliasType{},
|
|
1062
|
+
Arrays: []schemametadata.IMetadataSchema_IArrayType{},
|
|
1063
|
+
Tuples: []schemametadata.IMetadataSchema_ITupleType{},
|
|
1064
|
+
}
|
|
1065
|
+
for _, obj := range collection.Objects() {
|
|
1066
|
+
if obj != nil && visited[obj.Name] {
|
|
1067
|
+
filtered.Objects = append(filtered.Objects, obj.ToJSON())
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
for _, alias := range collection.Aliases() {
|
|
1071
|
+
if alias != nil && visited[alias.Name] {
|
|
1072
|
+
filtered.Aliases = append(filtered.Aliases, alias.ToJSON())
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
for _, array := range collection.Arrays() {
|
|
1076
|
+
if array != nil && visited[array.Name] {
|
|
1077
|
+
filtered.Arrays = append(filtered.Arrays, array.ToJSON())
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
for _, tuple := range collection.Tuples() {
|
|
1081
|
+
if tuple != nil && visited[tuple.Name] {
|
|
1082
|
+
filtered.Tuples = append(filtered.Tuples, tuple.ToJSON())
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
return filtered
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
func nestiaSDKVisitMetadataSchema(
|
|
1089
|
+
metadata *schemametadata.MetadataSchema,
|
|
1090
|
+
visited map[string]bool,
|
|
1091
|
+
seen map[*schemametadata.MetadataSchema]bool,
|
|
1092
|
+
) {
|
|
1093
|
+
if metadata == nil || seen[metadata] {
|
|
1094
|
+
return
|
|
1095
|
+
}
|
|
1096
|
+
seen[metadata] = true
|
|
1097
|
+
if metadata.Escaped != nil {
|
|
1098
|
+
nestiaSDKVisitMetadataSchema(metadata.Escaped.Original, visited, seen)
|
|
1099
|
+
nestiaSDKVisitMetadataSchema(metadata.Escaped.Returns, visited, seen)
|
|
1100
|
+
}
|
|
1101
|
+
if metadata.Rest != nil {
|
|
1102
|
+
nestiaSDKVisitMetadataSchema(metadata.Rest, visited, seen)
|
|
1103
|
+
}
|
|
1104
|
+
for _, alias := range metadata.Aliases {
|
|
1105
|
+
if alias.Type != nil {
|
|
1106
|
+
visited[alias.Type.Name] = true
|
|
1107
|
+
nestiaSDKVisitMetadataSchema(alias.Type.Value, visited, seen)
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
for _, array := range metadata.Arrays {
|
|
1111
|
+
if array.Type != nil {
|
|
1112
|
+
visited[array.Type.Name] = true
|
|
1113
|
+
nestiaSDKVisitMetadataSchema(array.Type.Value, visited, seen)
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
for _, tuple := range metadata.Tuples {
|
|
1117
|
+
if tuple.Type != nil {
|
|
1118
|
+
visited[tuple.Type.Name] = true
|
|
1119
|
+
for _, elem := range tuple.Type.Elements {
|
|
1120
|
+
nestiaSDKVisitMetadataSchema(elem, visited, seen)
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
for _, object := range metadata.Objects {
|
|
1125
|
+
if object.Type != nil {
|
|
1126
|
+
visited[object.Type.Name] = true
|
|
1127
|
+
for _, prop := range object.Type.Properties {
|
|
1128
|
+
if prop == nil {
|
|
1129
|
+
continue
|
|
1130
|
+
}
|
|
1131
|
+
nestiaSDKVisitMetadataSchema(prop.Key, visited, seen)
|
|
1132
|
+
nestiaSDKVisitMetadataSchema(prop.Value, visited, seen)
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
for _, set := range metadata.Sets {
|
|
1137
|
+
nestiaSDKVisitMetadataSchema(set.Value, visited, seen)
|
|
1138
|
+
}
|
|
1139
|
+
for _, item := range metadata.Maps {
|
|
1140
|
+
nestiaSDKVisitMetadataSchema(item.Key, visited, seen)
|
|
1141
|
+
nestiaSDKVisitMetadataSchema(item.Value, visited, seen)
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
func nestiaSDKUnionTypeNames(node *shimast.Node) []string {
|
|
1146
|
+
if node == nil {
|
|
1147
|
+
return nil
|
|
1148
|
+
}
|
|
1149
|
+
names := []string{}
|
|
1150
|
+
add := func(name string) {
|
|
1151
|
+
name = strings.TrimSpace(name)
|
|
1152
|
+
if name != "" {
|
|
1153
|
+
names = append(names, name)
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
add(nestiaSDKTypeNodeText(node))
|
|
1157
|
+
if node.Kind == shimast.KindTypeReference {
|
|
1158
|
+
add(nestiaSDKEntityNameText(node.AsTypeReferenceNode().TypeName))
|
|
1159
|
+
}
|
|
1160
|
+
return names
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
func nestiaSDKUnionRank(order map[string]int, name string) int {
|
|
1164
|
+
if index, ok := order[name]; ok {
|
|
1165
|
+
return index
|
|
1166
|
+
}
|
|
1167
|
+
return len(order)
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
func nestiaSDKIsTypeGuardError(prog *driver.Program, typ *shimchecker.Type, typeNode *shimast.Node) bool {
|
|
1171
|
+
if typeNode != nil {
|
|
1172
|
+
name := nestiaSDKTypeNodeText(typeNode)
|
|
1173
|
+
if name == "TypeGuardError" || strings.HasPrefix(name, "TypeGuardError<") {
|
|
1174
|
+
return true
|
|
1175
|
+
}
|
|
1176
|
+
if typeNode.Kind == shimast.KindTypeReference {
|
|
1177
|
+
ref := typeNode.AsTypeReferenceNode()
|
|
1178
|
+
name = nestiaSDKEntityNameText(ref.TypeName)
|
|
1179
|
+
if name == "TypeGuardError" {
|
|
1180
|
+
return true
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
if prog != nil && prog.Checker != nil && typ != nil {
|
|
1185
|
+
name := prog.Checker.TypeToString(typ)
|
|
1186
|
+
return name == "TypeGuardError" || strings.HasPrefix(name, "TypeGuardError<")
|
|
1187
|
+
}
|
|
1188
|
+
return false
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
func nestiaSDKTypeGuardErrorSchemaPipe() any {
|
|
1192
|
+
// Synthetic metadata for `TypeGuardError` exception responses — does not
|
|
1193
|
+
// flow through `nestiaSDKSchemaPipe`, so the pre-baked fields legacy.ts
|
|
1194
|
+
// reads (size/name/empty/jsonSchema) have to be filled by hand.
|
|
1195
|
+
metadata := nestiaSDKObjectReferenceSchema("TypeGuardErrorany")
|
|
1196
|
+
metadata["size"] = 1
|
|
1197
|
+
metadata["name"] = "TypeGuardErrorany"
|
|
1198
|
+
metadata["empty"] = false
|
|
1199
|
+
metadata["jsonSchema"] = map[string]any{
|
|
1200
|
+
"version": "3.1",
|
|
1201
|
+
"components": map[string]any{
|
|
1202
|
+
"schemas": map[string]any{
|
|
1203
|
+
"TypeGuardErrorany": map[string]any{
|
|
1204
|
+
"type": "object",
|
|
1205
|
+
"additionalProperties": false,
|
|
1206
|
+
"required": []any{"name", "method", "expected", "value"},
|
|
1207
|
+
"properties": map[string]any{
|
|
1208
|
+
"name": map[string]any{"type": "string"},
|
|
1209
|
+
"method": map[string]any{"type": "string"},
|
|
1210
|
+
"path": map[string]any{"type": "string"},
|
|
1211
|
+
"expected": map[string]any{"type": "string"},
|
|
1212
|
+
"value": map[string]any{},
|
|
1213
|
+
"description": map[string]any{"type": "string"},
|
|
1214
|
+
"message": map[string]any{"type": "string"},
|
|
1215
|
+
},
|
|
1216
|
+
},
|
|
1217
|
+
},
|
|
1218
|
+
},
|
|
1219
|
+
"schema": map[string]any{
|
|
1220
|
+
"$ref": "#/components/schemas/TypeGuardErrorany",
|
|
1221
|
+
},
|
|
1222
|
+
}
|
|
1223
|
+
return map[string]any{
|
|
1224
|
+
"success": true,
|
|
1225
|
+
"data": map[string]any{
|
|
1226
|
+
"components": map[string]any{
|
|
1227
|
+
"aliases": []any{},
|
|
1228
|
+
"arrays": []any{},
|
|
1229
|
+
"objects": []any{
|
|
1230
|
+
map[string]any{
|
|
1231
|
+
"description": nil,
|
|
1232
|
+
"index": 0,
|
|
1233
|
+
"jsDocTags": []any{},
|
|
1234
|
+
"name": "TypeGuardErrorany",
|
|
1235
|
+
"nullables": []any{false},
|
|
1236
|
+
"recursive": false,
|
|
1237
|
+
"properties": []any{
|
|
1238
|
+
nestiaSDKTypeGuardErrorProperty("name", nestiaSDKAtomicSchema("string", true)),
|
|
1239
|
+
nestiaSDKTypeGuardErrorProperty("method", nestiaSDKAtomicSchema("string", true)),
|
|
1240
|
+
nestiaSDKTypeGuardErrorProperty("path", nestiaSDKAtomicSchema("string", false)),
|
|
1241
|
+
nestiaSDKTypeGuardErrorProperty("expected", nestiaSDKAtomicSchema("string", true)),
|
|
1242
|
+
nestiaSDKTypeGuardErrorProperty("value", nestiaSDKAnySchema(true)),
|
|
1243
|
+
nestiaSDKTypeGuardErrorProperty("description", nestiaSDKAtomicSchema("string", false)),
|
|
1244
|
+
nestiaSDKTypeGuardErrorProperty("message", nestiaSDKAtomicSchema("string", false)),
|
|
1245
|
+
},
|
|
1246
|
+
},
|
|
1247
|
+
},
|
|
1248
|
+
"tuples": []any{},
|
|
1249
|
+
},
|
|
1250
|
+
"metadata": metadata,
|
|
1251
|
+
},
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
func nestiaSDKTypeGuardErrorProperty(key string, value map[string]any) map[string]any {
|
|
1256
|
+
return map[string]any{
|
|
1257
|
+
"description": nil,
|
|
1258
|
+
"jsDocTags": []any{},
|
|
1259
|
+
"key": nestiaSDKStringConstantSchema(key),
|
|
1260
|
+
"mutability": nil,
|
|
1261
|
+
"value": value,
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
func nestiaSDKStringConstantSchema(value string) map[string]any {
|
|
1266
|
+
schema := nestiaSDKBaseSchema(true)
|
|
1267
|
+
schema["constants"] = []any{
|
|
1268
|
+
map[string]any{
|
|
1269
|
+
"type": "string",
|
|
1270
|
+
"values": []any{
|
|
1271
|
+
map[string]any{
|
|
1272
|
+
"description": nil,
|
|
1273
|
+
"jsDocTags": []any{},
|
|
1274
|
+
"tags": []any{},
|
|
1275
|
+
"value": value,
|
|
1276
|
+
},
|
|
1277
|
+
},
|
|
1278
|
+
},
|
|
1279
|
+
}
|
|
1280
|
+
return schema
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
func nestiaSDKAtomicSchema(kind string, required bool) map[string]any {
|
|
1284
|
+
schema := nestiaSDKBaseSchema(required)
|
|
1285
|
+
schema["atomics"] = []any{
|
|
1286
|
+
map[string]any{
|
|
1287
|
+
"type": kind,
|
|
1288
|
+
"tags": []any{},
|
|
1289
|
+
},
|
|
1290
|
+
}
|
|
1291
|
+
return schema
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
func nestiaSDKAnySchema(required bool) map[string]any {
|
|
1295
|
+
schema := nestiaSDKBaseSchema(required)
|
|
1296
|
+
schema["any"] = true
|
|
1297
|
+
return schema
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
func nestiaSDKObjectReferenceSchema(name string) map[string]any {
|
|
1301
|
+
schema := nestiaSDKBaseSchema(true)
|
|
1302
|
+
schema["objects"] = []any{
|
|
1303
|
+
map[string]any{
|
|
1304
|
+
"name": name,
|
|
1305
|
+
"tags": []any{},
|
|
1306
|
+
},
|
|
1307
|
+
}
|
|
1308
|
+
return schema
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
func nestiaSDKBaseSchema(required bool) map[string]any {
|
|
1312
|
+
return map[string]any{
|
|
1313
|
+
"aliases": []any{},
|
|
1314
|
+
"any": false,
|
|
1315
|
+
"arrays": []any{},
|
|
1316
|
+
"atomics": []any{},
|
|
1317
|
+
"constants": []any{},
|
|
1318
|
+
"escaped": nil,
|
|
1319
|
+
"functions": []any{},
|
|
1320
|
+
"maps": []any{},
|
|
1321
|
+
"natives": []any{},
|
|
1322
|
+
"nullable": false,
|
|
1323
|
+
"objects": []any{},
|
|
1324
|
+
"optional": !required,
|
|
1325
|
+
"required": required,
|
|
1326
|
+
"rest": nil,
|
|
1327
|
+
"sets": []any{},
|
|
1328
|
+
"templates": []any{},
|
|
1329
|
+
"tuples": []any{},
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
func nestiaSDKReflectType(
|
|
1334
|
+
prog *driver.Program,
|
|
1335
|
+
imports []nestiaSDKImportInfo,
|
|
1336
|
+
typ *shimchecker.Type,
|
|
1337
|
+
typeNode *shimast.Node,
|
|
1338
|
+
) (map[string]any, []any) {
|
|
1339
|
+
if typeNode == nil {
|
|
1340
|
+
return map[string]any{"name": "__type"}, []any{}
|
|
1341
|
+
}
|
|
1342
|
+
if typeNode != nil {
|
|
1343
|
+
if ref, refs, ok := nestiaSDKReflectTypeNode(prog, imports, typeNode); ok {
|
|
1344
|
+
return ref, refs
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
name := ""
|
|
1348
|
+
if typeNode != nil {
|
|
1349
|
+
name = nestiaSDKTypeNodeText(typeNode)
|
|
1350
|
+
}
|
|
1351
|
+
if name == "" {
|
|
1352
|
+
name = "any"
|
|
1353
|
+
}
|
|
1354
|
+
if name == "any" && prog != nil && prog.Checker != nil && typ != nil {
|
|
1355
|
+
name = prog.Checker.TypeToString(typ)
|
|
1356
|
+
}
|
|
1357
|
+
return map[string]any{"name": name}, nestiaSDKReflectImports(name, imports)
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
func nestiaSDKReflectTypeNode(
|
|
1361
|
+
prog *driver.Program,
|
|
1362
|
+
imports []nestiaSDKImportInfo,
|
|
1363
|
+
node *shimast.Node,
|
|
1364
|
+
) (map[string]any, []any, bool) {
|
|
1365
|
+
if node == nil {
|
|
1366
|
+
return nil, nil, false
|
|
1367
|
+
}
|
|
1368
|
+
switch node.Kind {
|
|
1369
|
+
case shimast.KindIntersectionType:
|
|
1370
|
+
ref, refs := nestiaSDKReflectJoinedTypeNode(prog, imports, node.AsIntersectionTypeNode().Types, " & ")
|
|
1371
|
+
return ref, refs, true
|
|
1372
|
+
case shimast.KindUnionType:
|
|
1373
|
+
ref, refs := nestiaSDKReflectJoinedTypeNode(prog, imports, node.AsUnionTypeNode().Types, " | ")
|
|
1374
|
+
return ref, refs, true
|
|
1375
|
+
case shimast.KindArrayType:
|
|
1376
|
+
element, refs, ok := nestiaSDKReflectTypeNode(prog, imports, node.AsArrayTypeNode().ElementType)
|
|
1377
|
+
if ok == false {
|
|
1378
|
+
element = map[string]any{"name": nestiaSDKTypeNodeText(node.AsArrayTypeNode().ElementType)}
|
|
1379
|
+
refs = nestiaSDKReflectImports(element["name"].(string), imports)
|
|
1380
|
+
}
|
|
1381
|
+
return map[string]any{
|
|
1382
|
+
"name": "Array",
|
|
1383
|
+
"typeArguments": []any{element},
|
|
1384
|
+
}, refs, true
|
|
1385
|
+
case shimast.KindParenthesizedType:
|
|
1386
|
+
child, refs, ok := nestiaSDKReflectTypeNode(prog, imports, node.AsParenthesizedTypeNode().Type)
|
|
1387
|
+
if ok == false {
|
|
1388
|
+
child = map[string]any{"name": nestiaSDKTypeNodeText(node.AsParenthesizedTypeNode().Type)}
|
|
1389
|
+
refs = nestiaSDKReflectImports(child["name"].(string), imports)
|
|
1390
|
+
}
|
|
1391
|
+
name, _ := child["name"].(string)
|
|
1392
|
+
return map[string]any{"name": "(" + name + ")"}, refs, true
|
|
1393
|
+
case shimast.KindTypeOperator:
|
|
1394
|
+
operator := node.AsTypeOperatorNode()
|
|
1395
|
+
prefix := nestiaSDKTypeOperatorPrefix(node, operator.Type)
|
|
1396
|
+
if prefix == "" {
|
|
1397
|
+
return nil, nil, false
|
|
1398
|
+
}
|
|
1399
|
+
child, refs, ok := nestiaSDKReflectTypeNode(prog, imports, operator.Type)
|
|
1400
|
+
if ok == false {
|
|
1401
|
+
child = map[string]any{"name": nestiaSDKTypeNodeText(operator.Type)}
|
|
1402
|
+
refs = nestiaSDKReflectImports(child["name"].(string), imports)
|
|
1403
|
+
}
|
|
1404
|
+
name, _ := child["name"].(string)
|
|
1405
|
+
return map[string]any{"name": prefix + " " + name}, refs, true
|
|
1406
|
+
case shimast.KindTypeQuery:
|
|
1407
|
+
return nil, nil, false
|
|
1408
|
+
case shimast.KindTypeReference:
|
|
1409
|
+
ref := node.AsTypeReferenceNode()
|
|
1410
|
+
name := nestiaSDKEntityNameText(ref.TypeName)
|
|
1411
|
+
rootRefs := nestiaSDKReflectImports(name, imports)
|
|
1412
|
+
if len(rootRefs) == 0 && nestiaSDKIsAsyncReturnWrapper(prog, ref.TypeName, name) == false {
|
|
1413
|
+
rootRefs = nestiaSDKReflectTypeReferenceSymbolImport(prog, ref.TypeName, name)
|
|
1414
|
+
}
|
|
1415
|
+
if ref.TypeArguments != nil && len(ref.TypeArguments.Nodes) != 0 {
|
|
1416
|
+
if nestiaSDKIsAsyncReturnWrapper(prog, ref.TypeName, name) && len(ref.TypeArguments.Nodes) == 1 {
|
|
1417
|
+
return nestiaSDKReflectTypeNode(prog, imports, ref.TypeArguments.Nodes[0])
|
|
1418
|
+
}
|
|
1419
|
+
args := make([]any, 0, len(ref.TypeArguments.Nodes))
|
|
1420
|
+
groups := [][]any{rootRefs}
|
|
1421
|
+
for _, child := range ref.TypeArguments.Nodes {
|
|
1422
|
+
arg, refs, ok := nestiaSDKReflectTypeNode(prog, imports, child)
|
|
1423
|
+
if ok == false {
|
|
1424
|
+
text := nestiaSDKTypeNodeText(child)
|
|
1425
|
+
arg = map[string]any{"name": text}
|
|
1426
|
+
refs = nestiaSDKReflectImports(text, imports)
|
|
1427
|
+
}
|
|
1428
|
+
args = append(args, arg)
|
|
1429
|
+
groups = append(groups, refs)
|
|
1430
|
+
}
|
|
1431
|
+
return map[string]any{
|
|
1432
|
+
"name": name,
|
|
1433
|
+
"typeArguments": args,
|
|
1434
|
+
}, nestiaSDKMergeImportLiterals(groups...), true
|
|
1435
|
+
}
|
|
1436
|
+
return map[string]any{"name": name}, rootRefs, true
|
|
1437
|
+
default:
|
|
1438
|
+
name := nestiaSDKTypeNodeText(node)
|
|
1439
|
+
if name == "" {
|
|
1440
|
+
return nil, nil, false
|
|
1441
|
+
}
|
|
1442
|
+
return map[string]any{"name": name}, nestiaSDKReflectImports(name, imports), true
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
func nestiaSDKReflectTypeReferenceSymbolImport(prog *driver.Program, node *shimast.Node, name string) []any {
|
|
1447
|
+
if prog == nil || prog.Checker == nil || node == nil {
|
|
1448
|
+
return nil
|
|
1449
|
+
}
|
|
1450
|
+
prefix := strings.Split(name, ".")[0]
|
|
1451
|
+
if nestiaSDKIsGlobalTypePrefix(prefix) {
|
|
1452
|
+
return nil
|
|
1453
|
+
}
|
|
1454
|
+
symbol := prog.Checker.GetSymbolAtLocation(node)
|
|
1455
|
+
if symbol == nil {
|
|
1456
|
+
typ := prog.Checker.GetTypeFromTypeNode(node)
|
|
1457
|
+
if typ != nil {
|
|
1458
|
+
symbol = typ.Symbol()
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
if symbol == nil || len(symbol.Declarations) == 0 {
|
|
1462
|
+
return nil
|
|
1463
|
+
}
|
|
1464
|
+
sourceFile := shimast.GetSourceFileOfNode(symbol.Declarations[0])
|
|
1465
|
+
if sourceFile == nil {
|
|
1466
|
+
return nil
|
|
1467
|
+
}
|
|
1468
|
+
file := filepath.ToSlash(sourceFile.FileName())
|
|
1469
|
+
if strings.Contains(file, "/typescript/lib/") {
|
|
1470
|
+
return nil
|
|
1471
|
+
}
|
|
1472
|
+
return []any{
|
|
1473
|
+
map[string]any{
|
|
1474
|
+
"file": file,
|
|
1475
|
+
"asterisk": nestiaSDKLiteralNull,
|
|
1476
|
+
"default": nestiaSDKLiteralNull,
|
|
1477
|
+
"elements": []string{prefix},
|
|
1478
|
+
},
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
func nestiaSDKReflectJoinedTypeNode(
|
|
1483
|
+
prog *driver.Program,
|
|
1484
|
+
imports []nestiaSDKImportInfo,
|
|
1485
|
+
types *shimast.TypeList,
|
|
1486
|
+
joiner string,
|
|
1487
|
+
) (map[string]any, []any) {
|
|
1488
|
+
if types == nil {
|
|
1489
|
+
return map[string]any{"name": ""}, nil
|
|
1490
|
+
}
|
|
1491
|
+
names := make([]string, 0, len(types.Nodes))
|
|
1492
|
+
groups := [][]any{}
|
|
1493
|
+
for _, child := range types.Nodes {
|
|
1494
|
+
ref, refs, ok := nestiaSDKReflectTypeNode(prog, imports, child)
|
|
1495
|
+
if ok == false {
|
|
1496
|
+
text := nestiaSDKTypeNodeText(child)
|
|
1497
|
+
names = append(names, text)
|
|
1498
|
+
groups = append(groups, nestiaSDKReflectImports(text, imports))
|
|
1499
|
+
} else {
|
|
1500
|
+
names = append(names, nestiaSDKReflectTypeText(ref))
|
|
1501
|
+
groups = append(groups, refs)
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
return map[string]any{"name": strings.Join(names, joiner)}, nestiaSDKMergeImportLiterals(groups...)
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
func nestiaSDKReflectTypeText(ref map[string]any) string {
|
|
1508
|
+
name, _ := ref["name"].(string)
|
|
1509
|
+
args, ok := ref["typeArguments"].([]any)
|
|
1510
|
+
if ok == false || len(args) == 0 {
|
|
1511
|
+
return name
|
|
1512
|
+
}
|
|
1513
|
+
texts := make([]string, 0, len(args))
|
|
1514
|
+
for _, arg := range args {
|
|
1515
|
+
child, ok := arg.(map[string]any)
|
|
1516
|
+
if ok == false {
|
|
1517
|
+
continue
|
|
1518
|
+
}
|
|
1519
|
+
texts = append(texts, nestiaSDKReflectTypeText(child))
|
|
1520
|
+
}
|
|
1521
|
+
return name + "<" + strings.Join(texts, ", ") + ">"
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
func nestiaSDKMergeImportLiterals(groups ...[]any) []any {
|
|
1525
|
+
output := []any{}
|
|
1526
|
+
seen := map[string]bool{}
|
|
1527
|
+
for _, group := range groups {
|
|
1528
|
+
for _, item := range group {
|
|
1529
|
+
key := fmt.Sprintf("%#v", item)
|
|
1530
|
+
if seen[key] {
|
|
1531
|
+
continue
|
|
1532
|
+
}
|
|
1533
|
+
seen[key] = true
|
|
1534
|
+
output = append(output, item)
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
return output
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
func nestiaSDKTypeOperatorPrefix(node *shimast.Node, operand *shimast.Node) string {
|
|
1541
|
+
text := nestiaSDKTypeNodeText(node)
|
|
1542
|
+
child := nestiaSDKTypeNodeText(operand)
|
|
1543
|
+
prefix := strings.TrimSpace(strings.TrimSuffix(text, child))
|
|
1544
|
+
switch prefix {
|
|
1545
|
+
case "keyof", "unique", "readonly":
|
|
1546
|
+
return prefix
|
|
1547
|
+
}
|
|
1548
|
+
return ""
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
func nestiaSDKParentClassName(node *shimast.Node) string {
|
|
1552
|
+
for parent := node.Parent; parent != nil; parent = parent.Parent {
|
|
1553
|
+
if parent.Kind == shimast.KindClassDeclaration {
|
|
1554
|
+
if name := parent.Name(); name != nil {
|
|
1555
|
+
return name.Text()
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
return ""
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
func nestiaSDKMethodName(node *shimast.Node) string {
|
|
1563
|
+
if node == nil || node.Name() == nil {
|
|
1564
|
+
return ""
|
|
1565
|
+
}
|
|
1566
|
+
return strings.Trim(node.Name().Text(), "\"'")
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
func nestiaSDKParameterName(node *shimast.Node) string {
|
|
1570
|
+
if node == nil || node.Name() == nil {
|
|
1571
|
+
return ""
|
|
1572
|
+
}
|
|
1573
|
+
return strings.Trim(node.Name().Text(), "\"'")
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
func nestiaSDKParameterTypeName(prog *driver.Program, node *shimast.Node, typ *shimchecker.Type) string {
|
|
1577
|
+
if node != nil && node.AsParameterDeclaration() != nil {
|
|
1578
|
+
if typeNode := node.AsParameterDeclaration().Type; typeNode != nil {
|
|
1579
|
+
return nestiaSDKTypeNodeText(typeNode)
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
return nestiaSDKTypeNameFromChecker(prog, typ)
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
func nestiaSDKParameterTypeNode(node *shimast.Node) *shimast.Node {
|
|
1586
|
+
if node != nil && node.AsParameterDeclaration() != nil {
|
|
1587
|
+
return node.AsParameterDeclaration().Type
|
|
1588
|
+
}
|
|
1589
|
+
return nil
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
func nestiaSDKMethodReturnTypeName(
|
|
1593
|
+
prog *driver.Program,
|
|
1594
|
+
method *shimast.Node,
|
|
1595
|
+
typ *shimchecker.Type,
|
|
1596
|
+
) string {
|
|
1597
|
+
if method != nil && method.FunctionLikeData() != nil {
|
|
1598
|
+
if typeNode := method.FunctionLikeData().Type; typeNode != nil {
|
|
1599
|
+
return nestiaSDKReturnTypeNodeText(prog, typeNode)
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
return nestiaSDKTypeNameFromChecker(prog, typ)
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
func nestiaSDKMethodReturnTypeNode(prog *driver.Program, method *shimast.Node) *shimast.Node {
|
|
1606
|
+
if method != nil && method.FunctionLikeData() != nil {
|
|
1607
|
+
if typeNode := method.FunctionLikeData().Type; typeNode != nil {
|
|
1608
|
+
return nestiaSDKReturnTypeNode(prog, typeNode)
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
return nil
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
func nestiaSDKReturnTypeNode(prog *driver.Program, node *shimast.Node) *shimast.Node {
|
|
1615
|
+
if node != nil && node.Kind == shimast.KindTypeReference {
|
|
1616
|
+
ref := node.AsTypeReferenceNode()
|
|
1617
|
+
if ref != nil && ref.TypeArguments != nil && len(ref.TypeArguments.Nodes) == 1 && nestiaSDKIsAsyncReturnWrapper(prog, ref.TypeName, nestiaSDKEntityNameText(ref.TypeName)) {
|
|
1618
|
+
return ref.TypeArguments.Nodes[0]
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
return node
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1624
|
+
func nestiaSDKEntityNameText(node *shimast.Node) string {
|
|
1625
|
+
return nestiaSDKTypeNodeText(node)
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
func nestiaSDKReturnTypeNodeText(prog *driver.Program, node *shimast.Node) string {
|
|
1629
|
+
text := nestiaSDKTypeNodeText(node)
|
|
1630
|
+
if node != nil && node.Kind == shimast.KindTypeReference {
|
|
1631
|
+
ref := node.AsTypeReferenceNode()
|
|
1632
|
+
if ref != nil && ref.TypeArguments != nil && len(ref.TypeArguments.Nodes) == 1 && nestiaSDKIsAsyncReturnWrapper(prog, ref.TypeName, nestiaSDKEntityNameText(ref.TypeName)) {
|
|
1633
|
+
return nestiaSDKTypeNodeText(ref.TypeArguments.Nodes[0])
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
return text
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
func nestiaSDKIsAsyncReturnWrapper(
|
|
1640
|
+
prog *driver.Program,
|
|
1641
|
+
node *shimast.Node,
|
|
1642
|
+
name string,
|
|
1643
|
+
) bool {
|
|
1644
|
+
if name == "Promise" {
|
|
1645
|
+
return true
|
|
1646
|
+
}
|
|
1647
|
+
if name != "Observable" || prog == nil || prog.Checker == nil {
|
|
1648
|
+
return false
|
|
1649
|
+
}
|
|
1650
|
+
symbol := prog.Checker.GetSymbolAtLocation(node)
|
|
1651
|
+
return nestiaSDKIsRxjsObservableImport(node) ||
|
|
1652
|
+
(symbol != nil && nestiaSDKIsRxjsDeclarations(symbol.Declarations))
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
func nestiaSDKIsRxjsDeclarations(declarations []*shimast.Node) bool {
|
|
1656
|
+
for _, decl := range declarations {
|
|
1657
|
+
sourceFile := shimast.GetSourceFileOfNode(decl)
|
|
1658
|
+
if sourceFile == nil {
|
|
1659
|
+
continue
|
|
1660
|
+
}
|
|
1661
|
+
file := filepath.ToSlash(sourceFile.FileName())
|
|
1662
|
+
if strings.Contains(file, "/node_modules/rxjs/") {
|
|
1663
|
+
return true
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1666
|
+
return false
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
func nestiaSDKIsRxjsObservableImport(node *shimast.Node) bool {
|
|
1670
|
+
source, ok := transform.SourceFileText(shimast.GetSourceFileOfNode(node))
|
|
1671
|
+
return ok && nestiaSDKHasNamedImport(source, "rxjs", "Observable", "Observable")
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
func nestiaSDKHasNamedImport(
|
|
1675
|
+
source string,
|
|
1676
|
+
module string,
|
|
1677
|
+
imported string,
|
|
1678
|
+
local string,
|
|
1679
|
+
) bool {
|
|
1680
|
+
for _, match := range nestiaSDKImportFromPattern.FindAllStringSubmatch(source, -1) {
|
|
1681
|
+
if len(match) < 3 || match[2] != module {
|
|
1682
|
+
continue
|
|
1683
|
+
}
|
|
1684
|
+
open := strings.Index(match[1], "{")
|
|
1685
|
+
close := strings.LastIndex(match[1], "}")
|
|
1686
|
+
if open < 0 || close <= open {
|
|
1687
|
+
continue
|
|
1688
|
+
}
|
|
1689
|
+
for _, part := range strings.Split(match[1][open+1:close], ",") {
|
|
1690
|
+
fields := strings.Fields(strings.TrimPrefix(strings.TrimSpace(part), "type "))
|
|
1691
|
+
if len(fields) == 1 && fields[0] == local && imported == local {
|
|
1692
|
+
return true
|
|
1693
|
+
}
|
|
1694
|
+
if len(fields) == 3 &&
|
|
1695
|
+
fields[0] == imported &&
|
|
1696
|
+
fields[1] == "as" &&
|
|
1697
|
+
fields[2] == local {
|
|
1698
|
+
return true
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
return false
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
var nestiaSDKImportFromPattern = regexp.MustCompile(
|
|
1706
|
+
`(?s)import\s+(?:type\s+)?(.+?)\s+from\s+["']([^"']+)["']`,
|
|
1707
|
+
)
|
|
1708
|
+
|
|
1709
|
+
func nestiaSDKTypeNodeText(node *shimast.Node) string {
|
|
1710
|
+
if node == nil {
|
|
1711
|
+
return ""
|
|
1712
|
+
}
|
|
1713
|
+
file := shimast.GetSourceFileOfNode(node)
|
|
1714
|
+
source, ok := transform.SourceFileText(file)
|
|
1715
|
+
if ok == false {
|
|
1716
|
+
return ""
|
|
1717
|
+
}
|
|
1718
|
+
start, end := node.Pos(), node.End()
|
|
1719
|
+
if start < 0 || end > len(source) || start >= end {
|
|
1720
|
+
return ""
|
|
1721
|
+
}
|
|
1722
|
+
return strings.TrimSpace(source[start:end])
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
func nestiaSDKTypeNameFromChecker(prog *driver.Program, typ *shimchecker.Type) string {
|
|
1726
|
+
if prog != nil && prog.Checker != nil && typ != nil {
|
|
1727
|
+
return prog.Checker.TypeToString(typ)
|
|
1728
|
+
}
|
|
1729
|
+
return "any"
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
func insertSDKOperationMetadataDecorators(text string, sites []nestiaSDKSite) string {
|
|
1733
|
+
if len(sites) == 0 {
|
|
1734
|
+
return text
|
|
1735
|
+
}
|
|
1736
|
+
cursor := 0
|
|
1737
|
+
out := text
|
|
1738
|
+
for _, site := range sites {
|
|
1739
|
+
next, ok := insertSDKOperationMetadataDecorator(out, site, cursor)
|
|
1740
|
+
if ok {
|
|
1741
|
+
out = next.text
|
|
1742
|
+
cursor = next.cursor
|
|
1743
|
+
continue
|
|
1744
|
+
}
|
|
1745
|
+
next, ok = insertSDKOperationMetadataDecorator(out, site, 0)
|
|
1746
|
+
if ok {
|
|
1747
|
+
out = next.text
|
|
1748
|
+
cursor = next.cursor
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
return out
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
type sdkOperationMetadataInsertResult struct {
|
|
1755
|
+
text string
|
|
1756
|
+
cursor int
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
func insertSDKOperationMetadataDecorator(text string, site nestiaSDKSite, offset int) (sdkOperationMetadataInsertResult, bool) {
|
|
1760
|
+
if offset < 0 || offset > len(text) {
|
|
1761
|
+
offset = 0
|
|
1762
|
+
}
|
|
1763
|
+
needle := "], " + site.ClassName + ".prototype, \"" + site.MethodName + "\","
|
|
1764
|
+
relative := strings.Index(text[offset:], needle)
|
|
1765
|
+
idx := -1
|
|
1766
|
+
if relative >= 0 {
|
|
1767
|
+
idx = offset + relative
|
|
1768
|
+
}
|
|
1769
|
+
if idx < 0 {
|
|
1770
|
+
return sdkOperationMetadataInsertResult{text: text, cursor: offset}, false
|
|
1771
|
+
}
|
|
1772
|
+
head := strings.LastIndex(text[:idx], "__decorate([")
|
|
1773
|
+
if head < 0 {
|
|
1774
|
+
return sdkOperationMetadataInsertResult{text: text, cursor: offset}, false
|
|
1775
|
+
}
|
|
1776
|
+
if strings.Contains(text[head:idx], "__OperationMetadata.OperationMetadata") {
|
|
1777
|
+
return sdkOperationMetadataInsertResult{
|
|
1778
|
+
text: text,
|
|
1779
|
+
cursor: idx + len(needle),
|
|
1780
|
+
}, true
|
|
1781
|
+
}
|
|
1782
|
+
insert := head + len("__decorate([")
|
|
1783
|
+
decorator := "\n __OperationMetadata.OperationMetadata(" + site.Metadata + "),"
|
|
1784
|
+
next := text[:insert] + decorator + text[insert:]
|
|
1785
|
+
return sdkOperationMetadataInsertResult{
|
|
1786
|
+
text: next,
|
|
1787
|
+
cursor: idx + len(decorator) + len(needle),
|
|
1788
|
+
}, true
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
func injectSDKOperationMetadataImport(text string) string {
|
|
1792
|
+
if strings.Contains(text, "__OperationMetadata.OperationMetadata") == false ||
|
|
1793
|
+
strings.Contains(text, "const __OperationMetadata = require(\"@nestia/sdk\")") ||
|
|
1794
|
+
strings.Contains(text, "__OperationMetadata = __importStar(require(\"@nestia/sdk\"))") ||
|
|
1795
|
+
strings.Contains(text, "import * as __OperationMetadata from \"@nestia/sdk\"") {
|
|
1796
|
+
return text
|
|
1797
|
+
}
|
|
1798
|
+
esModule := sdkIsESModuleOutput(text)
|
|
1799
|
+
var stmt string
|
|
1800
|
+
if esModule {
|
|
1801
|
+
stmt = "import * as __OperationMetadata from \"@nestia/sdk\";\n"
|
|
1802
|
+
} else {
|
|
1803
|
+
stmt = "const __OperationMetadata = require(\"@nestia/sdk\");\n"
|
|
1804
|
+
}
|
|
1805
|
+
index := sdkRuntimeImportInsertionIndex(text, esModule)
|
|
1806
|
+
return text[:index] + stmt + text[index:]
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
func sdkIsESModuleOutput(text string) bool {
|
|
1810
|
+
return regexp.MustCompile(`(?m)^(import\s|import\{|import\*|export\s)`).MatchString(text)
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
func sdkRuntimeImportInsertionIndex(text string, esModule bool) int {
|
|
1814
|
+
index := 0
|
|
1815
|
+
if strings.HasPrefix(text, "#!") {
|
|
1816
|
+
if next := strings.IndexByte(text, '\n'); next >= 0 {
|
|
1817
|
+
index = next + 1
|
|
1818
|
+
} else {
|
|
1819
|
+
return len(text)
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
if esModule {
|
|
1823
|
+
return index
|
|
1824
|
+
}
|
|
1825
|
+
for {
|
|
1826
|
+
next := sdkConsumeRuntimeImportPrefix(text[index:])
|
|
1827
|
+
if next == 0 {
|
|
1828
|
+
return index
|
|
1829
|
+
}
|
|
1830
|
+
index += next
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
func sdkConsumeRuntimeImportPrefix(text string) int {
|
|
1835
|
+
for _, prefix := range []string{
|
|
1836
|
+
"\"use strict\";\n",
|
|
1837
|
+
"'use strict';\n",
|
|
1838
|
+
"/* @ttsc-rewritten */\n",
|
|
1839
|
+
} {
|
|
1840
|
+
if strings.HasPrefix(text, prefix) {
|
|
1841
|
+
return len(prefix)
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
return 0
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
func sourceLineIndent(source string, pos int) string {
|
|
1848
|
+
if pos < 0 || pos > len(source) {
|
|
1849
|
+
return ""
|
|
1850
|
+
}
|
|
1851
|
+
start := strings.LastIndex(source[:pos], "\n")
|
|
1852
|
+
if start < 0 {
|
|
1853
|
+
start = 0
|
|
1854
|
+
} else {
|
|
1855
|
+
start++
|
|
1856
|
+
}
|
|
1857
|
+
end := start
|
|
1858
|
+
for end < len(source) && (source[end] == ' ' || source[end] == '\t') {
|
|
1859
|
+
end++
|
|
1860
|
+
}
|
|
1861
|
+
return source[start:end]
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
func nestiaSDKDiagnostic(site nestiaSDKSite, message string) transform.Diagnostic {
|
|
1865
|
+
line, column := 0, 0
|
|
1866
|
+
if site.File != nil && site.Method != nil {
|
|
1867
|
+
if pos := site.Method.Pos(); pos >= 0 {
|
|
1868
|
+
l, c := shimscanner.GetECMALineAndByteOffsetOfPosition(site.File, pos)
|
|
1869
|
+
line, column = l+1, c+1
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
return transform.Diagnostic{
|
|
1873
|
+
File: site.FilePath,
|
|
1874
|
+
Line: line,
|
|
1875
|
+
Column: column,
|
|
1876
|
+
Code: "nestia.sdk.OperationMetadata",
|
|
1877
|
+
Message: message,
|
|
1878
|
+
}
|
|
1879
|
+
}
|