typia 14.0.4 → 14.0.5

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.
@@ -0,0 +1,206 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "os/exec"
6
+ "path/filepath"
7
+ "strings"
8
+ "testing"
9
+ )
10
+
11
+ // TestRecursiveContainerHelperIndexTransform verifies recursive container helpers
12
+ // remain callable when ordinary containers precede them in collection order.
13
+ func TestRecursiveContainerHelperIndexTransform(t *testing.T) {
14
+ project := recursiveContainerHelperIndexProject(t)
15
+ js := recursiveContainerHelperIndexTransform(t, project)
16
+ recursiveContainerHelperIndexRunRuntimeCases(t, project, js)
17
+ }
18
+
19
+ func recursiveContainerHelperIndexProject(t *testing.T) string {
20
+ t.Helper()
21
+ root := ttscTypiaTestRepoRoot(t)
22
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
23
+ if err := os.MkdirAll(base, 0o755); err != nil {
24
+ t.Fatalf("mkdir temp base: %v", err)
25
+ }
26
+ dir, err := os.MkdirTemp(base, "recursive-container-helper-index-")
27
+ if err != nil {
28
+ t.Fatalf("create temp fixture: %v", err)
29
+ }
30
+ t.Cleanup(func() { _ = os.RemoveAll(dir) })
31
+ src := filepath.Join(dir, "src")
32
+ if err := os.MkdirAll(src, 0o755); err != nil {
33
+ t.Fatalf("mkdir fixture src: %v", err)
34
+ }
35
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(recursiveContainerHelperIndexTSConfig), 0o644); err != nil {
36
+ t.Fatalf("write tsconfig: %v", err)
37
+ }
38
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(recursiveContainerHelperIndexSource), 0o644); err != nil {
39
+ t.Fatalf("write source: %v", err)
40
+ }
41
+ return dir
42
+ }
43
+
44
+ func recursiveContainerHelperIndexTransform(t *testing.T, project string) string {
45
+ t.Helper()
46
+ out, errText, code := ttscTypiaTestCapture(func() int {
47
+ return runTransform([]string{
48
+ "--cwd", project,
49
+ "--tsconfig", "tsconfig.json",
50
+ "--file", "src/main.ts",
51
+ "--output", "js",
52
+ })
53
+ })
54
+ if code != 0 {
55
+ t.Fatalf("recursive container helper transform failed: code=%d stderr=\n%s", code, errText)
56
+ }
57
+ return out
58
+ }
59
+
60
+ func recursiveContainerHelperIndexRunRuntimeCases(t *testing.T, project string, js string) {
61
+ t.Helper()
62
+ node, err := exec.LookPath("node")
63
+ if err != nil {
64
+ t.Skip("node executable not found")
65
+ }
66
+ runtimeDir := filepath.Join(project, "runtime")
67
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
68
+ t.Fatalf("mkdir runtime dir: %v", err)
69
+ }
70
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
71
+ if err := os.WriteFile(filepath.Join(runtimeDir, "feature-stub.cjs"), []byte(recursiveContainerHelperIndexFeatureStub), 0o644); err != nil {
72
+ t.Fatalf("write feature stub: %v", err)
73
+ }
74
+ for _, helper := range []string{
75
+ "_jsonStringifyNumber",
76
+ "_jsonStringifyString",
77
+ "_randomArray",
78
+ "_randomNumber",
79
+ "_randomPick",
80
+ "_throwTypeGuardError",
81
+ } {
82
+ js = strings.ReplaceAll(
83
+ js,
84
+ `require("typia/lib/internal/`+helper+`")`,
85
+ `require("./feature-stub.cjs")`,
86
+ )
87
+ }
88
+ if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(ttscTypiaTestRewriteCommonJS(t, js)), 0o644); err != nil {
89
+ t.Fatalf("write runtime module: %v", err)
90
+ }
91
+ runner := filepath.Join(runtimeDir, "run.cjs")
92
+ if err := os.WriteFile(runner, []byte(recursiveContainerHelperIndexRuntimeRunner), 0o644); err != nil {
93
+ t.Fatalf("write runtime runner: %v", err)
94
+ }
95
+ cmd := exec.Command(node, runner)
96
+ cmd.Dir = runtimeDir
97
+ output, err := cmd.CombinedOutput()
98
+ if err != nil {
99
+ t.Fatalf("recursive container helper runtime cases failed: %v\n%s", err, output)
100
+ }
101
+ }
102
+
103
+ const recursiveContainerHelperIndexTSConfig = `{
104
+ "compilerOptions": {
105
+ "target": "ES2022",
106
+ "module": "commonjs",
107
+ "moduleResolution": "bundler",
108
+ "ignoreDeprecations": "6.0",
109
+ "types": ["*"],
110
+ "esModuleInterop": true,
111
+ "strict": true,
112
+ "skipLibCheck": true
113
+ },
114
+ "include": ["src"]
115
+ }
116
+ `
117
+
118
+ const recursiveContainerHelperIndexSource = `import typia from "typia";
119
+
120
+ type JsonPrimitive = string | number | boolean | null;
121
+ type JsonArray = JsonValue[];
122
+ type JsonObject = { [key: string]: JsonValue };
123
+ type JsonValue = JsonPrimitive | JsonArray | JsonObject;
124
+
125
+ interface ArrayWitness {
126
+ ordinary: string[];
127
+ value: JsonValue;
128
+ }
129
+
130
+ type RecursiveTuple = [string, RecursiveTuple | null];
131
+ interface TupleWitness {
132
+ ordinary: [number];
133
+ value: RecursiveTuple;
134
+ }
135
+
136
+ type RandomArray = Array<string | RandomArray>;
137
+ interface RandomArrayWitness {
138
+ ordinary: string[];
139
+ value: RandomArray;
140
+ }
141
+
142
+ export const isArray = typia.createIs<ArrayWitness>();
143
+ export const isTuple = typia.createIs<TupleWitness>();
144
+ export const stringifyArray = typia.json.createStringify<ArrayWitness>();
145
+ export const stringifyTuple = typia.json.createStringify<TupleWitness>();
146
+ export const camelArray = typia.notations.createCamel<ArrayWitness>();
147
+ export const camelTuple = typia.notations.createCamel<TupleWitness>();
148
+ export const cloneArray = typia.plain.createClone<ArrayWitness>();
149
+ export const cloneTuple = typia.plain.createClone<TupleWitness>();
150
+ export const classifyArray = typia.plain.createClassify<ArrayWitness>();
151
+ export const classifyTuple = typia.plain.createClassify<TupleWitness>();
152
+ export const pruneArray = typia.plain.createPrune<ArrayWitness>();
153
+ export const pruneTuple = typia.plain.createPrune<TupleWitness>();
154
+ export const randomArray = typia.createRandom<RandomArrayWitness>({
155
+ array: () => [],
156
+ string: () => "generated",
157
+ });
158
+ export const randomTuple = typia.createRandom<TupleWitness>({
159
+ boolean: () => false,
160
+ number: () => 1,
161
+ string: () => "generated",
162
+ });
163
+ `
164
+
165
+ const recursiveContainerHelperIndexRuntimeRunner = `const mod = require("./main.cjs");
166
+
167
+ const arrayValue = { ordinary: ["a"], value: [1, { nested: [true, null] }] };
168
+ const tupleValue = { ordinary: [1], value: ["root", ["child", null]] };
169
+
170
+ const expect = (label, actual, expected) => {
171
+ if (actual !== expected) {
172
+ throw new Error(label + ": expected " + expected + ", got " + actual);
173
+ }
174
+ };
175
+
176
+ expect("is array", mod.isArray(arrayValue), true);
177
+ expect("is tuple", mod.isTuple(tupleValue), true);
178
+ expect("stringify array", mod.stringifyArray(arrayValue), JSON.stringify(arrayValue));
179
+ expect("stringify tuple", mod.stringifyTuple(tupleValue), JSON.stringify(tupleValue));
180
+ expect("notation array", mod.camelArray(arrayValue).value[1].nested[0], true);
181
+ expect("notation tuple", mod.camelTuple(tupleValue).value[1][0], "child");
182
+ expect("clone array", mod.cloneArray(arrayValue).value[1].nested[1], null);
183
+ expect("clone tuple", mod.cloneTuple(tupleValue).value[1][0], "child");
184
+ expect("classify array", mod.classifyArray(arrayValue).value[1].nested[0], true);
185
+ expect("classify tuple", mod.classifyTuple(tupleValue).value[1][0], "child");
186
+
187
+ const prunedArray = { ...arrayValue, extra: true };
188
+ mod.pruneArray(prunedArray);
189
+ expect("prune array", "extra" in prunedArray, false);
190
+ const prunedTuple = { ...tupleValue, extra: true };
191
+ mod.pruneTuple(prunedTuple);
192
+ expect("prune tuple", "extra" in prunedTuple, false);
193
+
194
+ const generatedArray = mod.randomArray();
195
+ expect("random array", Array.isArray(generatedArray.value), true);
196
+ const generatedTuple = mod.randomTuple();
197
+ expect("random tuple", generatedTuple.value[0], "generated");
198
+ `
199
+
200
+ const recursiveContainerHelperIndexFeatureStub = `module.exports._jsonStringifyNumber = (value) => Number.isFinite(value) ? value : null;
201
+ module.exports._jsonStringifyString = (value) => JSON.stringify(value);
202
+ module.exports._randomArray = () => [];
203
+ module.exports._randomNumber = () => 1;
204
+ module.exports._randomPick = (values) => values[0];
205
+ module.exports._throwTypeGuardError = (props) => { throw Object.assign(new Error(props.expected), props); };
206
+ `
@@ -0,0 +1,88 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "path/filepath"
6
+ "strings"
7
+ "testing"
8
+ )
9
+
10
+ // TestWrongTypeTagTargetDiagnostic verifies a rejected tag names its declared
11
+ // target once and leaves a compatible tag untouched.
12
+ func TestWrongTypeTagTargetDiagnostic(t *testing.T) {
13
+ project := wrongTypeTagTargetDiagnosticProject(t)
14
+ _, errText, code := ttscTypiaTestCapture(func() int {
15
+ return runTransform([]string{
16
+ "--cwd", project,
17
+ "--tsconfig", "tsconfig.json",
18
+ "--file", "src/main.ts",
19
+ "--output", "js",
20
+ })
21
+ })
22
+ if code == 0 {
23
+ t.Fatal("wrong-target tag unexpectedly transformed without diagnostics")
24
+ }
25
+ const expected = `the property ["typia.tag"] target must contain array type.`
26
+ if count := strings.Count(errText, expected); count != 1 {
27
+ t.Fatalf("wrong-target diagnostic count mismatch: got %d, want 1\n%s", count, errText)
28
+ }
29
+ if count := strings.Count(errText, "Payload.invalid:"); count != 1 {
30
+ t.Fatalf("diagnostic ownership mismatch: got %d, want 1\n%s", count, errText)
31
+ }
32
+ if strings.Contains(errText, "target must contain boolean type") {
33
+ t.Fatalf("diagnostic named the host type:\n%s", errText)
34
+ }
35
+ if strings.Contains(errText, "Payload.valid:") {
36
+ t.Fatalf("valid array control produced a diagnostic:\n%s", errText)
37
+ }
38
+ }
39
+
40
+ func wrongTypeTagTargetDiagnosticProject(t *testing.T) string {
41
+ t.Helper()
42
+ root := ttscTypiaTestRepoRoot(t)
43
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
44
+ if err := os.MkdirAll(base, 0o755); err != nil {
45
+ t.Fatalf("mkdir temp base: %v", err)
46
+ }
47
+ project, err := os.MkdirTemp(base, "wrong-tag-target-")
48
+ if err != nil {
49
+ t.Fatalf("create temp fixture: %v", err)
50
+ }
51
+ t.Cleanup(func() { _ = os.RemoveAll(project) })
52
+ src := filepath.Join(project, "src")
53
+ if err := os.MkdirAll(src, 0o755); err != nil {
54
+ t.Fatalf("mkdir fixture src: %v", err)
55
+ }
56
+ if err := os.WriteFile(filepath.Join(project, "tsconfig.json"), []byte(wrongTypeTagTargetDiagnosticTSConfig), 0o644); err != nil {
57
+ t.Fatalf("write tsconfig: %v", err)
58
+ }
59
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(wrongTypeTagTargetDiagnosticSource), 0o644); err != nil {
60
+ t.Fatalf("write source: %v", err)
61
+ }
62
+ return project
63
+ }
64
+
65
+ const wrongTypeTagTargetDiagnosticTSConfig = `{
66
+ "compilerOptions": {
67
+ "target": "ES2022",
68
+ "module": "commonjs",
69
+ "moduleResolution": "bundler",
70
+ "ignoreDeprecations": "6.0",
71
+ "types": ["*"],
72
+ "esModuleInterop": true,
73
+ "strict": true,
74
+ "skipLibCheck": true
75
+ },
76
+ "include": ["src"]
77
+ }
78
+ `
79
+
80
+ const wrongTypeTagTargetDiagnosticSource = `import typia, { tags } from "typia";
81
+
82
+ interface Payload {
83
+ invalid: boolean & tags.MinItems<1>;
84
+ valid: string[] & tags.MinItems<1>;
85
+ }
86
+
87
+ export const test = (input: unknown) => typia.is<Payload>(input);
88
+ `
@@ -2,6 +2,7 @@ package factories
2
2
 
