@nestia/core 11.2.0 → 12.0.0-dev.20260520.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/MIGRATION.md +169 -0
  2. package/lib/adaptors/WebSocketAdaptor.js +7 -3
  3. package/lib/adaptors/WebSocketAdaptor.js.map +1 -1
  4. package/lib/decorators/DynamicModule.js.map +1 -1
  5. package/lib/decorators/EncryptedBody.js.map +1 -1
  6. package/lib/decorators/EncryptedController.js.map +1 -1
  7. package/lib/decorators/EncryptedModule.js.map +1 -1
  8. package/lib/decorators/EncryptedRoute.js.map +1 -1
  9. package/lib/decorators/HumanRoute.js.map +1 -1
  10. package/lib/decorators/NoTransformConfigurationError.js +5 -2
  11. package/lib/decorators/NoTransformConfigurationError.js.map +1 -1
  12. package/lib/decorators/PlainBody.js.map +1 -1
  13. package/lib/decorators/SwaggerCustomizer.js.map +1 -1
  14. package/lib/decorators/SwaggerExample.js.map +1 -1
  15. package/lib/decorators/TypedBody.js.map +1 -1
  16. package/lib/decorators/TypedException.js.map +1 -1
  17. package/lib/decorators/TypedFormData.js.map +1 -1
  18. package/lib/decorators/TypedHeaders.js.map +1 -1
  19. package/lib/decorators/TypedParam.js +5 -2
  20. package/lib/decorators/TypedParam.js.map +1 -1
  21. package/lib/decorators/TypedQuery.js.map +1 -1
  22. package/lib/decorators/TypedRoute.js.map +1 -1
  23. package/lib/decorators/WebSocketRoute.js.map +1 -1
  24. package/lib/decorators/doNotThrowTransformError.js.map +1 -1
  25. package/lib/decorators/internal/get_path_and_querify.js +5 -2
  26. package/lib/decorators/internal/get_path_and_querify.js.map +1 -1
  27. package/lib/decorators/internal/get_path_and_stringify.js +5 -2
  28. package/lib/decorators/internal/get_path_and_stringify.js.map +1 -1
  29. package/lib/decorators/internal/get_text_body.js.map +1 -1
  30. package/lib/decorators/internal/headers_to_object.js.map +1 -1
  31. package/lib/decorators/internal/is_request_body_undefined.js.map +1 -1
  32. package/lib/decorators/internal/load_controller.js +48 -16
  33. package/lib/decorators/internal/load_controller.js.map +1 -1
  34. package/lib/decorators/internal/route_error.js +3 -3
  35. package/lib/decorators/internal/route_error.js.map +1 -1
  36. package/lib/decorators/internal/validate_request_body.js +5 -2
  37. package/lib/decorators/internal/validate_request_body.js.map +1 -1
  38. package/lib/decorators/internal/validate_request_form_data.js +5 -2
  39. package/lib/decorators/internal/validate_request_form_data.js.map +1 -1
  40. package/lib/decorators/internal/validate_request_headers.js +5 -2
  41. package/lib/decorators/internal/validate_request_headers.js.map +1 -1
  42. package/lib/decorators/internal/validate_request_query.js +30 -4
  43. package/lib/decorators/internal/validate_request_query.js.map +1 -1
  44. package/lib/index.js.map +1 -1
  45. package/lib/transform.d.ts +2 -5
  46. package/lib/transform.js +48 -28
  47. package/lib/transform.js.map +1 -1
  48. package/lib/utils/ArrayUtil.js.map +1 -1
  49. package/lib/utils/ExceptionManager.js.map +1 -1
  50. package/lib/utils/Singleton.js.map +1 -1
  51. package/lib/utils/SourceFinder.js.map +1 -1
  52. package/lib/utils/VersioningStrategy.js.map +1 -1
  53. package/native/cmd/ttsc-nestia/build.go +434 -0
  54. package/native/cmd/ttsc-nestia/cleanup.go +408 -0
  55. package/native/cmd/ttsc-nestia/core_querify.go +227 -0
  56. package/native/cmd/ttsc-nestia/core_transform.go +1713 -0
  57. package/native/cmd/ttsc-nestia/core_websocket.go +115 -0
  58. package/native/cmd/ttsc-nestia/main.go +72 -0
  59. package/native/cmd/ttsc-nestia/path_rewrite.go +285 -0
  60. package/native/cmd/ttsc-nestia/printer.go +244 -0
  61. package/native/cmd/ttsc-nestia/rewrite.go +662 -0
  62. package/native/cmd/ttsc-nestia/sdk_metadata_json.go +327 -0
  63. package/native/cmd/ttsc-nestia/sdk_transform.go +1541 -0
  64. package/native/cmd/ttsc-nestia/transform.go +387 -0
  65. package/native/cmd/ttsc-nestia/typia_fast.go +326 -0
  66. package/native/cmd/ttsc-nestia/typia_replacement.go +24 -0
  67. package/native/go.mod +32 -0
  68. package/native/go.sum +54 -0
  69. package/native/plugin/plan.go +102 -0
  70. package/native/transform.cjs +21 -0
  71. package/package.json +27 -22
  72. package/src/decorators/NoTransformConfigurationError.ts +5 -2
  73. package/src/decorators/internal/load_controller.ts +50 -19
  74. package/src/decorators/internal/validate_request_query.ts +21 -2
  75. package/src/transform.ts +82 -35
  76. package/lib/decorators/internal/NoTransformConfigureError.d.ts +0 -1
  77. package/lib/decorators/internal/NoTransformConfigureError.js +0 -7
  78. package/lib/decorators/internal/NoTransformConfigureError.js.map +0 -1
  79. package/lib/options/INestiaTransformOptions.d.ts +0 -13
  80. package/lib/options/INestiaTransformOptions.js +0 -3
  81. package/lib/options/INestiaTransformOptions.js.map +0 -1
  82. package/lib/options/INestiaTransformProject.d.ts +0 -5
  83. package/lib/options/INestiaTransformProject.js +0 -3
  84. package/lib/options/INestiaTransformProject.js.map +0 -1
  85. package/lib/programmers/PlainBodyProgrammer.d.ts +0 -9
  86. package/lib/programmers/PlainBodyProgrammer.js +0 -58
  87. package/lib/programmers/PlainBodyProgrammer.js.map +0 -1
  88. package/lib/programmers/TypedBodyProgrammer.d.ts +0 -9
  89. package/lib/programmers/TypedBodyProgrammer.js +0 -94
  90. package/lib/programmers/TypedBodyProgrammer.js.map +0 -1
  91. package/lib/programmers/TypedFormDataBodyProgrammer.d.ts +0 -9
  92. package/lib/programmers/TypedFormDataBodyProgrammer.js +0 -65
  93. package/lib/programmers/TypedFormDataBodyProgrammer.js.map +0 -1
  94. package/lib/programmers/TypedHeadersProgrammer.d.ts +0 -9
  95. package/lib/programmers/TypedHeadersProgrammer.js +0 -38
  96. package/lib/programmers/TypedHeadersProgrammer.js.map +0 -1
  97. package/lib/programmers/TypedParamProgrammer.d.ts +0 -10
  98. package/lib/programmers/TypedParamProgrammer.js +0 -32
  99. package/lib/programmers/TypedParamProgrammer.js.map +0 -1
  100. package/lib/programmers/TypedQueryBodyProgrammer.d.ts +0 -9
  101. package/lib/programmers/TypedQueryBodyProgrammer.js +0 -74
  102. package/lib/programmers/TypedQueryBodyProgrammer.js.map +0 -1
  103. package/lib/programmers/TypedQueryProgrammer.d.ts +0 -9
  104. package/lib/programmers/TypedQueryProgrammer.js +0 -75
  105. package/lib/programmers/TypedQueryProgrammer.js.map +0 -1
  106. package/lib/programmers/TypedQueryRouteProgrammer.d.ts +0 -9
  107. package/lib/programmers/TypedQueryRouteProgrammer.js +0 -75
  108. package/lib/programmers/TypedQueryRouteProgrammer.js.map +0 -1
  109. package/lib/programmers/TypedRouteProgrammer.d.ts +0 -9
  110. package/lib/programmers/TypedRouteProgrammer.js +0 -79
  111. package/lib/programmers/TypedRouteProgrammer.js.map +0 -1
  112. package/lib/programmers/http/HttpAssertQuerifyProgrammer.d.ts +0 -9
  113. package/lib/programmers/http/HttpAssertQuerifyProgrammer.js +0 -39
  114. package/lib/programmers/http/HttpAssertQuerifyProgrammer.js.map +0 -1
  115. package/lib/programmers/http/HttpIsQuerifyProgrammer.d.ts +0 -9
  116. package/lib/programmers/http/HttpIsQuerifyProgrammer.js +0 -36
  117. package/lib/programmers/http/HttpIsQuerifyProgrammer.js.map +0 -1
  118. package/lib/programmers/http/HttpQuerifyProgrammer.d.ts +0 -9
  119. package/lib/programmers/http/HttpQuerifyProgrammer.js +0 -50
  120. package/lib/programmers/http/HttpQuerifyProgrammer.js.map +0 -1
  121. package/lib/programmers/http/HttpValidateQuerifyProgrammer.d.ts +0 -9
  122. package/lib/programmers/http/HttpValidateQuerifyProgrammer.js +0 -40
  123. package/lib/programmers/http/HttpValidateQuerifyProgrammer.js.map +0 -1
  124. package/lib/programmers/internal/CoreMetadataUtil.d.ts +0 -5
  125. package/lib/programmers/internal/CoreMetadataUtil.js +0 -19
  126. package/lib/programmers/internal/CoreMetadataUtil.js.map +0 -1
  127. package/lib/transformers/FileTransformer.d.ts +0 -5
  128. package/lib/transformers/FileTransformer.js +0 -80
  129. package/lib/transformers/FileTransformer.js.map +0 -1
  130. package/lib/transformers/MethodTransformer.d.ts +0 -8
  131. package/lib/transformers/MethodTransformer.js +0 -58
  132. package/lib/transformers/MethodTransformer.js.map +0 -1
  133. package/lib/transformers/NodeTransformer.d.ts +0 -8
  134. package/lib/transformers/NodeTransformer.js +0 -24
  135. package/lib/transformers/NodeTransformer.js.map +0 -1
  136. package/lib/transformers/ParameterDecoratorTransformer.d.ts +0 -9
  137. package/lib/transformers/ParameterDecoratorTransformer.js +0 -104
  138. package/lib/transformers/ParameterDecoratorTransformer.js.map +0 -1
  139. package/lib/transformers/ParameterTransformer.d.ts +0 -8
  140. package/lib/transformers/ParameterTransformer.js +0 -37
  141. package/lib/transformers/ParameterTransformer.js.map +0 -1
  142. package/lib/transformers/TypedRouteTransformer.d.ts +0 -9
  143. package/lib/transformers/TypedRouteTransformer.js +0 -68
  144. package/lib/transformers/TypedRouteTransformer.js.map +0 -1
  145. package/lib/transformers/WebSocketRouteTransformer.d.ts +0 -9
  146. package/lib/transformers/WebSocketRouteTransformer.js +0 -72
  147. package/lib/transformers/WebSocketRouteTransformer.js.map +0 -1
  148. package/src/decorators/internal/NoTransformConfigureError.ts +0 -2
  149. package/src/options/INestiaTransformOptions.ts +0 -34
  150. package/src/options/INestiaTransformProject.ts +0 -10
  151. package/src/programmers/PlainBodyProgrammer.ts +0 -72
  152. package/src/programmers/TypedBodyProgrammer.ts +0 -148
  153. package/src/programmers/TypedFormDataBodyProgrammer.ts +0 -118
  154. package/src/programmers/TypedHeadersProgrammer.ts +0 -65
  155. package/src/programmers/TypedParamProgrammer.ts +0 -33
  156. package/src/programmers/TypedQueryBodyProgrammer.ts +0 -113
  157. package/src/programmers/TypedQueryProgrammer.ts +0 -115
  158. package/src/programmers/TypedQueryRouteProgrammer.ts +0 -107
  159. package/src/programmers/TypedRouteProgrammer.ts +0 -103
  160. package/src/programmers/http/HttpAssertQuerifyProgrammer.ts +0 -74
  161. package/src/programmers/http/HttpIsQuerifyProgrammer.ts +0 -77
  162. package/src/programmers/http/HttpQuerifyProgrammer.ts +0 -110
  163. package/src/programmers/http/HttpValidateQuerifyProgrammer.ts +0 -78
  164. package/src/programmers/internal/CoreMetadataUtil.ts +0 -21
  165. package/src/transformers/FileTransformer.ts +0 -109
  166. package/src/transformers/MethodTransformer.ts +0 -103
  167. package/src/transformers/NodeTransformer.ts +0 -23
  168. package/src/transformers/ParameterDecoratorTransformer.ts +0 -143
  169. package/src/transformers/ParameterTransformer.ts +0 -57
  170. package/src/transformers/TypedRouteTransformer.ts +0 -85
  171. package/src/transformers/WebSocketRouteTransformer.ts +0 -120
