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.
- package/lib/executable/TypiaGenerateWizard.js +55 -8
- package/lib/executable/TypiaGenerateWizard.js.map +1 -1
- package/lib/executable/TypiaGenerateWizard2.mjs +55 -8
- package/lib/executable/TypiaGenerateWizard2.mjs.map +1 -1
- package/lib/transform.d.ts +2 -13
- package/lib/transform.js +4 -11
- package/lib/transform.js.map +1 -1
- package/lib/transform2.mjs +6 -14
- package/lib/transform2.mjs.map +1 -1
- package/native/adapter/cleanup.go +2 -19
- package/native/cmd/ttsc-typia/transform.go +163 -4
- package/native/core/factories/LiteralFactory.go +14 -1
- package/native/core/programmers/llm/LlmApplicationProgrammer.go +16 -4
- package/native/core/programmers/llm/LlmParametersProgrammer.go +10 -37
- package/native/core/programmers/llm/LlmSchemaProgrammer.go +510 -153
- package/package.json +4 -4
- package/src/executable/TypiaGenerateWizard.ts +78 -9
- package/src/transform.ts +6 -11
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
return nativefactories.LiteralFactory.Write(LlmParametersProgrammer.WriteParameters(struct {
|
|
49
|
+
Metadata *schemametadata.MetadataSchema
|
|
50
|
+
Config map[string]any
|
|
51
51
|
}{
|
|
52
|
-
|
|
53
|
-
|
|
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 :=
|
|
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 {
|