3
3
  import (
4
4
  "fmt"
5
+ "reflect"
5
6
  "strings"
6
7
 
7
8
  schemametadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
@@ -162,12 +163,15 @@ func (metadataTypeTagFactoryNamespace) Analyze(props struct {
162
163
  if tag == nil {
163
164
  continue
164
165
  }
165
- target := ""
166
- if metadataTypeTagFactory_includes(tag.Target, props.Type) {
167
- target = props.Type
166
+ if metadataTypeTagFactory_includes(tag.Target, props.Type) == false {
167
+ report(struct {
168
+ Property *string
169
+ Message string
170
+ }{Property: nil, Message: metadataTypeTagFactory_target_message(tag.Target)})
171
+ continue
168
172
  }
169
173
  output = append(output, schemametadata.IMetadataTypeTag{
170
- Target: target,
174
+ Target: props.Type,
171
175
  Name: tag.Name,
172
176
  Kind: tag.Kind,
173
177
  Value: tag.Value,
@@ -195,7 +199,7 @@ func (metadataTypeTagFactoryNamespace) Analyze(props struct {
195
199
  for _, object := range props.Objects {
196
200
  names = append(names, object.Name)
197
201
  }
198
- *props.Errors = append(*props.Errors, MetadataFactory_IError{
202
+ metadataTypeTagFactory_append_error(props.Errors, MetadataFactory_IError{
199
203
  Name: strings.Join(names, " & "),
200
204
  Explore: props.Explore,
201
205
  Messages: messages,
@@ -218,10 +222,14 @@ func (metadataTypeTagFactoryNamespace) Validate(props struct {
218
222
  for _, tag := range props.Tags {
219
223
  if tag.Target != props.Type {
220
224
  if success {
225
+ target := tag.Target
226
+ if target == "" {
227
+ target = props.Type
228
+ }
221
229
  success = props.Report(struct {
222
230
  Property *string
223
231
  Message string
224
- }{Property: nil, Message: "target must contain " + props.Type + " type"})
232
+ }{Property: nil, Message: metadataTypeTagFactory_target_message([]string{target})})
225
233
  }
226
234
  }
227
235
  }
@@ -570,3 +578,16 @@ func metadataTypeTagFactory_essentialFieldsMessage() string {
570
578
  }
571
579
  return strings.Join(values, ", ")
572
580
  }
581
+
582
+ func metadataTypeTagFactory_target_message(targets []string) string {
583
+ return "target must contain " + strings.Join(targets, " or ") + " type"
584
+ }
585
+
586
+ func metadataTypeTagFactory_append_error(errors *[]MetadataFactory_IError, next MetadataFactory_IError) {
587
+ for _, previous := range *errors {
588
+ if reflect.DeepEqual(previous, next) {
589
+ return
590
+ }
591
+ }
592
+ *errors = append(*errors, next)
593
+ }
@@ -345,11 +345,14 @@ func randomProgrammer_write_array_functions(props struct {
345
345
  }) []*shimast.Node {
346
346
  f := nativecontext.EmitFactoryOf(randomProgrammer_factory, props.Context.Emit)
347
347
  output := []*shimast.Node{}
348
- for i, array := range props.Collection.Arrays() {
348
+ for _, array := range props.Collection.Arrays() {
349
349
  if array.Recursive == false {
350
350
  continue
351
351
  }
352
- index := i
352
+ index := 0
353
+ if array.Index != nil {
354
+ index = *array.Index
355
+ }
353
356
  array := array
354
357
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
355
358
  Name: randomProgrammer_prefix_array(index),
@@ -396,11 +399,14 @@ func randomProgrammer_write_tuple_functions(props struct {
396
399
  f := nativecontext.EmitFactoryOf(randomProgrammer_factory, props.Context.Emit)
397
400
  output := []*shimast.Node{}
398
401
  _, unsatisfiableTuples := nativehelpers.RandomJoiner.UnsatisfiableRecursives(props.Collection.Objects(), props.Collection.Tuples())
399
- for i, tuple := range props.Collection.Tuples() {
402
+ for _, tuple := range props.Collection.Tuples() {
400
403
  if tuple.Recursive == false {
401
404
  continue
402
405
  }
403
- index := i
406
+ index := 0
407
+ if tuple.Index != nil {
408
+ index = *tuple.Index
409
+ }
404
410
  tuple := tuple
405
411
  if unsatisfiableTuples[tuple] {
406
412
  panic(nativecontext.NewTransformerError(nativecontext.TransformerError_IProps{
@@ -181,13 +181,17 @@ func (checkerProgrammerNamespace) Write_array_functions(props CheckerProgrammer_
181
181
  f := nativecontext.EmitFactoryOf(checkerProgrammer_factory, props.Context.Emit)
182
182
  arrays := props.Collection.Arrays()
183
183
  output := []*shimast.Node{}
184
- for i, typ := range arrays {
184
+ for _, typ := range arrays {
185
185
  if typ.Recursive == false {
186
186
  continue
187
187
  }
188
+ index := 0
189
+ if typ.Index != nil {
190
+ index = *typ.Index
191
+ }
188
192
  input := f.NewIdentifier("input")
189
193
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
190
- Name: fmt.Sprintf("%sa%d", props.Config.Prefix, i),
194
+ Name: fmt.Sprintf("%sa%d", props.Config.Prefix, index),
191
195
  Value: f.NewArrowFunction(
192
196
  nil,
193
197
  nil,
@@ -200,7 +204,7 @@ func (checkerProgrammerNamespace) Write_array_functions(props CheckerProgrammer_
200
204
  nativefactories.TypeFactory.Keyword("any", props.Context.Emit),
201
205
  nil,
202
206
  f.NewToken(shimast.KindEqualsGreaterThanToken),
203
- checkerProgrammer_visit_guard(FeatureProgrammer.VisitKey(props.Config.Prefix, "a", i), checkerProgrammer_decode_array_inline(checkerProgrammer_decodeArrayInlineProps{
207
+ checkerProgrammer_visit_guard(FeatureProgrammer.VisitKey(props.Config.Prefix, "a", index), checkerProgrammer_decode_array_inline(checkerProgrammer_decodeArrayInlineProps{
204
208
  Config: props.Config,
205
209
  Context: props.Context,
206
210
  Functor: props.Functor,
@@ -226,13 +230,17 @@ func (checkerProgrammerNamespace) Write_tuple_functions(props CheckerProgrammer_
226
230
  f := nativecontext.EmitFactoryOf(checkerProgrammer_factory, props.Context.Emit)
227
231
  tuples := props.Collection.Tuples()
228
232
  output := []*shimast.Node{}
229
- for i, tuple := range tuples {
233
+ for _, tuple := range tuples {
230
234
  if tuple.Recursive == false {
231
235
  continue
232
236
  }
237
+ index := 0
238
+ if tuple.Index != nil {
239
+ index = *tuple.Index
240
+ }
233
241
  input := f.NewIdentifier("input")
234
242
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
235
- Name: fmt.Sprintf("%st%d", props.Config.Prefix, i),
243
+ Name: fmt.Sprintf("%st%d", props.Config.Prefix, index),
236
244
  Value: f.NewArrowFunction(
237
245
  nil,
238
246
  nil,
@@ -245,7 +253,7 @@ func (checkerProgrammerNamespace) Write_tuple_functions(props CheckerProgrammer_
245
253
  nativefactories.TypeFactory.Keyword("any", props.Context.Emit),
246
254
  nil,
247
255
  f.NewToken(shimast.KindEqualsGreaterThanToken),
248
- checkerProgrammer_visit_guard(FeatureProgrammer.VisitKey(props.Config.Prefix, "t", i), checkerProgrammer_decode_tuple_inline(checkerProgrammer_decodeTupleInlineProps{
256
+ checkerProgrammer_visit_guard(FeatureProgrammer.VisitKey(props.Config.Prefix, "t", index), checkerProgrammer_decode_tuple_inline(checkerProgrammer_decodeTupleInlineProps{
249
257
  Config: props.Config,
250
258
  Context: props.Context,
251
259
  Functor: props.Functor,
@@ -100,12 +100,16 @@ func jsonStringifyProgrammer_write_array_functions(props struct {
100
100
  }) []*shimast.Node {
101
101
  f := nativecontext.EmitFactoryOf(jsonStringifyProgrammer_factory, props.Context.Emit)
102
102
  output := []*shimast.Node{}
103
- for i, typ := range props.Collection.Arrays() {
103
+ for _, typ := range props.Collection.Arrays() {
104
104
  if typ.Recursive == false {
105
105
  continue
106
106
  }
107
+ index := 0
108
+ if typ.Index != nil {
109
+ index = *typ.Index
110
+ }
107
111
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
108
- Name: fmt.Sprintf("%sa%d", props.Config.Prefix, i),
112
+ Name: fmt.Sprintf("%sa%d", props.Config.Prefix, index),
109
113
  Value: f.NewArrowFunction(
110
114
  nil,
111
115
  nil,
@@ -118,7 +122,7 @@ func jsonStringifyProgrammer_write_array_functions(props struct {
118
122
  nil,
119
123
  f.NewToken(shimast.KindEqualsGreaterThanToken),
120
124
  nativeinternal.FeatureProgrammer.VisitGuardSerialize(
121
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", i),
125
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", index),
122
126
  jsonStringifyProgrammer_circular_thrower(props.Context, props.Functor),
123
127
  jsonStringifyProgrammer_decode_array_inline(jsonStringifyProgrammer_decodeArrayProps{
124
128
  Context: props.Context,
@@ -153,12 +157,16 @@ func jsonStringifyProgrammer_write_tuple_functions(props struct {
153
157
  }) []*shimast.Node {
154
158
  f := nativecontext.EmitFactoryOf(jsonStringifyProgrammer_factory, props.Context.Emit)
155
159
  output := []*shimast.Node{}
156
- for i, tuple := range props.Collection.Tuples() {
160
+ for _, tuple := range props.Collection.Tuples() {
157
161
  if tuple.Recursive == false {
158
162
  continue
159
163
  }
164
+ index := 0
165
+ if tuple.Index != nil {
166
+ index = *tuple.Index
167
+ }
160
168
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
161
- Name: fmt.Sprintf("%st%d", props.Config.Prefix, i),
169
+ Name: fmt.Sprintf("%st%d", props.Config.Prefix, index),
162
170
  Value: f.NewArrowFunction(
163
171
  nil,
164
172
  nil,
@@ -171,7 +179,7 @@ func jsonStringifyProgrammer_write_tuple_functions(props struct {
171
179
  nil,
172
180
  f.NewToken(shimast.KindEqualsGreaterThanToken),
173
181
  nativeinternal.FeatureProgrammer.VisitGuardSerialize(
174
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", i),
182
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", index),
175
183
  jsonStringifyProgrammer_circular_thrower(props.Context, props.Functor),
176
184
  jsonStringifyProgrammer_decode_tuple_inline(jsonStringifyProgrammer_decodeTupleInlineProps{
177
185
  Context: props.Context,
@@ -131,12 +131,16 @@ func notationGeneralProgrammer_write_array_functions(props struct {
131
131
  }) []*shimast.Node {
132
132
  f := nativecontext.EmitFactoryOf(notationGeneralProgrammer_factory, props.Context.Emit)
133
133
  output := []*shimast.Node{}
134
- for i, typ := range props.Collection.Arrays() {
134
+ for _, typ := range props.Collection.Arrays() {
135
135
  if typ.Recursive == false {
136
136
  continue
137
137
  }
138
+ index := 0
139
+ if typ.Index != nil {
140
+ index = *typ.Index
141
+ }
138
142
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
139
- Name: fmt.Sprintf("%sa%d", props.Config.Prefix, i),
143
+ Name: fmt.Sprintf("%sa%d", props.Config.Prefix, index),
140
144
  Value: f.NewArrowFunction(
141
145
  nil,
142
146
  nil,
@@ -149,7 +153,7 @@ func notationGeneralProgrammer_write_array_functions(props struct {
149
153
  nil,
150
154
  f.NewToken(shimast.KindEqualsGreaterThanToken),
151
155
  nativeinternal.FeatureProgrammer.VisitGuardRebuild(
152
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", i),
156
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", index),
153
157
  true,
154
158
  notationGeneralProgrammer_decode_array_inline(notationGeneralProgrammer_decodeArrayProps{
155
159
  Context: props.Context,
@@ -184,12 +188,16 @@ func notationGeneralProgrammer_write_tuple_functions(props struct {
184
188
  }) []*shimast.Node {
185
189
  f := nativecontext.EmitFactoryOf(notationGeneralProgrammer_factory, props.Context.Emit)
186
190
  output := []*shimast.Node{}
187
- for i, tuple := range props.Collection.Tuples() {
191
+ for _, tuple := range props.Collection.Tuples() {
188
192
  if tuple.Recursive == false {
189
193
  continue
190
194
  }
195
+ index := 0
196
+ if tuple.Index != nil {
197
+ index = *tuple.Index
198
+ }
191
199
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
192
- Name: fmt.Sprintf("%st%d", props.Config.Prefix, i),
200
+ Name: fmt.Sprintf("%st%d", props.Config.Prefix, index),
193
201
  Value: f.NewArrowFunction(
194
202
  nil,
195
203
  nil,
@@ -202,7 +210,7 @@ func notationGeneralProgrammer_write_tuple_functions(props struct {
202
210
  nil,
203
211
  f.NewToken(shimast.KindEqualsGreaterThanToken),
204
212
  nativeinternal.FeatureProgrammer.VisitGuardRebuild(
205
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", i),
213
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", index),
206
214
  true,
207
215
  notationGeneralProgrammer_decode_tuple_inline(notationGeneralProgrammer_decodeTupleInlineProps{
208
216
  Context: props.Context,
@@ -135,12 +135,16 @@ func plainClassifyProgrammer_write_array_functions(props struct {
135
135
  }) []*shimast.Node {
136
136
  f := nativecontext.EmitFactoryOf(plainClassifyProgrammer_factory, props.Context.Emit)
137
137
  output := []*shimast.Node{}
138
- for i, typ := range props.Collection.Arrays() {
138
+ for _, typ := range props.Collection.Arrays() {
139
139
  if typ.Recursive == false {
140
140
  continue
141
141
  }
142
+ index := 0
143
+ if typ.Index != nil {
144
+ index = *typ.Index
145
+ }
142
146
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
143
- Name: fmt.Sprintf("%sa%d", props.Config.Prefix, i),
147
+ Name: fmt.Sprintf("%sa%d", props.Config.Prefix, index),
144
148
  Value: f.NewArrowFunction(
145
149
  nil,
146
150
  nil,
@@ -153,7 +157,7 @@ func plainClassifyProgrammer_write_array_functions(props struct {
153
157
  nil,
154
158
  f.NewToken(shimast.KindEqualsGreaterThanToken),
155
159
  nativeinternal.FeatureProgrammer.VisitGuardRebuild(
156
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", i),
160
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", index),
157
161
  true,
158
162
  plainClassifyProgrammer_decode_array_inline(plainClassifyProgrammer_decodeArrayProps{
159
163
  Context: props.Context,
@@ -187,12 +191,16 @@ func plainClassifyProgrammer_write_tuple_functions(props struct {
187
191
  }) []*shimast.Node {
188
192
  f := nativecontext.EmitFactoryOf(plainClassifyProgrammer_factory, props.Context.Emit)
189
193
  output := []*shimast.Node{}
190
- for i, tuple := range props.Collection.Tuples() {
194
+ for _, tuple := range props.Collection.Tuples() {
191
195
  if tuple.Recursive == false {
192
196
  continue
193
197
  }
198
+ index := 0
199
+ if tuple.Index != nil {
200
+ index = *tuple.Index
201
+ }
194
202
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
195
- Name: fmt.Sprintf("%st%d", props.Config.Prefix, i),
203
+ Name: fmt.Sprintf("%st%d", props.Config.Prefix, index),
196
204
  Value: f.NewArrowFunction(
197
205
  nil,
198
206
  nil,
@@ -205,7 +213,7 @@ func plainClassifyProgrammer_write_tuple_functions(props struct {
205
213
  nil,
206
214
  f.NewToken(shimast.KindEqualsGreaterThanToken),
207
215
  nativeinternal.FeatureProgrammer.VisitGuardRebuild(
208
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", i),
216
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", index),
209
217
  true,
210
218
  plainClassifyProgrammer_decode_tuple_inline(plainClassifyProgrammer_decodeTupleInlineProps{
211
219
  Context: props.Context,
@@ -96,12 +96,16 @@ func plainCloneProgrammer_write_array_functions(props struct {
96
96
  }) []*shimast.Node {
97
97
  f := nativecontext.EmitFactoryOf(plainCloneProgrammer_factory, props.Context.Emit)
98
98
  output := []*shimast.Node{}
99
- for i, typ := range props.Collection.Arrays() {
99
+ for _, typ := range props.Collection.Arrays() {
100
100
  if typ.Recursive == false {
101
101
  continue
102
102
  }
103
+ index := 0
104
+ if typ.Index != nil {
105
+ index = *typ.Index
106
+ }
103
107
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
104
- Name: fmt.Sprintf("%sa%d", props.Config.Prefix, i),
108
+ Name: fmt.Sprintf("%sa%d", props.Config.Prefix, index),
105
109
  Value: f.NewArrowFunction(
106
110
  nil,
107
111
  nil,
@@ -114,7 +118,7 @@ func plainCloneProgrammer_write_array_functions(props struct {
114
118
  nil,
115
119
  f.NewToken(shimast.KindEqualsGreaterThanToken),
116
120
  nativeinternal.FeatureProgrammer.VisitGuardRebuild(
117
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", i),
121
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", index),
118
122
  true,
119
123
  plainCloneProgrammer_decode_array_inline(plainCloneProgrammer_decodeArrayProps{
120
124
  Context: props.Context,
@@ -148,12 +152,16 @@ func plainCloneProgrammer_write_tuple_functions(props struct {
148
152
  }) []*shimast.Node {
149
153
  f := nativecontext.EmitFactoryOf(plainCloneProgrammer_factory, props.Context.Emit)
150
154
  output := []*shimast.Node{}
151
- for i, tuple := range props.Collection.Tuples() {
155
+ for _, tuple := range props.Collection.Tuples() {
152
156
  if tuple.Recursive == false {
153
157
  continue
154
158
  }
159
+ index := 0
160
+ if tuple.Index != nil {
161
+ index = *tuple.Index
162
+ }
155
163
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
156
- Name: fmt.Sprintf("%st%d", props.Config.Prefix, i),
164
+ Name: fmt.Sprintf("%st%d", props.Config.Prefix, index),
157
165
  Value: f.NewArrowFunction(
158
166
  nil,
159
167
  nil,
@@ -166,7 +174,7 @@ func plainCloneProgrammer_write_tuple_functions(props struct {
166
174
  nil,
167
175
  f.NewToken(shimast.KindEqualsGreaterThanToken),
168
176
  nativeinternal.FeatureProgrammer.VisitGuardRebuild(
169
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", i),
177
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", index),
170
178
  true,
171
179
  plainCloneProgrammer_decode_tuple_inline(plainCloneProgrammer_decodeTupleInlineProps{
172
180
  Context: props.Context,
@@ -93,12 +93,16 @@ func plainPruneProgrammer_write_array_functions(props struct {
93
93
  }) []*shimast.Node {
94
94
  f := nativecontext.EmitFactoryOf(plainPruneProgrammer_factory, props.Context.Emit)
95
95
  output := []*shimast.Node{}
96
- for i, typ := range props.Collection.Arrays() {
96
+ for _, typ := range props.Collection.Arrays() {
97
97
  if typ.Recursive == false {
98
98
  continue
99
99
  }
100
+ index := 0
101
+ if typ.Index != nil {
102
+ index = *typ.Index
103
+ }
100
104
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
101
- Name: fmt.Sprintf("%sa%d", props.Config.Prefix, i),
105
+ Name: fmt.Sprintf("%sa%d", props.Config.Prefix, index),
102
106
  Value: f.NewArrowFunction(
103
107
  nil,
104
108
  nil,
@@ -111,7 +115,7 @@ func plainPruneProgrammer_write_array_functions(props struct {
111
115
  nil,
112
116
  f.NewToken(shimast.KindEqualsGreaterThanToken),
113
117
  nativeinternal.FeatureProgrammer.VisitGuardSkip(
114
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", i),
118
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "a", index),
115
119
  plainPruneProgrammer_decode_array_inline(plainPruneProgrammer_decodeArrayProps{
116
120
  Context: props.Context,
117
121
  Config: props.Config,
@@ -144,12 +148,16 @@ func plainPruneProgrammer_write_tuple_functions(props struct {
144
148
  }) []*shimast.Node {
145
149
  f := nativecontext.EmitFactoryOf(plainPruneProgrammer_factory, props.Context.Emit)
146
150
  output := []*shimast.Node{}
147
- for i, tuple := range props.Collection.Tuples() {
151
+ for _, tuple := range props.Collection.Tuples() {
148
152
  if tuple.Recursive == false {
149
153
  continue
150
154
  }
155
+ index := 0
156
+ if tuple.Index != nil {
157
+ index = *tuple.Index
158
+ }
151
159
  output = append(output, nativefactories.StatementFactory.Constant(nativefactories.StatementFactory_ConstantProps{
152
- Name: fmt.Sprintf("%st%d", props.Config.Prefix, i),
160
+ Name: fmt.Sprintf("%st%d", props.Config.Prefix, index),
153
161
  Value: f.NewArrowFunction(
154
162
  nil,
155
163
  nil,
@@ -162,7 +170,7 @@ func plainPruneProgrammer_write_tuple_functions(props struct {
162
170
  nil,
163
171
  f.NewToken(shimast.KindEqualsGreaterThanToken),
164
172
  nativeinternal.FeatureProgrammer.VisitGuardSkip(
165
- nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", i),
173
+ nativeinternal.FeatureProgrammer.VisitKey(props.Config.Prefix, "t", index),
166
174
  plainPruneProgrammer_decode_tuple_inline(plainPruneProgrammer_decodeTupleInlineProps{
167
175
  Context: props.Context,
168
176
  Config: props.Config,
@@ -805,6 +813,14 @@ func plainPruneProgrammer_initializer(props nativeinternal.FeatureProgrammer_Ini
805
813
  }
806
814
 
807
815
  func plainPruneProgrammer_filter(metadata *schemametadata.MetadataSchema) bool {
816
+ return plainPruneProgrammer_filter_visited(metadata, map[*schemametadata.MetadataSchema]bool{})
817
+ }
818
+
819
+ func plainPruneProgrammer_filter_visited(metadata *schemametadata.MetadataSchema, visited map[*schemametadata.MetadataSchema]bool) bool {
820
+ if visited[metadata] {
821
+ return false
822
+ }
823
+ visited[metadata] = true
808
824
  if metadata.Any {
809
825
  return false
810
826
  }
@@ -812,12 +828,12 @@ func plainPruneProgrammer_filter(metadata *schemametadata.MetadataSchema) bool {
812
828
  return true
813
829
  }
814
830
  for _, tuple := range metadata.Tuples {
815
- if plainPruneProgrammer_tuple_filter(tuple) {
831
+ if plainPruneProgrammer_tuple_filter_visited(tuple, visited) {
816
832
  return true
817
833
  }
818
834
  }
819
835
  for _, array := range metadata.Arrays {
820
- if plainPruneProgrammer_filter(array.Type.Value) {
836
+ if plainPruneProgrammer_filter_visited(array.Type.Value, visited) {
821
837
  return true
822
838
  }
823
839
  }
@@ -825,11 +841,15 @@ func plainPruneProgrammer_filter(metadata *schemametadata.MetadataSchema) bool {
825
841
  }
826
842
 
827
843
  func plainPruneProgrammer_tuple_filter(tuple *schemametadata.MetadataTuple) bool {
844
+ return plainPruneProgrammer_tuple_filter_visited(tuple, map[*schemametadata.MetadataSchema]bool{})
845
+ }
846
+
847
+ func plainPruneProgrammer_tuple_filter_visited(tuple *schemametadata.MetadataTuple, visited map[*schemametadata.MetadataSchema]bool) bool {
828
848
  return len(tuple.Type.Elements) != 0 && plainPruneProgrammer_some_schema(tuple.Type.Elements, func(elem *schemametadata.MetadataSchema) bool {
829
849
  if elem.Rest != nil {
830
- return plainPruneProgrammer_filter(elem.Rest)
850
+ return plainPruneProgrammer_filter_visited(elem.Rest, visited)
831
851
  }
832
- return plainPruneProgrammer_filter(elem)
852
+ return plainPruneProgrammer_filter_visited(elem, visited)
833
853
  })
834
854
  }
835
855
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typia",
3
- "version": "14.0.4",
3
+ "version": "14.0.5",
4
4
  "description": "Superfast runtime validators with only one line",
5
5
  "main": "lib/index.js",
6
6
  "exports": {
@@ -43,8 +43,8 @@
43
43
  "homepage": "https://typia.io",
44
44
  "dependencies": {
45
45
  "randexp": "^0.5.3",
46
- "@typia/interface": "^14.0.4",
47
- "@typia/utils": "^14.0.4"
46
+ "@typia/interface": "^14.0.5",
47
+ "@typia/utils": "^14.0.5"
48
48
  },
49
49
  "peerDependencies": {
50
50
  "ttsc": ">=0.19.2"