typia 13.1.19 → 13.3.0

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 (235) hide show
  1. package/lib/executable/FileSystemIdentity.d.ts +23 -0
  2. package/lib/executable/FileSystemIdentity.js +30 -0
  3. package/lib/executable/FileSystemIdentity.js.map +1 -1
  4. package/lib/executable/FileSystemIdentity.mjs +4 -0
  5. package/lib/executable/FileSystemIdentity.mjs.map +1 -1
  6. package/lib/executable/TypiaGenerateWizard.js +15 -9
  7. package/lib/executable/TypiaGenerateWizard.js.map +1 -1
  8. package/lib/executable/TypiaGenerateWizard.mjs +11 -7
  9. package/lib/executable/TypiaGenerateWizard.mjs.map +1 -1
  10. package/lib/http.d.ts +3 -3
  11. package/lib/http.js.map +1 -1
  12. package/lib/http.mjs.map +1 -1
  13. package/lib/internal/_ProtobufReader.d.ts +18 -3
  14. package/lib/internal/_ProtobufReader.js +39 -11
  15. package/lib/internal/_ProtobufReader.js.map +1 -1
  16. package/lib/internal/_ProtobufReader.mjs +37 -10
  17. package/lib/internal/_ProtobufReader.mjs.map +1 -1
  18. package/lib/internal/_assertGuard.js +13 -3
  19. package/lib/internal/_assertGuard.js.map +1 -1
  20. package/lib/internal/_assertGuard.mjs +4 -2
  21. package/lib/internal/_assertGuard.mjs.map +1 -1
  22. package/lib/internal/_isFormatIdnHostname.js +5 -1
  23. package/lib/internal/_isFormatIdnHostname.js.map +1 -1
  24. package/lib/internal/_isFormatIdnHostname.mjs +1 -1
  25. package/lib/internal/_isFormatIdnHostname.mjs.map +1 -1
  26. package/lib/internal/_isFormatTime.js +19 -2
  27. package/lib/internal/_isFormatTime.js.map +1 -1
  28. package/lib/internal/_isFormatTime.mjs +9 -2
  29. package/lib/internal/_isFormatTime.mjs.map +1 -1
  30. package/lib/internal/_jsonStringifyArray.d.ts +1 -0
  31. package/lib/internal/_jsonStringifyArray.js +48 -0
  32. package/lib/internal/_jsonStringifyArray.js.map +1 -0
  33. package/lib/internal/_jsonStringifyArray.mjs +40 -0
  34. package/lib/internal/_jsonStringifyArray.mjs.map +1 -0
  35. package/lib/internal/_jsonStringifyElement.d.ts +1 -0
  36. package/lib/internal/_jsonStringifyElement.js +23 -0
  37. package/lib/internal/_jsonStringifyElement.js.map +1 -0
  38. package/lib/internal/_jsonStringifyElement.mjs +23 -0
  39. package/lib/internal/_jsonStringifyElement.mjs.map +1 -0
  40. package/lib/internal/_jsonStringifyProperty.d.ts +1 -0
  41. package/lib/internal/_jsonStringifyProperty.js +31 -0
  42. package/lib/internal/_jsonStringifyProperty.js.map +1 -0
  43. package/lib/internal/_jsonStringifyProperty.mjs +31 -0
  44. package/lib/internal/_jsonStringifyProperty.mjs.map +1 -0
  45. package/lib/internal/_llmApplicationFinalize.js +1 -1
  46. package/lib/internal/_llmApplicationFinalize.js.map +1 -1
  47. package/lib/internal/_llmApplicationFinalize.mjs +1 -1
  48. package/lib/internal/_llmApplicationFinalize.mjs.map +1 -1
  49. package/lib/internal/_randomArray.js +37 -4
  50. package/lib/internal/_randomArray.js.map +1 -1
  51. package/lib/internal/_randomArray.mjs +16 -3
  52. package/lib/internal/_randomArray.mjs.map +1 -1
  53. package/lib/internal/_randomFormatByte.js +28 -2
  54. package/lib/internal/_randomFormatByte.js.map +1 -1
  55. package/lib/internal/_randomFormatByte.mjs +22 -3
  56. package/lib/internal/_randomFormatByte.mjs.map +1 -1
  57. package/lib/internal/_randomFormatDate.d.ts +3 -6
  58. package/lib/internal/_randomFormatDate.js +2 -10
  59. package/lib/internal/_randomFormatDate.js.map +1 -1
  60. package/lib/internal/_randomFormatDate.mjs +2 -6
  61. package/lib/internal/_randomFormatDate.mjs.map +1 -1
  62. package/lib/internal/_randomFormatDatetime.d.ts +3 -6
  63. package/lib/internal/_randomFormatDatetime.js +25 -8
  64. package/lib/internal/_randomFormatDatetime.js.map +1 -1
  65. package/lib/internal/_randomFormatDatetime.mjs +17 -7
  66. package/lib/internal/_randomFormatDatetime.mjs.map +1 -1
  67. package/lib/internal/_randomFormatDuration.js +23 -15
  68. package/lib/internal/_randomFormatDuration.js.map +1 -1
  69. package/lib/internal/_randomFormatDuration.mjs +23 -15
  70. package/lib/internal/_randomFormatDuration.mjs.map +1 -1
  71. package/lib/internal/_randomFormatHostname.d.ts +2 -2
  72. package/lib/internal/_randomFormatHostname.js +2 -2
  73. package/lib/internal/_randomFormatHostname.mjs +2 -2
  74. package/lib/internal/_randomFormatHostname.mjs.map +1 -1
  75. package/lib/internal/_randomFormatIdnHostname.js +9 -10
  76. package/lib/internal/_randomFormatIdnHostname.js.map +1 -1
  77. package/lib/internal/_randomFormatIdnHostname.mjs +3 -4
  78. package/lib/internal/_randomFormatIdnHostname.mjs.map +1 -1
  79. package/lib/internal/_randomFormatIpv4.js +31 -1
  80. package/lib/internal/_randomFormatIpv4.js.map +1 -1
  81. package/lib/internal/_randomFormatIpv4.mjs +23 -2
  82. package/lib/internal/_randomFormatIpv4.mjs.map +1 -1
  83. package/lib/internal/_randomFormatIpv6.js +57 -1
  84. package/lib/internal/_randomFormatIpv6.js.map +1 -1
  85. package/lib/internal/_randomFormatIpv6.mjs +45 -2
  86. package/lib/internal/_randomFormatIpv6.mjs.map +1 -1
  87. package/lib/internal/_randomFormatJsonPointer.js +14 -2
  88. package/lib/internal/_randomFormatJsonPointer.js.map +1 -1
  89. package/lib/internal/_randomFormatJsonPointer.mjs +13 -3
  90. package/lib/internal/_randomFormatJsonPointer.mjs.map +1 -1
  91. package/lib/internal/_randomFormatRegex.js +15 -2
  92. package/lib/internal/_randomFormatRegex.js.map +1 -1
  93. package/lib/internal/_randomFormatRegex.mjs +14 -3
  94. package/lib/internal/_randomFormatRegex.mjs.map +1 -1
  95. package/lib/internal/_randomFormatRelativeJsonPointer.js +19 -5
  96. package/lib/internal/_randomFormatRelativeJsonPointer.js.map +1 -1
  97. package/lib/internal/_randomFormatRelativeJsonPointer.mjs +21 -6
  98. package/lib/internal/_randomFormatRelativeJsonPointer.mjs.map +1 -1
  99. package/lib/internal/_randomFormatTime.js +38 -7
  100. package/lib/internal/_randomFormatTime.js.map +1 -1
  101. package/lib/internal/_randomFormatTime.mjs +40 -5
  102. package/lib/internal/_randomFormatTime.mjs.map +1 -1
  103. package/lib/internal/_randomPattern.js.map +1 -1
  104. package/lib/internal/_randomPattern.mjs.map +1 -1
  105. package/lib/internal/_randomStringLength.d.ts +41 -10
  106. package/lib/internal/_randomStringLength.js +49 -13
  107. package/lib/internal/_randomStringLength.js.map +1 -1
  108. package/lib/internal/_randomStringLength.mjs +48 -13
  109. package/lib/internal/_randomStringLength.mjs.map +1 -1
  110. package/lib/internal/private/__notationRename.js.map +1 -1
  111. package/lib/internal/private/__notationRename.mjs.map +1 -1
  112. package/lib/internal/private/__randomComposition.d.ts +31 -0
  113. package/lib/internal/private/__randomComposition.js +68 -0
  114. package/lib/internal/private/__randomComposition.js.map +1 -0
  115. package/lib/internal/private/__randomComposition.mjs +71 -0
  116. package/lib/internal/private/__randomComposition.mjs.map +1 -0
  117. package/lib/internal/private/__randomEpoch.d.ts +19 -0
  118. package/lib/internal/private/__randomEpoch.js +31 -0
  119. package/lib/internal/private/__randomEpoch.js.map +1 -0
  120. package/lib/internal/private/__randomEpoch.mjs +28 -0
  121. package/lib/internal/private/__randomEpoch.mjs.map +1 -0
  122. package/lib/json.d.ts +2 -2
  123. package/lib/json.js.map +1 -1
  124. package/lib/json.mjs.map +1 -1
  125. package/lib/module.d.ts +28 -13
  126. package/lib/module.js.map +1 -1
  127. package/lib/module.mjs.map +1 -1
  128. package/lib/notations.d.ts +4 -4
  129. package/lib/notations.js.map +1 -1
  130. package/lib/notations.mjs.map +1 -1
  131. package/lib/plain.d.ts +3 -3
  132. package/lib/plain.js.map +1 -1
  133. package/lib/plain.mjs.map +1 -1
  134. package/lib/protobuf.d.ts +2 -2
  135. package/lib/protobuf.js.map +1 -1
  136. package/lib/protobuf.mjs.map +1 -1
  137. package/native/cmd/ttsc-typia/assert_guard_factory_contract_test.go +17 -4
  138. package/native/cmd/ttsc-typia/build.go +3 -0
  139. package/native/cmd/ttsc-typia/callable_interface_function_semantics_transform_test.go +331 -0
  140. package/native/cmd/ttsc-typia/callable_type_literal_boundaries_transform_test.go +1184 -0
  141. package/native/cmd/ttsc-typia/compare_functional_union_membership_transform_test.go +434 -0
  142. package/native/cmd/ttsc-typia/compare_template_literal_union_transform_test.go +241 -0
  143. package/native/cmd/ttsc-typia/create_assert_error_factory_arity_test.go +309 -0
  144. package/native/cmd/ttsc-typia/default_library_spoof_native_identity_transform_test.go +216 -0
  145. package/native/cmd/ttsc-typia/json_schema_dynamic_key_determinism_transform_test.go +246 -0
  146. package/native/cmd/ttsc-typia/json_stringify_contextual_undefined_transform_test.go +556 -0
  147. package/native/cmd/ttsc-typia/lib_replacement_native_identity_transform_test.go +277 -0
  148. package/native/cmd/ttsc-typia/local_function_named_like_typia_operation_transform_test.go +185 -0
  149. package/native/cmd/ttsc-typia/native_named_intersection_union_transform_test.go +390 -0
  150. package/native/cmd/ttsc-typia/node_buffer_native_exports_is_transform_test.go +526 -0
  151. package/native/cmd/ttsc-typia/package_declaration_native_identity_is_transform_test.go +293 -0
  152. package/native/cmd/ttsc-typia/protobuf_diagnostic_code_transform_test.go +167 -0
  153. package/native/cmd/ttsc-typia/recursive_conditional_alias_name_transform_test.go +307 -0
  154. package/native/cmd/ttsc-typia/shadowed_typia_module_declaration_diagnostic_test.go +152 -0
  155. package/native/cmd/ttsc-typia/symbol_index_domain_transform_test.go +316 -0
  156. package/native/cmd/ttsc-typia/template_literal_type_tags_transform_test.go +1 -3
  157. package/native/cmd/ttsc-typia/transform.go +23 -0
  158. package/native/cmd/ttsc-typia/transform_helpers_test.go +166 -25
  159. package/native/cmd/ttsc-typia/user_global_native_identity_transform_test.go +484 -0
  160. package/native/core/factories/FormatCheatSheet.go +2 -2
  161. package/native/core/factories/MetadataCommentTagFactory.go +26 -11
  162. package/native/core/factories/ProtobufFactory.go +6 -1
  163. package/native/core/factories/factory_utility_coverage_test.go +896 -907
  164. package/native/core/factories/internal/metadata/MetadataHelper.go +190 -58
  165. package/native/core/factories/internal/metadata/emplace_metadata_object.go +25 -0
  166. package/native/core/factories/internal/metadata/iterate_metadata_function.go +1 -1
  167. package/native/core/factories/internal/metadata/iterate_metadata_intersection.go +103 -23
  168. package/native/core/factories/internal/metadata/iterate_metadata_map.go +3 -7
  169. package/native/core/factories/internal/metadata/iterate_metadata_native.go +32 -14
  170. package/native/core/factories/internal/metadata/iterate_metadata_set.go +3 -7
  171. package/native/core/factories/metadata_comment_tag_factory_coverage_test.go +2 -2
  172. package/native/core/programmers/RandomProgrammer.go +5 -2
  173. package/native/core/programmers/compare/CompareEqualProgrammer.go +27 -13
  174. package/native/core/programmers/helpers/FunctionProgrammer.go +6 -13
  175. package/native/core/programmers/helpers/StringifyJoinder.go +129 -50
  176. package/native/core/programmers/helpers/joiner_branch_coverage_test.go +116 -120
  177. package/native/core/programmers/iterate/iterate_check_coverage_test.go +76 -158
  178. package/native/core/programmers/iterate/iterate_utility_coverage_test.go +231 -270
  179. package/native/core/programmers/iterate/json_schema_object.go +49 -7
  180. package/native/core/programmers/iterate/json_schema_pattern_property_order_test.go +44 -0
  181. package/native/core/programmers/iterate/openapi_v3_downgrader.go +34 -1
  182. package/native/core/programmers/iterate/template_runtime_pattern.go +11 -0
  183. package/native/core/programmers/json/JsonStringifyProgrammer.go +47 -6
  184. package/native/core/programmers/llm/LlmApplicationProgrammer.go +9 -1
  185. package/native/core/programmers/protobuf/ProtobufMessageProgrammer.go +1 -1
  186. package/native/core/schemas/metadata/MetadataCollection.go +47 -14
  187. package/native/core/schemas/metadata/MetadataDefaultLibrary.go +81 -0
  188. package/native/core/schemas/metadata/MetadataObjectType.go +7 -18
  189. package/native/go.mod +4 -4
  190. package/native/transform/CallExpressionTransformer.go +167 -0
  191. package/native/transform/features/protobuf/ProtobufMessageTransformer.go +1 -1
  192. package/package.json +3 -7
  193. package/src/executable/FileSystemIdentity.ts +33 -0
  194. package/src/executable/TypiaGenerateWizard.ts +18 -12
  195. package/src/http.ts +18 -4
  196. package/src/internal/_ProtobufReader.ts +40 -11
  197. package/src/internal/_assertGuard.ts +13 -2
  198. package/src/internal/_isFormatIdnHostname.ts +5 -1
  199. package/src/internal/_isFormatTime.ts +19 -2
  200. package/src/internal/_jsonStringifyArray.ts +50 -0
  201. package/src/internal/_jsonStringifyElement.ts +19 -0
  202. package/src/internal/_jsonStringifyProperty.ts +30 -0
  203. package/src/internal/_llmApplicationFinalize.ts +6 -1
  204. package/src/internal/_randomArray.ts +42 -6
  205. package/src/internal/_randomFormatByte.ts +36 -4
  206. package/src/internal/_randomFormatDate.ts +4 -20
  207. package/src/internal/_randomFormatDatetime.ts +34 -20
  208. package/src/internal/_randomFormatDuration.ts +19 -4
  209. package/src/internal/_randomFormatHostname.ts +2 -2
  210. package/src/internal/_randomFormatIdnHostname.ts +8 -9
  211. package/src/internal/_randomFormatIpv4.ts +43 -3
  212. package/src/internal/_randomFormatIpv6.ts +67 -3
  213. package/src/internal/_randomFormatJsonPointer.ts +23 -3
  214. package/src/internal/_randomFormatRegex.ts +22 -6
  215. package/src/internal/_randomFormatRelativeJsonPointer.ts +23 -10
  216. package/src/internal/_randomFormatTime.ts +50 -12
  217. package/src/internal/_randomPattern.ts +4 -1
  218. package/src/internal/_randomStringLength.ts +61 -17
  219. package/src/internal/private/__notationRename.ts +1 -4
  220. package/src/internal/private/__randomComposition.ts +74 -0
  221. package/src/internal/private/__randomEpoch.ts +34 -0
  222. package/src/json.ts +16 -4
  223. package/src/module.ts +56 -22
  224. package/src/notations.ts +16 -4
  225. package/src/plain.ts +12 -3
  226. package/src/protobuf.ts +16 -4
  227. package/native/adapter/visit.go +0 -173
  228. package/native/adapter/visit_property_chain_edges_test.go +0 -129
  229. package/native/core/programmers/helpers/disable_function_programmer_declare.go +0 -10
  230. package/native/core/programmers/iterate/check_union_array_like.go +0 -422
  231. package/native/core/programmers/iterate/prune_object_properties.go +0 -105
  232. package/native/core/programmers/iterate/stringify_dynamic_properties.go +0 -219
  233. package/native/core/programmers/iterate/stringify_native.go +0 -14
  234. package/native/core/programmers/iterate/stringify_regular_properties.go +0 -112
  235. package/native/core/schemas/metadata/MetadataApplication.go +0 -41
