@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
package/native/sdk/register.go
CHANGED
|
@@ -1,165 +1,322 @@
|
|
|
1
|
-
package sdk
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"fmt"
|
|
5
|
-
"os"
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"github.com/
|
|
10
|
-
"github.com/
|
|
11
|
-
"github.com/samchon/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
|
|
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
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
1
|
+
package sdk
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"os"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
|
|
9
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
10
|
+
shimprinter "github.com/microsoft/typescript-go/shim/printer"
|
|
11
|
+
"github.com/samchon/nestia/packages/core/native/plugin"
|
|
12
|
+
"github.com/samchon/nestia/packages/core/native/transform"
|
|
13
|
+
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
// sdkMetadataNamespace is the import alias the legacy (text/program-mutation)
|
|
17
|
+
// path references. The emit-context path lets tsgo's module-transform pick the
|
|
18
|
+
// generated alias itself, so it does not use this constant.
|
|
19
|
+
const sdkMetadataNamespace = "__OperationMetadata"
|
|
20
|
+
|
|
21
|
+
// sdkMetadataModule is the runtime package the injected decorator is imported
|
|
22
|
+
// from.
|
|
23
|
+
const sdkMetadataModule = "@nestia/sdk"
|
|
24
|
+
|
|
25
|
+
// sdkMetadataMember is the decorator factory exported by sdkMetadataModule.
|
|
26
|
+
const sdkMetadataMember = "OperationMetadata"
|
|
27
|
+
|
|
28
|
+
// init registers the SDK metadata transform with both native entry paths.
|
|
29
|
+
//
|
|
30
|
+
// ttsc classifies this package (name != "main") as a linked transform and
|
|
31
|
+
// statically links it into the `@nestia/core` host binary — but only for
|
|
32
|
+
// projects that depend on `@nestia/sdk`. The direct linked-plugin path keeps
|
|
33
|
+
// old plugin plans working, while the contributor collectors let the aggregate
|
|
34
|
+
// core host run SDK metadata rewrites without starting a second native backend.
|
|
35
|
+
func init() {
|
|
36
|
+
driver.RegisterPlugin(linkedPlugin{})
|
|
37
|
+
transform.RegisterBuildOutputRewriteCollector(collectSDKBuildOutputRewriter)
|
|
38
|
+
transform.RegisterSourceRewriteCollector(collectSDKSourceRewriteMap)
|
|
39
|
+
transform.RegisterEmitTransformCollector(collectSDKEmitTransform)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type linkedPlugin struct{}
|
|
43
|
+
|
|
44
|
+
// ApplyProgram injects the `@OperationMetadata("<json>")` decorator that the
|
|
45
|
+
// SDK / Swagger / e2e generators read at runtime, plus the namespace import it
|
|
46
|
+
// references.
|
|
47
|
+
//
|
|
48
|
+
// Insertion is done with synthesized AST nodes (NodeFlagsSynthesized): ttsc's
|
|
49
|
+
// emit prints those structurally, without slicing the original source text, so
|
|
50
|
+
// no source-text rewrite is needed. The metadata is carried as a single JSON
|
|
51
|
+
// string literal — the `OperationMetadata` decorator `JSON.parse`s it — which
|
|
52
|
+
// keeps the constructed AST to one literal node instead of a deep object tree.
|
|
53
|
+
func (linkedPlugin) ApplyProgram(prog *driver.Program, _ driver.PluginContext) error {
|
|
54
|
+
sites, diags := collectNestiaSDKSites(prog)
|
|
55
|
+
if len(diags) > 0 {
|
|
56
|
+
messages := make([]string, 0, len(diags))
|
|
57
|
+
for _, diag := range diags {
|
|
58
|
+
messages = append(messages, diag.String(""))
|
|
59
|
+
}
|
|
60
|
+
return fmt.Errorf("%s", strings.Join(messages, "\n"))
|
|
61
|
+
}
|
|
62
|
+
if len(sites) == 0 {
|
|
63
|
+
return nil
|
|
64
|
+
}
|
|
65
|
+
factory := shimast.NewNodeFactory(shimast.NodeFactoryHooks{})
|
|
66
|
+
touched := map[*shimast.SourceFile]bool{}
|
|
67
|
+
for _, site := range sites {
|
|
68
|
+
if site.Method == nil || site.File == nil {
|
|
69
|
+
continue
|
|
70
|
+
}
|
|
71
|
+
injectOperationMetadataDecorator(factory, site.Method, site.Metadata)
|
|
72
|
+
touched[site.File] = true
|
|
73
|
+
}
|
|
74
|
+
for file := range touched {
|
|
75
|
+
injectOperationMetadataImport(factory, file)
|
|
76
|
+
}
|
|
77
|
+
return nil
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// EmitTransform builds the SDK metadata pass as an emit-phase AST transformer
|
|
81
|
+
// (the AST-integration path that mirrors typia's `transform.Transform`). It
|
|
82
|
+
// collects every controller-method site once for the program, then returns a
|
|
83
|
+
// per-file `driver.PluginTransform` that injects the
|
|
84
|
+
// `@<ns>.OperationMetadata("<json>")` decorator plus a namespace import of
|
|
85
|
+
// `@nestia/sdk`, both built with ec.Factory and referenced through
|
|
86
|
+
// NewGeneratedNameForNode(modSpec), so tsgo's builtin module-transform emits the
|
|
87
|
+
// `require("@nestia/sdk")` and aliases the reference itself — no hand-rolled
|
|
88
|
+
// `__OperationMetadata` namespace and no text-splice.
|
|
89
|
+
//
|
|
90
|
+
// Core's build command wires this into `prog.EmitWithPluginTransformers`
|
|
91
|
+
// alongside the typia and core transforms, exactly as the typia build command
|
|
92
|
+
// wires `nativetransform.Transform`. A site-collection failure is returned as
|
|
93
|
+
// diagnostics; the returned transform is nil when there are no sites.
|
|
94
|
+
func EmitTransform(prog *driver.Program) (driver.PluginTransform, []transform.Diagnostic) {
|
|
95
|
+
sites, diagnostics := collectNestiaSDKSites(prog)
|
|
96
|
+
if len(diagnostics) > 0 {
|
|
97
|
+
return nil, diagnostics
|
|
98
|
+
}
|
|
99
|
+
if len(sites) == 0 {
|
|
100
|
+
return nil, nil
|
|
101
|
+
}
|
|
102
|
+
byFile := map[string][]nestiaSDKSite{}
|
|
103
|
+
for _, site := range sites {
|
|
104
|
+
byFile[filepath.ToSlash(site.FilePath)] = append(byFile[filepath.ToSlash(site.FilePath)], site)
|
|
105
|
+
}
|
|
106
|
+
return func(ec *shimprinter.EmitContext, sf *shimast.SourceFile) *shimast.SourceFile {
|
|
107
|
+
if sf == nil {
|
|
108
|
+
return sf
|
|
109
|
+
}
|
|
110
|
+
fileSites := byFile[filepath.ToSlash(sf.FileName())]
|
|
111
|
+
if len(fileSites) == 0 {
|
|
112
|
+
return sf
|
|
113
|
+
}
|
|
114
|
+
// One module-specifier literal per file, shared between the injected
|
|
115
|
+
// import declaration and every decorator reference, so
|
|
116
|
+
// NewGeneratedNameForNode binds them to the same alias tsgo's
|
|
117
|
+
// module-transform emits for the require.
|
|
118
|
+
modSpec := ec.Factory.NewStringLiteral(sdkMetadataModule, shimast.TokenFlagsNone)
|
|
119
|
+
// Sites were collected from the parse-tree program, so site.Method is an
|
|
120
|
+
// original method node. By the time this contributor runs, typia and core
|
|
121
|
+
// have already rebuilt every decorated method into a synthetic copy with a
|
|
122
|
+
// fresh modifier list, and the original node is no longer in the emitted
|
|
123
|
+
// tree. Map each original method to its synthetic counterpart (via the
|
|
124
|
+
// emit context's original link) so the injected decorator lands on the
|
|
125
|
+
// node that is actually printed; fall back to the original when the method
|
|
126
|
+
// was untouched.
|
|
127
|
+
synthByOriginal := map[*shimast.Node]*shimast.Node{}
|
|
128
|
+
var collect func(node *shimast.Node)
|
|
129
|
+
collect = func(node *shimast.Node) {
|
|
130
|
+
if node == nil {
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
if node.Kind == shimast.KindMethodDeclaration {
|
|
134
|
+
if original := ec.MostOriginal(node); original != nil {
|
|
135
|
+
synthByOriginal[original] = node
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
node.ForEachChild(func(child *shimast.Node) bool {
|
|
139
|
+
collect(child)
|
|
140
|
+
return false
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
collect(sf.AsNode())
|
|
144
|
+
for _, site := range fileSites {
|
|
145
|
+
if site.Method == nil {
|
|
146
|
+
continue
|
|
147
|
+
}
|
|
148
|
+
method := site.Method
|
|
149
|
+
if synth, ok := synthByOriginal[site.Method]; ok {
|
|
150
|
+
method = synth
|
|
151
|
+
}
|
|
152
|
+
injectOperationMetadataDecoratorEC(ec, modSpec, method, site.Metadata)
|
|
153
|
+
}
|
|
154
|
+
injectOperationMetadataImportEC(ec, modSpec, sf)
|
|
155
|
+
return sf
|
|
156
|
+
}, nil
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// collectSDKEmitTransform exposes EmitTransform to the core `transform`
|
|
160
|
+
// subcommand's contributor registry, the node-path twin of
|
|
161
|
+
// collectSDKSourceRewriteMap. It is gated by the same NESTIA_SDK_TRANSFORM flag
|
|
162
|
+
// so the SDK metadata pass only participates when the caller opts in.
|
|
163
|
+
func collectSDKEmitTransform(
|
|
164
|
+
prog *driver.Program,
|
|
165
|
+
_ plugin.Plan,
|
|
166
|
+
) (driver.PluginTransform, []transform.Diagnostic) {
|
|
167
|
+
if shouldRunSDKContributorTransform() == false {
|
|
168
|
+
return nil, nil
|
|
169
|
+
}
|
|
170
|
+
return EmitTransform(prog)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
func collectSDKBuildOutputRewriter(
|
|
174
|
+
prog *driver.Program,
|
|
175
|
+
plan plugin.Plan,
|
|
176
|
+
) (*transform.BuildOutputRewriter, []transform.Diagnostic) {
|
|
177
|
+
if shouldRunSDKContributorTransform() == false {
|
|
178
|
+
return nil, nil
|
|
179
|
+
}
|
|
180
|
+
plan.SDK = true
|
|
181
|
+
set, diagnostics := collectNestiaSDKBuildRewrites(prog, plan)
|
|
182
|
+
return &transform.BuildOutputRewriter{
|
|
183
|
+
Len: set.Len,
|
|
184
|
+
Apply: set.Apply,
|
|
185
|
+
}, diagnostics
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
func collectSDKSourceRewriteMap(
|
|
189
|
+
prog *driver.Program,
|
|
190
|
+
plan plugin.Plan,
|
|
191
|
+
onlyFile string,
|
|
192
|
+
) (map[string][]transform.SourceRewrite, []transform.Diagnostic) {
|
|
193
|
+
if shouldRunSDKContributorTransform() == false {
|
|
194
|
+
return map[string][]transform.SourceRewrite{}, nil
|
|
195
|
+
}
|
|
196
|
+
plan.SDK = true
|
|
197
|
+
return collectNestiaSDKSourceRewriteMap(prog, plan, onlyFile)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
func shouldRunSDKContributorTransform() bool {
|
|
201
|
+
return os.Getenv("NESTIA_SDK_TRANSFORM") == "1"
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
func synthesized(node *shimast.Node) *shimast.Node {
|
|
205
|
+
if node != nil {
|
|
206
|
+
node.Flags |= shimast.NodeFlagsSynthesized
|
|
207
|
+
}
|
|
208
|
+
return node
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// injectOperationMetadataDecorator prepends a synthesized
|
|
212
|
+
// `@__OperationMetadata.OperationMetadata("<json>")` decorator to a controller
|
|
213
|
+
// method. Every site is a method that already carries `@nestia/core`
|
|
214
|
+
// decorators, so its modifier list is non-nil and can be mutated in place.
|
|
215
|
+
func injectOperationMetadataDecorator(
|
|
216
|
+
factory *shimast.NodeFactory,
|
|
217
|
+
method *shimast.Node,
|
|
218
|
+
metadataJSON string,
|
|
219
|
+
) {
|
|
220
|
+
modifiers := method.Modifiers()
|
|
221
|
+
if modifiers == nil {
|
|
222
|
+
return
|
|
223
|
+
}
|
|
224
|
+
namespaceID := synthesized(factory.NewIdentifier(sdkMetadataNamespace))
|
|
225
|
+
memberID := synthesized(factory.NewIdentifier("OperationMetadata"))
|
|
226
|
+
access := synthesized(factory.NewPropertyAccessExpression(
|
|
227
|
+
namespaceID,
|
|
228
|
+
nil,
|
|
229
|
+
memberID,
|
|
230
|
+
shimast.NodeFlagsNone,
|
|
231
|
+
))
|
|
232
|
+
namespaceID.Parent = access
|
|
233
|
+
memberID.Parent = access
|
|
234
|
+
argument := synthesized(factory.NewStringLiteral(metadataJSON, shimast.TokenFlagsNone))
|
|
235
|
+
call := synthesized(factory.NewCallExpression(
|
|
236
|
+
access,
|
|
237
|
+
nil,
|
|
238
|
+
nil,
|
|
239
|
+
factory.NewNodeList([]*shimast.Node{argument}),
|
|
240
|
+
shimast.NodeFlagsNone,
|
|
241
|
+
))
|
|
242
|
+
access.Parent = call
|
|
243
|
+
argument.Parent = call
|
|
244
|
+
decorator := synthesized(factory.NewDecorator(call))
|
|
245
|
+
call.Parent = decorator
|
|
246
|
+
decorator.Parent = method
|
|
247
|
+
modifiers.Nodes = append([]*shimast.Node{decorator}, modifiers.Nodes...)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// injectOperationMetadataImport prepends a synthesized
|
|
251
|
+
// `import * as __OperationMetadata from "@nestia/sdk"` to a touched file.
|
|
252
|
+
func injectOperationMetadataImport(
|
|
253
|
+
factory *shimast.NodeFactory,
|
|
254
|
+
file *shimast.SourceFile,
|
|
255
|
+
) {
|
|
256
|
+
if file == nil || file.Statements == nil {
|
|
257
|
+
return
|
|
258
|
+
}
|
|
259
|
+
namespaceID := synthesized(factory.NewIdentifier(sdkMetadataNamespace))
|
|
260
|
+
namespace := synthesized(factory.NewNamespaceImport(namespaceID))
|
|
261
|
+
namespaceID.Parent = namespace
|
|
262
|
+
clause := synthesized(factory.NewImportClause(shimast.KindUnknown, nil, namespace))
|
|
263
|
+
namespace.Parent = clause
|
|
264
|
+
specifier := synthesized(factory.NewStringLiteral("@nestia/sdk", shimast.TokenFlagsNone))
|
|
265
|
+
declaration := synthesized(factory.NewImportDeclaration(nil, clause, specifier, nil))
|
|
266
|
+
clause.Parent = declaration
|
|
267
|
+
specifier.Parent = declaration
|
|
268
|
+
declaration.Parent = file.AsNode()
|
|
269
|
+
file.Statements.Nodes = append([]*shimast.Node{declaration}, file.Statements.Nodes...)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// injectOperationMetadataDecoratorEC is the emit-context (AST-integration)
|
|
273
|
+
// twin of injectOperationMetadataDecorator. The decorator's namespace reference
|
|
274
|
+
// is `ec.Factory.NewGeneratedNameForNode(modSpec)`, the same generated name
|
|
275
|
+
// tsgo's module-transform binds to `require("@nestia/sdk")`, so no hand-rolled
|
|
276
|
+
// `__OperationMetadata` alias is needed.
|
|
277
|
+
func injectOperationMetadataDecoratorEC(
|
|
278
|
+
ec *shimprinter.EmitContext,
|
|
279
|
+
modSpec *shimast.Node,
|
|
280
|
+
method *shimast.Node,
|
|
281
|
+
metadataJSON string,
|
|
282
|
+
) {
|
|
283
|
+
modifiers := method.Modifiers()
|
|
284
|
+
if modifiers == nil {
|
|
285
|
+
return
|
|
286
|
+
}
|
|
287
|
+
access := ec.Factory.NewPropertyAccessExpression(
|
|
288
|
+
ec.Factory.NewGeneratedNameForNode(modSpec),
|
|
289
|
+
nil,
|
|
290
|
+
ec.Factory.NewIdentifier(sdkMetadataMember),
|
|
291
|
+
shimast.NodeFlagsNone,
|
|
292
|
+
)
|
|
293
|
+
argument := ec.Factory.NewStringLiteral(metadataJSON, shimast.TokenFlagsNone)
|
|
294
|
+
call := ec.Factory.NewCallExpression(
|
|
295
|
+
access,
|
|
296
|
+
nil,
|
|
297
|
+
nil,
|
|
298
|
+
ec.Factory.NewNodeList([]*shimast.Node{argument}),
|
|
299
|
+
shimast.NodeFlagsNone,
|
|
300
|
+
)
|
|
301
|
+
decorator := ec.Factory.NewDecorator(call)
|
|
302
|
+
modifiers.Nodes = append([]*shimast.Node{decorator}, modifiers.Nodes...)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// injectOperationMetadataImportEC is the emit-context twin of
|
|
306
|
+
// injectOperationMetadataImport. It prepends `import * as <gen> from
|
|
307
|
+
// "@nestia/sdk"` built with ec.Factory, reusing modSpec so the namespace alias
|
|
308
|
+
// matches every decorator reference; tsgo's module-transform turns it into the
|
|
309
|
+
// `const <gen> = require("@nestia/sdk")` binding.
|
|
310
|
+
func injectOperationMetadataImportEC(
|
|
311
|
+
ec *shimprinter.EmitContext,
|
|
312
|
+
modSpec *shimast.Node,
|
|
313
|
+
file *shimast.SourceFile,
|
|
314
|
+
) {
|
|
315
|
+
if file == nil || file.Statements == nil {
|
|
316
|
+
return
|
|
317
|
+
}
|
|
318
|
+
namespace := ec.Factory.NewNamespaceImport(ec.Factory.NewGeneratedNameForNode(modSpec))
|
|
319
|
+
clause := ec.Factory.NewImportClause(shimast.KindUnknown, nil, namespace)
|
|
320
|
+
declaration := ec.Factory.NewImportDeclaration(nil, clause, modSpec, nil)
|
|
321
|
+
file.Statements.Nodes = append([]*shimast.Node{declaration}, file.Statements.Nodes...)
|
|
322
|
+
}
|
package/native/sdk/sdk.go
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
// Package sdk implements the `@nestia/sdk` ttsc transform plugin: it injects
|
|
2
|
-
// the `@OperationMetadata({...})` decorator the SDK / Swagger / e2e generators
|
|
3
|
-
// read at runtime. It is a separate plugin from `@nestia/core` so that a
|
|
4
|
-
// project depending only on `@nestia/core` never compiles this code — see
|
|
5
|
-
// `packages/core/native/transform` for the shared transform infrastructure
|
|
6
|
-
// this package imports.
|
|
7
|
-
package sdk
|
|
8
|
-
|
|
9
|
-
import (
|
|
10
|
-
"io"
|
|
11
|
-
"os"
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
var (
|
|
15
|
-
stdout io.Writer = os.Stdout
|
|
16
|
-
stderr io.Writer = os.Stderr
|
|
17
|
-
)
|
|
1
|
+
// Package sdk implements the `@nestia/sdk` ttsc transform plugin: it injects
|
|
2
|
+
// the `@OperationMetadata({...})` decorator the SDK / Swagger / e2e generators
|
|
3
|
+
// read at runtime. It is a separate plugin from `@nestia/core` so that a
|
|
4
|
+
// project depending only on `@nestia/core` never compiles this code — see
|
|
5
|
+
// `packages/core/native/transform` for the shared transform infrastructure
|
|
6
|
+
// this package imports.
|
|
7
|
+
package sdk
|
|
8
|
+
|
|
9
|
+
import (
|
|
10
|
+
"io"
|
|
11
|
+
"os"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
var (
|
|
15
|
+
stdout io.Writer = os.Stdout
|
|
16
|
+
stderr io.Writer = os.Stderr
|
|
17
|
+
)
|