@@ -0,0 +1,434 @@
1
+ package main
2
+
3
+ import (
4
+ "encoding/json"
5
+ "flag"
6
+ "fmt"
7
+ "io"
8
+ "os"
9
+ "path/filepath"
10
+ "regexp"
11
+ "time"
12
+
13
+ shimast "github.com/microsoft/typescript-go/shim/ast"
14
+ shimcompiler "github.com/microsoft/typescript-go/shim/compiler"
15
+ shimscanner "github.com/microsoft/typescript-go/shim/scanner"
16
+ "github.com/samchon/nestia/packages/core/native/plugin"
17
+ "github.com/samchon/ttsc/packages/ttsc/driver"
18
+ typiaadapter "github.com/samchon/typia/packages/typia/native/adapter"
19
+ )
20
+
21
+ func runBuild(args []string) int {
22
+ profile := os.Getenv("TTSC_NESTIA_PROFILE") != ""
23
+ var totalStarted time.Time
24
+ if profile {
25
+ totalStarted = time.Now()
26
+ }
27
+ fs := flag.NewFlagSet("build", flag.ContinueOnError)
28
+ fs.SetOutput(stderr)
29
+ tsconfigPath := fs.String("tsconfig", "tsconfig.json", "path to tsconfig.json")
30
+ cwdOverride := fs.String("cwd", "", "override the working directory")
31
+ quiet := fs.Bool("quiet", true, "suppress the per-call diagnostic summary")
32
+ verbose := fs.Bool("verbose", false, "print the per-call diagnostic summary")
33
+ emit := fs.Bool("emit", false, "force emitted .js files")
34
+ noEmit := fs.Bool("noEmit", false, "force analysis-only run with no file writes")
35
+ outDir := fs.String("outDir", "", "override compilerOptions.outDir")
36
+ manifestPath := fs.String("manifest", "", "write emitted file list as JSON")
37
+ pluginsJSON := fs.String("plugins-json", "", "ordered ttsc plugin payload")
38
+ if err := fs.Parse(args); err != nil {
39
+ return 2
40
+ }
41
+ if *emit && *noEmit {
42
+ fmt.Fprintln(stderr, "ttsc-nestia build: --emit and --noEmit are mutually exclusive")
43
+ return 2
44
+ }
45
+ if *verbose {
46
+ *quiet = false
47
+ }
48
+ plan, err := plugin.ParsePlan(*pluginsJSON)
49
+ if err != nil {
50
+ fmt.Fprintf(stderr, "ttsc-nestia build: %v\n", err)
51
+ return 2
52
+ }
53
+
54
+ cwd, ok := resolveCWD("ttsc-nestia build", *cwdOverride)
55
+ if !ok {
56
+ return 2
57
+ }
58
+ var started time.Time
59
+ if profile {
60
+ started = time.Now()
61
+ }
62
+ prog, diags, err := driver.LoadProgram(cwd, *tsconfigPath, driver.LoadProgramOptions{
63
+ ForceEmit: *emit,
64
+ ForceNoEmit: *noEmit,
65
+ OutDir: *outDir,
66
+ })
67
+ profileBuildStep(profile, "load-program", started)
68
+ if err != nil {
69
+ fmt.Fprintf(stderr, "ttsc-nestia build: %v\n", err)
70
+ return 2
71
+ }
72
+ if len(diags) > 0 {
73
+ driver.WritePrettyDiagnostics(stderr, diags, cwd)
74
+ return 2
75
+ }
76
+ defer prog.Close()
77
+ if profile {
78
+ started = time.Now()
79
+ }
80
+ if diags := prog.Diagnostics(); len(diags) > 0 {
81
+ profileBuildStep(profile, "diagnostics", started)
82
+ driver.WritePrettyDiagnostics(stderr, diags, cwd)
83
+ return 2
84
+ }
85
+ profileBuildStep(profile, "diagnostics", started)
86
+
87
+ shouldEmit := !prog.ParsedConfig.ParsedConfig.CompilerOptions.NoEmit.IsTrue()
88
+ if !*quiet {
89
+ fmt.Fprintf(
90
+ stdout,
91
+ "// ttsc-nestia build: tsconfig=%s cwd=%s core=%v sdk=%v typia=%v emit=%v\n",
92
+ *tsconfigPath,
93
+ cwd,
94
+ plan.Core,
95
+ plan.SDK,
96
+ plan.Typia,
97
+ shouldEmit,
98
+ )
99
+ }
100
+ if !shouldEmit {
101
+ return 0
102
+ }
103
+
104
+ rewrites := newNativeRewriteSet()
105
+ if profile {
106
+ started = time.Now()
107
+ }
108
+ sites, recognized, transformDiags := collectTypiaRewrites(
109
+ prog,
110
+ cwd,
111
+ shouldEmit,
112
+ *quiet,
113
+ "",
114
+ rewrites,
115
+ readTypiaPluginOptions(cwd, *tsconfigPath),
116
+ )
117
+ profileBuildStepCount(profile, "typia-rewrites", started, rewrites.Len())
118
+ if len(transformDiags) > 0 {
119
+ writeTypiaTransformDiagnostics(stderr, transformDiags, cwd)
120
+ return 3
121
+ }
122
+ beforeCore := rewrites.Len()
123
+ if profile {
124
+ started = time.Now()
125
+ }
126
+ coreDiags := collectNestiaCoreBuildRewrites(prog, plan, rewrites)
127
+ profileBuildStepCount(profile, "core-rewrites", started, rewrites.Len()-beforeCore)
128
+ if len(coreDiags) > 0 {
129
+ writeTypiaTransformDiagnostics(stderr, coreDiags, cwd)
130
+ return 3
131
+ }
132
+ if profile {
133
+ started = time.Now()
134
+ }
135
+ sdkRewrites, sdkDiags := collectNestiaSDKBuildRewrites(prog, plan)
136
+ profileBuildStepCount(profile, "sdk-rewrites", started, sdkRewrites.Len())
137
+ if len(sdkDiags) > 0 {
138
+ writeTypiaTransformDiagnostics(stderr, sdkDiags, cwd)
139
+ return 3
140
+ }
141
+ if profile {
142
+ started = time.Now()
143
+ }
144
+ newPathsRewriter(prog).applyAll(prog.SourceFiles())
145
+ profileBuildStep(profile, "paths-rewrite", started)
146
+
147
+ cursors := map[string]int{}
148
+ var nativePatchElapsed time.Duration
149
+ var sdkPatchElapsed time.Duration
150
+ var cleanupElapsed time.Duration
151
+ var writeElapsed time.Duration
152
+ writeFile := shimcompiler.WriteFile(func(fileName, text string, data *shimcompiler.WriteFileData) error {
153
+ _ = data
154
+ var patchStarted time.Time
155
+ if profile {
156
+ patchStarted = time.Now()
157
+ }
158
+ patched, err := rewrites.Apply(fileName, text, cursors)
159
+ if profile {
160
+ nativePatchElapsed += time.Since(patchStarted)
161
+ }
162
+ if err != nil {
163
+ return err
164
+ }
165
+ if profile {
166
+ patchStarted = time.Now()
167
+ }
168
+ patched, err = sdkRewrites.Apply(fileName, patched)
169
+ if profile {
170
+ sdkPatchElapsed += time.Since(patchStarted)
171
+ }
172
+ if err != nil {
173
+ return err
174
+ }
175
+ if profile {
176
+ patchStarted = time.Now()
177
+ }
178
+ patched = cleanupTransformedTextWithRuntimeAliases(patched, rewrites.RuntimeAliasesForOutput(fileName))
179
+ if profile {
180
+ cleanupElapsed += time.Since(patchStarted)
181
+ patchStarted = time.Now()
182
+ defer func() {
183
+ writeElapsed += time.Since(patchStarted)
184
+ }()
185
+ }
186
+ return driver.DefaultWriteFile(fileName, patched)
187
+ })
188
+ if profile {
189
+ started = time.Now()
190
+ }
191
+ res, eDiags, err := prog.EmitAllRaw(writeFile)
192
+ profileBuildStep(profile, "emit-total", started)
193
+ profileBuildDuration(profile, "emit-native-patch", nativePatchElapsed)
194
+ profileBuildDuration(profile, "emit-sdk-patch", sdkPatchElapsed)
195
+ profileBuildDuration(profile, "emit-cleanup", cleanupElapsed)
196
+ profileBuildDuration(profile, "emit-write", writeElapsed)
197
+ if err != nil {
198
+ fmt.Fprintf(stderr, "ttsc-nestia build: emit failed: %v\n", err)
199
+ return 3
200
+ }
201
+ emitHasError := false
202
+ for _, d := range eDiags {
203
+ fmt.Fprintln(stderr, " -", d.String())
204
+ if d.IsError() {
205
+ emitHasError = true
206
+ }
207
+ }
208
+ if emitHasError {
209
+ return 3
210
+ }
211
+ if *manifestPath != "" {
212
+ data, err := json.Marshal(res.EmittedFiles)
213
+ if err != nil {
214
+ fmt.Fprintf(stderr, "ttsc-nestia build: manifest marshal failed: %v\n", err)
215
+ return 3
216
+ }
217
+ if err := os.MkdirAll(filepath.Dir(*manifestPath), 0o755); err != nil {
218
+ fmt.Fprintf(stderr, "ttsc-nestia build: manifest mkdir failed: %v\n", err)
219
+ return 3
220
+ }
221
+ if err := os.WriteFile(*manifestPath, data, 0o644); err != nil {
222
+ fmt.Fprintf(stderr, "ttsc-nestia build: manifest write failed: %v\n", err)
223
+ return 3
224
+ }
225
+ }
226
+ if !*quiet {
227
+ fmt.Fprintf(stdout, "// ttsc-nestia build: typia recognized=%d total=%d rewrites=%d\n", recognized, sites, rewrites.Len())
228
+ }
229
+ profileBuildStep(profile, "total", totalStarted)
230
+ return 0
231
+ }
232
+
233
+ func runCheck(args []string) int {
234
+ fs := flag.NewFlagSet("check", flag.ContinueOnError)
235
+ fs.SetOutput(stderr)
236
+ tsconfigPath := fs.String("tsconfig", "tsconfig.json", "path to tsconfig.json")
237
+ cwdOverride := fs.String("cwd", "", "override the working directory")
238
+ pluginsJSON := fs.String("plugins-json", "", "ordered ttsc plugin payload")
239
+ if err := fs.Parse(args); err != nil {
240
+ return 2
241
+ }
242
+ if _, err := plugin.ParsePlan(*pluginsJSON); err != nil {
243
+ fmt.Fprintf(stderr, "ttsc-nestia check: %v\n", err)
244
+ return 2
245
+ }
246
+ cwd, ok := resolveCWD("ttsc-nestia check", *cwdOverride)
247
+ if !ok {
248
+ return 2
249
+ }
250
+ prog, diags, err := driver.LoadProgram(cwd, *tsconfigPath, driver.LoadProgramOptions{
251
+ ForceNoEmit: true,
252
+ })
253
+ if err != nil {
254
+ fmt.Fprintf(stderr, "ttsc-nestia check: %v\n", err)
255
+ return 2
256
+ }
257
+ if len(diags) > 0 {
258
+ driver.WritePrettyDiagnostics(stderr, diags, cwd)
259
+ return 2
260
+ }
261
+ defer prog.Close()
262
+ if diags := prog.Diagnostics(); len(diags) > 0 {
263
+ driver.WritePrettyDiagnostics(stderr, diags, cwd)
264
+ return 2
265
+ }
266
+ return 0
267
+ }
268
+
269
+ type typiaTransformDiagnostic struct {
270
+ File string
271
+ Line int
272
+ Column int
273
+ Code string
274
+ Message string
275
+ }
276
+
277
+ func (d typiaTransformDiagnostic) String(cwd string) string {
278
+ file := d.File
279
+ if rel, err := filepath.Rel(cwd, file); err == nil {
280
+ file = rel
281
+ }
282
+ if d.Line > 0 {
283
+ return fmt.Sprintf("%s:%d:%d - error TS(%s): %s", file, d.Line, d.Column, d.Code, d.Message)
284
+ }
285
+ return fmt.Sprintf("%s - error TS(%s): %s", file, d.Code, d.Message)
286
+ }
287
+
288
+ func writeTypiaTransformDiagnostics(out io.Writer, diagnostics []typiaTransformDiagnostic, cwd string) {
289
+ for _, diag := range diagnostics {
290
+ fmt.Fprintln(out, diag.String(cwd))
291
+ }
292
+ }
293
+
294
+ func profileBuildStep(enabled bool, name string, started time.Time) {
295
+ if enabled {
296
+ profileBuildDuration(enabled, name, time.Since(started))
297
+ }
298
+ }
299
+
300
+ func profileBuildStepCount(enabled bool, name string, started time.Time, count int) {
301
+ if enabled {
302
+ fmt.Fprintf(stderr, "ttsc-nestia profile: %s=%s count=%d\n", name, time.Since(started), count)
303
+ }
304
+ }
305
+
306
+ func profileBuildDuration(enabled bool, name string, elapsed time.Duration) {
307
+ if enabled {
308
+ fmt.Fprintf(stderr, "ttsc-nestia profile: %s=%s\n", name, elapsed)
309
+ }
310
+ }
311
+
312
+ func newTypiaTransformDiagnostic(site typiaadapter.CallSite, message string) typiaTransformDiagnostic {
313
+ line, column := 0, 0
314
+ if site.File != nil && site.Call != nil {
315
+ pos := site.Call.AsNode().Pos()
316
+ if pos >= 0 {
317
+ l, c := shimscanner.GetECMALineAndByteOffsetOfPosition(site.File, pos)
318
+ line, column = l+1, c+1
319
+ }
320
+ }
321
+ return typiaTransformDiagnostic{
322
+ File: site.FilePath,
323
+ Line: line,
324
+ Column: column,
325
+ Code: "typia." + site.Module + "." + site.Method,
326
+ Message: message,
327
+ }
328
+ }
329
+
330
+ func collectTypiaRewrites(
331
+ prog *driver.Program,
332
+ cwd string,
333
+ emit bool,
334
+ quiet bool,
335
+ onlyFile string,
336
+ rewrites *nativeRewriteSet,
337
+ pluginOptions typiaadapter.PluginOptions,
338
+ ) (int, int, []typiaTransformDiagnostic) {
339
+ sites := collectNestiaTypiaCallSites(prog.SourceFiles(), prog.Checker)
340
+ recognized := 0
341
+ diagnostics := []typiaTransformDiagnostic{}
342
+ for _, site := range sites {
343
+ if onlyFile != "" && filepath.ToSlash(site.FilePath) != filepath.ToSlash(onlyFile) {
344
+ continue
345
+ }
346
+ rel := site.FilePath
347
+ if abs, err := filepath.Rel(cwd, rel); err == nil {
348
+ rel = abs
349
+ }
350
+ if reason := typiaadapter.UnsupportedReason(site); reason != "" {
351
+ diagnostics = append(diagnostics, newTypiaTransformDiagnostic(site, reason))
352
+ continue
353
+ }
354
+ expr, handled, err := typiaadapter.EmitCallWithOptions(prog, site, pluginOptions)
355
+ if !handled {
356
+ diagnostics = append(diagnostics, newTypiaTransformDiagnostic(site, "method not covered"))
357
+ continue
358
+ }
359
+ if err != nil {
360
+ diagnostics = append(diagnostics, newTypiaTransformDiagnostic(site, err.Error()))
361
+ continue
362
+ }
363
+ expr = parenthesizeTypiaReplacement(site, expr)
364
+ rewrites.Add(nativeRewrite{
365
+ FilePath: site.FilePath,
366
+ RootName: site.RootName,
367
+ Namespaces: site.Namespaces,
368
+ Method: site.Method,
369
+ Replacement: expr,
370
+ ConsumeParens: true,
371
+ SourceStart: typiaBuildRewriteSortKey(site),
372
+ })
373
+ if !emit && !quiet {
374
+ fmt.Fprintf(stdout, "%s: typia.%s<T> -> %s\n", rel, site.Method, expr)
375
+ }
376
+ recognized++
377
+ }
378
+ return len(sites), recognized, diagnostics
379
+ }
380
+
381
+ func typiaBuildRewriteSortKey(site typiaadapter.CallSite) int {
382
+ node := site.Call.AsNode()
383
+ if node == nil {
384
+ return 0
385
+ }
386
+ insideDecorator := false
387
+ classEnd := 0
388
+ for current := node.Parent; current != nil; current = current.Parent {
389
+ if current.Kind == nestiaCoreKindDecorator {
390
+ insideDecorator = true
391
+ }
392
+ if current.Kind == shimast.KindClassDeclaration || current.Kind == shimast.KindClassExpression {
393
+ classEnd = current.End()
394
+ break
395
+ }
396
+ }
397
+ if insideDecorator == false {
398
+ return node.Pos()
399
+ }
400
+ if classEnd != 0 {
401
+ return classEnd + node.Pos()
402
+ }
403
+ return node.Pos() + 1_000_000_000
404
+ }
405
+
406
+ func readTypiaPluginOptions(cwd, tsconfigPath string) typiaadapter.PluginOptions {
407
+ path := tsconfigPath
408
+ if !filepath.IsAbs(path) {
409
+ path = filepath.Join(cwd, path)
410
+ }
411
+ data, err := os.ReadFile(path)
412
+ if err != nil {
413
+ return typiaadapter.PluginOptions{}
414
+ }
415
+ text := string(data)
416
+ return typiaadapter.PluginOptions{
417
+ Functional: regexp.MustCompile(`(?s)"functional"\s*:\s*true`).MatchString(text),
418
+ Numeric: regexp.MustCompile(`(?s)"numeric"\s*:\s*true`).MatchString(text),
419
+ Finite: regexp.MustCompile(`(?s)"finite"\s*:\s*true`).MatchString(text),
420
+ Undefined: regexp.MustCompile(`(?s)"undefined"\s*:\s*true`).MatchString(text),
421
+ }
422
+ }
423
+
424
+ func resolveCWD(label string, cwdOverride string) (string, bool) {
425
+ if cwdOverride != "" {
426
+ return cwdOverride, true
427
+ }
428
+ cwd, err := os.Getwd()
429
+ if err != nil {
430
+ fmt.Fprintf(stderr, "%s: cwd: %v\n", label, err)
431
+ return "", false
432
+ }
433
+ return cwd, true
434
+ }