@@ -0,0 +1,246 @@
1
+ package main
2
+
3
+ import (
4
+ "bytes"
5
+ "crypto/sha256"
6
+ "os"
7
+ "os/exec"
8
+ "path/filepath"
9
+ "testing"
10
+ )
11
+
12
+ // TestJsonSchemaDynamicKeyDeterminismTransform verifies dynamic-key schemas emit deterministically.
13
+ //
14
+ // Multiple template and numeric index signatures used to reach a Go map before
15
+ // their value metadata was merged. Repeating one unchanged transform therefore
16
+ // has to compare the complete output bytes, while runtime checks ensure a stable
17
+ // order is not achieved by losing, duplicating, or broadening schema branches.
18
+ //
19
+ // 1. Transform unchanged tag-free dynamic-key fixtures repeatedly to TypeScript and JavaScript.
20
+ // 2. Require every complete emit to match the first emit byte for byte.
21
+ // 3. Execute the JavaScript and assert branch completeness plus unrelated ordering controls.
22
+ func TestJsonSchemaDynamicKeyDeterminismTransform(t *testing.T) {
23
+ project := jsonSchemaDynamicKeyDeterminismProject(t)
24
+ var javascript string
25
+ for _, output := range []string{"ts", "js"} {
26
+ baseline := jsonSchemaDynamicKeyDeterminismTransform(t, project, output)
27
+ for iteration := 1; iteration < 32; iteration++ {
28
+ current := jsonSchemaDynamicKeyDeterminismTransform(t, project, output)
29
+ if bytes.Equal([]byte(current), []byte(baseline)) == false {
30
+ t.Fatalf(
31
+ "%s emit %d changed for unchanged input: baseline=%x current=%x first-difference=%d",
32
+ output,
33
+ iteration+1,
34
+ sha256.Sum256([]byte(baseline)),
35
+ sha256.Sum256([]byte(current)),
36
+ jsonSchemaDynamicKeyDeterminismFirstDifference(baseline, current),
37
+ )
38
+ }
39
+ }
40
+ t.Logf("%s emit remained byte-identical across 32 transforms: sha256=%x", output, sha256.Sum256([]byte(baseline)))
41
+ if output == "js" {
42
+ javascript = baseline
43
+ }
44
+ }
45
+ jsonSchemaDynamicKeyDeterminismRunRuntimeCases(t, project, javascript)
46
+ }
47
+
48
+ func jsonSchemaDynamicKeyDeterminismProject(t *testing.T) string {
49
+ t.Helper()
50
+ root := ttscTypiaTestRepoRoot(t)
51
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
52
+ if err := os.MkdirAll(base, 0o755); err != nil {
53
+ t.Fatalf("mkdir temp base: %v", err)
54
+ }
55
+ dir, err := os.MkdirTemp(base, "json-schema-dynamic-key-determinism-")
56
+ if err != nil {
57
+ t.Fatalf("create temp fixture: %v", err)
58
+ }
59
+ t.Cleanup(func() {
60
+ _ = os.RemoveAll(dir)
61
+ })
62
+ src := filepath.Join(dir, "src")
63
+ if err := os.MkdirAll(src, 0o755); err != nil {
64
+ t.Fatalf("mkdir fixture src: %v", err)
65
+ }
66
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(jsonSchemaDynamicKeyDeterminismTSConfig), 0o644); err != nil {
67
+ t.Fatalf("write tsconfig: %v", err)
68
+ }
69
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(jsonSchemaDynamicKeyDeterminismSource), 0o644); err != nil {
70
+ t.Fatalf("write source: %v", err)
71
+ }
72
+ return dir
73
+ }
74
+
75
+ func jsonSchemaDynamicKeyDeterminismTransform(t *testing.T, project string, output string) string {
76
+ t.Helper()
77
+ out, errText, code := ttscTypiaTestCapture(func() int {
78
+ return runTransform([]string{
79
+ "--cwd", project,
80
+ "--tsconfig", "tsconfig.json",
81
+ "--file", "src/main.ts",
82
+ "--output", output,
83
+ })
84
+ })
85
+ if code != 0 {
86
+ t.Fatalf("dynamic-key schema transform failed: output=%s code=%d stderr=\n%s", output, code, errText)
87
+ }
88
+ return out
89
+ }
90
+
91
+ func jsonSchemaDynamicKeyDeterminismFirstDifference(x string, y string) int {
92
+ limit := len(x)
93
+ if len(y) < limit {
94
+ limit = len(y)
95
+ }
96
+ for i := 0; i < limit; i++ {
97
+ if x[i] != y[i] {
98
+ return i
99
+ }
100
+ }
101
+ return limit
102
+ }
103
+
104
+ func jsonSchemaDynamicKeyDeterminismRunRuntimeCases(t *testing.T, project string, javascript string) {
105
+ t.Helper()
106
+ node, err := exec.LookPath("node")
107
+ if err != nil {
108
+ t.Skip("node executable not found")
109
+ }
110
+ runtimeDir := filepath.Join(project, "runtime")
111
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
112
+ t.Fatalf("mkdir runtime dir: %v", err)
113
+ }
114
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
115
+ runtimeJS := ttscTypiaTestRewriteCommonJS(t, javascript)
116
+ if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
117
+ t.Fatalf("write runtime module: %v", err)
118
+ }
119
+ runner := filepath.Join(runtimeDir, "run.cjs")
120
+ if err := os.WriteFile(runner, []byte(jsonSchemaDynamicKeyDeterminismRuntimeRunner), 0o644); err != nil {
121
+ t.Fatalf("write runtime runner: %v", err)
122
+ }
123
+ cmd := exec.Command(node, runner)
124
+ cmd.Dir = runtimeDir
125
+ output, err := cmd.CombinedOutput()
126
+ if err != nil {
127
+ t.Fatalf("dynamic-key schema runtime cases failed: %v\n%s", err, output)
128
+ }
129
+ }
130
+
131
+ const jsonSchemaDynamicKeyDeterminismTSConfig = `{
132
+ "compilerOptions": {
133
+ "target": "ES2022",
134
+ "module": "commonjs",
135
+ "moduleResolution": "bundler",
136
+ "ignoreDeprecations": "6.0",
137
+ "types": ["*"],
138
+ "esModuleInterop": true,
139
+ "strict": true,
140
+ "skipLibCheck": true
141
+ },
142
+ "include": ["src"]
143
+ }
144
+ `
145
+
146
+ const jsonSchemaDynamicKeyDeterminismSource = `import typia from "typia";
147
+
148
+ interface DynamicComposite {
149
+ id: string;
150
+ name: string;
151
+ [index: number]: number;
152
+ [key: ` + "`prefix_${string}`" + `]: string;
153
+ [key: ` + "`${string}_postfix`" + `]: string;
154
+ [key: ` + "`value_${number}`" + `]: boolean | string | number;
155
+ [key: ` + "`between_${string}_and_${number}`" + `]: boolean;
156
+ }
157
+
158
+ interface DynamicTemplate {
159
+ [key: ` + "`prefix_${string}`" + `]: string;
160
+ [key: ` + "`${string}_postfix`" + `]: string;
161
+ [key: ` + "`value_${number}`" + `]: number;
162
+ [key: ` + "`between_${string}_and_${number}`" + `]: boolean;
163
+ }
164
+
165
+ interface DynamicUnion {
166
+ [key: number | ` + "`prefix_${string}`" + ` | ` + "`${string}_postfix`" + `]: string;
167
+ [key: ` + "`value_between_${number}_and_${number}`" + `]: number;
168
+ }
169
+
170
+ interface LiteralOnly {
171
+ z: string;
172
+ a: number;
173
+ }
174
+
175
+ interface SingleDynamic {
176
+ [key: ` + "`only_${string}`" + `]: string;
177
+ }
178
+
179
+ type OrdinaryUnion = string | number;
180
+
181
+ export const schemas = typia.json.schemas<[
182
+ DynamicComposite,
183
+ DynamicTemplate,
184
+ DynamicUnion,
185
+ LiteralOnly,
186
+ SingleDynamic,
187
+ OrdinaryUnion,
188
+ ]>();
189
+ `
190
+
191
+ const jsonSchemaDynamicKeyDeterminismRuntimeRunner = `const unit = require("./main.cjs").schemas;
192
+
193
+ const components = unit.components?.schemas ?? {};
194
+ const assertTypes = (name, expected) => {
195
+ const additional = components[name]?.additionalProperties;
196
+ const actual = Array.isArray(additional?.oneOf)
197
+ ? additional.oneOf.map((schema) => schema.type)
198
+ : [additional?.type];
199
+ if (JSON.stringify(actual) !== JSON.stringify(expected)) {
200
+ throw new Error(name + " branches were " + JSON.stringify(actual) + ", expected " + JSON.stringify(expected));
201
+ }
202
+ };
203
+
204
+ assertTypes("DynamicComposite", ["number", "string", "boolean"]);
205
+ assertTypes("DynamicTemplate", ["string", "number", "boolean"]);
206
+ assertTypes("DynamicUnion", ["string", "number"]);
207
+
208
+ const literal = components.LiteralOnly;
209
+ const literalShape = {
210
+ type: literal?.type,
211
+ propertyKeys: Object.keys(literal?.properties ?? {}),
212
+ propertyTypes: Object.values(literal?.properties ?? {}).map((schema) => schema.type),
213
+ required: literal?.required,
214
+ additionalProperties: literal?.additionalProperties,
215
+ };
216
+ const expectedLiteralShape = {
217
+ type: "object",
218
+ propertyKeys: ["z", "a"],
219
+ propertyTypes: ["string", "number"],
220
+ required: ["z", "a"],
221
+ additionalProperties: false,
222
+ };
223
+ if (JSON.stringify(literalShape) !== JSON.stringify(expectedLiteralShape)) {
224
+ throw new Error("zero-dynamic literal schema changed: " + JSON.stringify(literalShape));
225
+ }
226
+ if (components.SingleDynamic?.additionalProperties?.type !== "string") {
227
+ throw new Error("single dynamic-key schema changed: " + JSON.stringify(components.SingleDynamic));
228
+ }
229
+ const ordinaryTypes = components.OrdinaryUnion?.oneOf?.map((schema) => schema.type) ?? [];
230
+ if (JSON.stringify(ordinaryTypes) !== JSON.stringify(["string", "number"])) {
231
+ throw new Error("ordinary union branches changed: " + JSON.stringify(ordinaryTypes));
232
+ }
233
+
234
+ const refs = unit.schemas.map((schema) => schema.$ref);
235
+ const expectedRefs = [
236
+ "#/components/schemas/DynamicComposite",
237
+ "#/components/schemas/DynamicTemplate",
238
+ "#/components/schemas/DynamicUnion",
239
+ "#/components/schemas/LiteralOnly",
240
+ "#/components/schemas/SingleDynamic",
241
+ "#/components/schemas/OrdinaryUnion",
242
+ ];
243
+ if (JSON.stringify(refs) !== JSON.stringify(expectedRefs)) {
244
+ throw new Error("schema order changed: " + JSON.stringify(refs));
245
+ }
246
+ `