typia 13.0.0-dev.20260430 → 13.0.0-dev.20260501

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.
@@ -2,6 +2,7 @@ package main
2
2
 
3
3
  import (
4
4
  "bytes"
5
+ "encoding/json"
5
6
  "flag"
6
7
  "fmt"
7
8
  "os"
@@ -28,10 +29,6 @@ func runTransform(args []string) int {
28
29
  if err := fs.Parse(args); err != nil {
29
30
  return 2
30
31
  }
31
- if *file == "" {
32
- fmt.Fprintln(stderr, "ttsc-typia transform: --file is required")
33
- return 2
34
- }
35
32
  if *rewriteMode != "none" && *rewriteMode != "typia" {
36
33
  fmt.Fprintf(stderr, "ttsc-typia transform: unknown --rewrite-mode value %q\n", *rewriteMode)
37
34
  return 2
@@ -63,6 +60,14 @@ func runTransform(args []string) int {
63
60
  }
64
61
  defer prog.Close()
65
62
 
63
+ if *file == "" {
64
+ if *out != "" {
65
+ fmt.Fprintln(stderr, "ttsc-typia transform: --out requires --file")
66
+ return 2
67
+ }
68
+ return runTransformProject(prog, cwd, *rewriteMode, *tsconfigPath)
69
+ }
70
+
66
71
  absFile := *file
67
72
  if !filepath.IsAbs(absFile) {
68
73
  absFile = filepath.Join(cwd, absFile)
@@ -134,12 +139,92 @@ func defaultTransformOutput() string {
134
139
  return "js"
135
140
  }
136
141
 
142
+ type transformProjectOutput struct {
143
+ Diagnostics []transformCompilerDiagnostic `json:"diagnostics,omitempty"`
144
+ TypeScript map[string]string `json:"typescript"`
145
+ }
146
+
147
+ type transformCompilerDiagnostic struct {
148
+ File *string `json:"file"`
149
+ Category string `json:"category"`
150
+ Code string `json:"code"`
151
+ Line int `json:"line,omitempty"`
152
+ Character int `json:"character,omitempty"`
153
+ MessageText string `json:"messageText"`
154
+ }
155
+
137
156
  type transformSourceRewrite struct {
138
157
  start int
139
158
  end int
140
159
  replacement string
141
160
  }
142
161
 
162
+ func runTransformProject(
163
+ prog *driver.Program,
164
+ cwd string,
165
+ rewriteMode string,
166
+ tsconfigPath string,
167
+ ) int {
168
+ rewrites := map[string][]transformSourceRewrite{}
169
+ diagnostics := []transformCompilerDiagnostic{}
170
+ if rewriteMode == "typia" {
171
+ grouped, diags := collectTypiaSourceRewriteMap(
172
+ prog,
173
+ readTypiaPluginOptions(cwd, tsconfigPath),
174
+ )
175
+ rewrites = grouped
176
+ for _, diag := range diags {
177
+ diagnostics = append(diagnostics, transformDiagnosticToCompilerDiagnostic(diag))
178
+ }
179
+ }
180
+
181
+ output := transformProjectOutput{
182
+ Diagnostics: diagnostics,
183
+ TypeScript: map[string]string{},
184
+ }
185
+ for _, file := range prog.SourceFiles() {
186
+ filename := filepath.ToSlash(file.FileName())
187
+ source, ok := sourceFileText(file)
188
+ if !ok {
189
+ output.Diagnostics = append(
190
+ output.Diagnostics,
191
+ newTransformCompilerDiagnostic(
192
+ filename,
193
+ 0,
194
+ 0,
195
+ "typia.transform",
196
+ "source text is unavailable",
197
+ ),
198
+ )
199
+ continue
200
+ }
201
+ transformed, err := applySourceRewrites(source, rewrites[filename])
202
+ if err != nil {
203
+ output.Diagnostics = append(
204
+ output.Diagnostics,
205
+ newTransformCompilerDiagnostic(
206
+ filename,
207
+ 0,
208
+ 0,
209
+ "typia.transform",
210
+ err.Error(),
211
+ ),
212
+ )
213
+ continue
214
+ }
215
+ output.TypeScript[sourceFileKey(cwd, filename)] = cleanupTypeScriptTransformText(transformed)
216
+ }
217
+
218
+ if err := json.NewEncoder(stdout).Encode(output); err != nil {
219
+ fmt.Fprintf(stderr, "ttsc-typia transform: encode output: %v\n", err)
220
+ return 3
221
+ }
222
+ if len(output.Diagnostics) > 0 {
223
+ return 3
224
+ }
225
+ return 0
226
+ }
227
+
143
228
  func runTransformTypeScript(
144
229
  prog *driver.Program,
145
230
  cwd string,
@@ -241,6 +326,38 @@ func collectTypiaSourceRewrites(
241
326
  return rewrites, diagnostics
242
327
  }
243
328
 
329
+ func collectTypiaSourceRewriteMap(
330
+ prog *driver.Program,
331
+ pluginOptions typiaadapter.PluginOptions,
332
+ ) (map[string][]transformSourceRewrite, []typiaTransformDiagnostic) {
333
+ sites := typiaadapter.CollectCallSites(prog.SourceFiles(), prog.Checker)
334
+ rewrites := map[string][]transformSourceRewrite{}
335
+ diagnostics := []typiaTransformDiagnostic{}
336
+ for _, site := range sites {
337
+ file := filepath.ToSlash(site.FilePath)
338
+ if reason := typiaadapter.UnsupportedReason(site); reason != "" {
339
+ diagnostics = append(diagnostics, newTypiaTransformDiagnostic(site, reason))
340
+ continue
341
+ }
342
+ expr, handled, err := typiaadapter.EmitCallWithOptionsPreservingTypes(prog, site, pluginOptions)
343
+ if !handled {
344
+ diagnostics = append(diagnostics, newTypiaTransformDiagnostic(site, "method not covered"))
345
+ continue
346
+ }
347
+ if err != nil {
348
+ diagnostics = append(diagnostics, newTypiaTransformDiagnostic(site, err.Error()))
349
+ continue
350
+ }
351
+ node := site.Call.AsNode()
352
+ rewrites[file] = append(rewrites[file], transformSourceRewrite{
353
+ start: node.Pos(),
354
+ end: node.End(),
355
+ replacement: expr,
356
+ })
357
+ }
358
+ return rewrites, diagnostics
359
+ }
360
+
244
361
  func applySourceRewrites(source string, rewrites []transformSourceRewrite) (string, error) {
245
362
  sort.SliceStable(rewrites, func(i, j int) bool {
246
363
  return rewrites[i].start > rewrites[j].start
@@ -288,3 +405,45 @@ func cleanupTypeScriptTransformText(text string) string {
288
405
  }
289
406
  return text
290
407
  }
408
+
409
+ func sourceFileKey(cwd string, file string) string {
410
+ rel, err := filepath.Rel(cwd, filepath.FromSlash(file))
411
+ if err != nil || rel == ".." || strings.HasPrefix(rel, ".."+string(os.PathSeparator)) {
412
+ return filepath.ToSlash(file)
413
+ }
414
+ return filepath.ToSlash(rel)
415
+ }
416
+
417
+ func transformDiagnosticToCompilerDiagnostic(
418
+ diag typiaTransformDiagnostic,
419
+ ) transformCompilerDiagnostic {
420
+ return newTransformCompilerDiagnostic(
421
+ diag.File,
422
+ diag.Line,
423
+ diag.Column,
424
+ diag.Code,
425
+ diag.Message,
426
+ )
427
+ }
428
+
429
+ func newTransformCompilerDiagnostic(
430
+ file string,
431
+ line int,
432
+ character int,
433
+ code string,
434
+ message string,
435
+ ) transformCompilerDiagnostic {
436
+ var ptr *string
437
+ if file != "" {
438
+ normalized := filepath.ToSlash(file)
439
+ ptr = &normalized
440
+ }
441
+ return transformCompilerDiagnostic{
442
+ File: ptr,
443
+ Category: "error",
444
+ Code: code,
445
+ Line: line,
446
+ Character: character,
447
+ MessageText: message,
448
+ }
449
+ }
@@ -100,7 +100,7 @@ func literalFactory_fieldName(name string) string {
100
100
  func literalFactory_writeObject(obj map[string]any) *shimast.Node {
101
101
  keys := make([]string, 0, len(obj))
102
102
  for key, value := range obj {
103
- if value == nil {
103
+ if literalFactory_isNilLike(value) {
104
104
  continue
105
105
  }
106
106
  keys = append(keys, key)
@@ -190,6 +190,19 @@ func literalFactory_propertyRank(key string) int {
190
190
  return 1_000
191
191
  }
192
192
 
193
+ func literalFactory_isNilLike(value any) bool {
194
+ if value == nil {
195
+ return true
196
+ }
197
+ reflected := reflect.ValueOf(value)
198
+ switch reflected.Kind() {
199
+ case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice:
200
+ return reflected.IsNil()
201
+ default:
202
+ return false
203
+ }
204
+ }
205
+
193
206
  func literalFactory_writeArray(array []any) *shimast.Node {
194
207
  elements := make([]*shimast.Node, 0, len(array))
195
208
  for _, elem := range array {
@@ -329,8 +329,7 @@ func llmApplicationProgrammer_writeParameters(props struct {
329
329
  }) any {
330
330
  rawParameters, _ := props.Function["parameters"].([]any)
331
331
  if len(rawParameters) == 0 {
332
- return llmParametersProgrammer_write_parameters_expression(
333
- props.Context,
332
+ return llmApplicationProgrammer_convertParameters(
334
333
  props.Components,
335
334
  nativeiterate.JsonSchema{"type": "object", "properties": map[string]any{}, "additionalProperties": false, "required": []any{}},
336
335
  props.Config,
@@ -355,7 +354,7 @@ func llmApplicationProgrammer_writeParameters(props struct {
355
354
  schema["description"] = description
356
355
  }
357
356
  }
358
- return llmParametersProgrammer_write_parameters_expression(props.Context, props.Components, schema, props.Config)
357
+ return llmApplicationProgrammer_convertParameters(props.Components, schema, props.Config)
359
358
  }
360
359
 
361
360
  func llmApplicationProgrammer_writeOutput(props struct {
@@ -370,7 +369,20 @@ func llmApplicationProgrammer_writeOutput(props struct {
370
369
  props.Schema["description"] = desc
371
370
  }
372
371
  }
373
- return llmParametersProgrammer_write_parameters_expression(props.Context, props.Components, props.Schema, props.Config)
372
+ return llmApplicationProgrammer_convertParameters(props.Components, props.Schema, props.Config)
373
+ }
374
+
375
+ func llmApplicationProgrammer_convertParameters(
376
+ components *nativeiterate.OpenApi_IComponents,
377
+ schema nativeiterate.JsonSchema,
378
+ config map[string]any,
379
+ ) map[string]any {
380
+ defs := map[string]any{}
381
+ target := llmParametersProgrammer_dereference_schema(schema, components)
382
+ output := llmSchemaProgrammer_convert_schema_config(target, components, defs, config)
383
+ output["additionalProperties"] = false
384
+ output["$defs"] = defs
385
+ return output
374
386
  }
375
387
 
376
388
  func llmApplicationProgrammer_writeValidator(props struct {
@@ -45,27 +45,13 @@ func (llmParametersProgrammerNamespace) Write(props LlmParametersProgrammer_IWri
45
45
  }
46
46
 
47
47
  func (llmParametersProgrammerNamespace) WriteParametersExpression(props LlmParametersProgrammer_IWriteProps) *shimast.Node {
48
- collection := nativejson.JsonSchemasProgrammer.WriteSchemas(struct {
49
- Version string
50
- Metadatas []*schemametadata.MetadataSchema
48
+ return nativefactories.LiteralFactory.Write(LlmParametersProgrammer.WriteParameters(struct {
49
+ Metadata *schemametadata.MetadataSchema
50
+ Config map[string]any
51
51
  }{
52
- Version: "3.1",
53
- Metadatas: []*schemametadata.MetadataSchema{props.Metadata},
54
- })
55
- if len(collection.Schemas) == 0 {
56
- return llmParametersProgrammer_write_parameters_expression(
57
- props.Context,
58
- &nativeiterate.OpenApi_IComponents{Schemas: map[string]nativeiterate.JsonSchema{}},
59
- nativeiterate.JsonSchema{"type": "object", "properties": map[string]any{}, "required": []any{}},
60
- props.Config,
61
- )
62
- }
63
- return llmParametersProgrammer_write_parameters_expression(
64
- props.Context,
65
- collection.Components,
66
- llmParametersProgrammer_dereference_schema(collection.Schemas[0], collection.Components),
67
- props.Config,
68
- )
52
+ Metadata: props.Metadata,
53
+ Config: props.Config,
54
+ }))
69
55
  }
70
56
 
71
57
  func (llmParametersProgrammerNamespace) WriteParameters(props struct {
@@ -84,14 +70,14 @@ func (llmParametersProgrammerNamespace) WriteParameters(props struct {
84
70
  }
85
71
  schema := collection.Schemas[0]
86
72
  if typ, ok := schema["type"].(string); ok && typ == "object" {
87
- return llmParametersProgrammer_convert_parameters(schema, collection.Components)
73
+ return llmParametersProgrammer_convert_parameters(schema, collection.Components, props.Config)
88
74
  }
89
75
  if ref, ok := schema["$ref"].(string); ok {
90
76
  name := ref[strings.LastIndex(ref, "/")+1:]
91
77
  if collection.Components != nil && collection.Components.Schemas != nil {
92
78
  if target, found := collection.Components.Schemas[name]; found {
93
79
  if typ, ok := target["type"].(string); ok && typ == "object" {
94
- return llmParametersProgrammer_convert_parameters(target, collection.Components)
80
+ return llmParametersProgrammer_convert_parameters(target, collection.Components, props.Config)
95
81
  }
96
82
  }
97
83
  }
@@ -133,28 +119,15 @@ func (llmParametersProgrammerNamespace) Validate(props struct {
133
119
  return output
134
120
  }
135
121
 
136
- func llmParametersProgrammer_convert_parameters(schema nativeiterate.JsonSchema, components *nativeiterate.OpenApi_IComponents) map[string]any {
122
+ func llmParametersProgrammer_convert_parameters(schema nativeiterate.JsonSchema, components *nativeiterate.OpenApi_IComponents, config map[string]any) map[string]any {
137
123
  defs := map[string]any{}
138
124
  target := llmParametersProgrammer_dereference_schema(schema, components)
139
- output := llmSchemaProgrammer_convert_schema(target, components, defs)
125
+ output := llmSchemaProgrammer_convert_schema_config(target, components, defs, config)
140
126
  output["additionalProperties"] = false
141
127
  output["$defs"] = defs
142
128
  return output
143
129
  }
144
130
 
145
- func llmParametersProgrammer_write_parameters_expression(
146
- context nativecontext.ITypiaContext,
147
- components *nativeiterate.OpenApi_IComponents,
148
- schema nativeiterate.JsonSchema,
149
- config map[string]any,
150
- ) *shimast.Node {
151
- return llmProgrammer_converter_result(context, "parameters", "typia.llm.parameters", []*shimast.Node{
152
- llmProgrammer_object_property("config", llmProgrammer_config_expression(config)),
153
- llmProgrammer_object_property("components", nativefactories.LiteralFactory.Write(components)),
154
- llmProgrammer_object_property("schema", nativefactories.LiteralFactory.Write(schema)),
155
- })
156
- }
157
-
158
131
  func llmParametersProgrammer_dereference_schema(schema nativeiterate.JsonSchema, components *nativeiterate.OpenApi_IComponents) nativeiterate.JsonSchema {
159
132
  ref, ok := schema["$ref"].(string)
160
133
  if ok == false || components == nil || components.Schemas == nil {