typia 13.1.19 → 13.2.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 (169) 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/internal/_ProtobufReader.d.ts +18 -3
  11. package/lib/internal/_ProtobufReader.js +39 -11
  12. package/lib/internal/_ProtobufReader.js.map +1 -1
  13. package/lib/internal/_ProtobufReader.mjs +37 -10
  14. package/lib/internal/_ProtobufReader.mjs.map +1 -1
  15. package/lib/internal/_jsonStringifyArray.d.ts +1 -0
  16. package/lib/internal/_jsonStringifyArray.js +48 -0
  17. package/lib/internal/_jsonStringifyArray.js.map +1 -0
  18. package/lib/internal/_jsonStringifyArray.mjs +40 -0
  19. package/lib/internal/_jsonStringifyArray.mjs.map +1 -0
  20. package/lib/internal/_jsonStringifyElement.d.ts +1 -0
  21. package/lib/internal/_jsonStringifyElement.js +23 -0
  22. package/lib/internal/_jsonStringifyElement.js.map +1 -0
  23. package/lib/internal/_jsonStringifyElement.mjs +23 -0
  24. package/lib/internal/_jsonStringifyElement.mjs.map +1 -0
  25. package/lib/internal/_jsonStringifyProperty.d.ts +1 -0
  26. package/lib/internal/_jsonStringifyProperty.js +31 -0
  27. package/lib/internal/_jsonStringifyProperty.js.map +1 -0
  28. package/lib/internal/_jsonStringifyProperty.mjs +31 -0
  29. package/lib/internal/_jsonStringifyProperty.mjs.map +1 -0
  30. package/lib/internal/_llmApplicationFinalize.js +1 -1
  31. package/lib/internal/_llmApplicationFinalize.js.map +1 -1
  32. package/lib/internal/_llmApplicationFinalize.mjs +1 -1
  33. package/lib/internal/_llmApplicationFinalize.mjs.map +1 -1
  34. package/lib/internal/_randomFormatByte.js +24 -1
  35. package/lib/internal/_randomFormatByte.js.map +1 -1
  36. package/lib/internal/_randomFormatByte.mjs +20 -2
  37. package/lib/internal/_randomFormatByte.mjs.map +1 -1
  38. package/lib/internal/_randomFormatDate.d.ts +3 -6
  39. package/lib/internal/_randomFormatDate.js +2 -10
  40. package/lib/internal/_randomFormatDate.js.map +1 -1
  41. package/lib/internal/_randomFormatDate.mjs +2 -6
  42. package/lib/internal/_randomFormatDate.mjs.map +1 -1
  43. package/lib/internal/_randomFormatDatetime.d.ts +3 -6
  44. package/lib/internal/_randomFormatDatetime.js +25 -8
  45. package/lib/internal/_randomFormatDatetime.js.map +1 -1
  46. package/lib/internal/_randomFormatDatetime.mjs +17 -7
  47. package/lib/internal/_randomFormatDatetime.mjs.map +1 -1
  48. package/lib/internal/_randomFormatDuration.js +23 -15
  49. package/lib/internal/_randomFormatDuration.js.map +1 -1
  50. package/lib/internal/_randomFormatDuration.mjs +23 -15
  51. package/lib/internal/_randomFormatDuration.mjs.map +1 -1
  52. package/lib/internal/_randomFormatIpv4.js +31 -1
  53. package/lib/internal/_randomFormatIpv4.js.map +1 -1
  54. package/lib/internal/_randomFormatIpv4.mjs +23 -2
  55. package/lib/internal/_randomFormatIpv4.mjs.map +1 -1
  56. package/lib/internal/_randomFormatIpv6.js +57 -1
  57. package/lib/internal/_randomFormatIpv6.js.map +1 -1
  58. package/lib/internal/_randomFormatIpv6.mjs +45 -2
  59. package/lib/internal/_randomFormatIpv6.mjs.map +1 -1
  60. package/lib/internal/_randomFormatJsonPointer.js +14 -2
  61. package/lib/internal/_randomFormatJsonPointer.js.map +1 -1
  62. package/lib/internal/_randomFormatJsonPointer.mjs +13 -3
  63. package/lib/internal/_randomFormatJsonPointer.mjs.map +1 -1
  64. package/lib/internal/_randomFormatRegex.js +14 -1
  65. package/lib/internal/_randomFormatRegex.js.map +1 -1
  66. package/lib/internal/_randomFormatRegex.mjs +14 -2
  67. package/lib/internal/_randomFormatRegex.mjs.map +1 -1
  68. package/lib/internal/_randomFormatRelativeJsonPointer.js +19 -5
  69. package/lib/internal/_randomFormatRelativeJsonPointer.js.map +1 -1
  70. package/lib/internal/_randomFormatRelativeJsonPointer.mjs +21 -6
  71. package/lib/internal/_randomFormatRelativeJsonPointer.mjs.map +1 -1
  72. package/lib/internal/_randomFormatTime.js +33 -7
  73. package/lib/internal/_randomFormatTime.js.map +1 -1
  74. package/lib/internal/_randomFormatTime.mjs +37 -5
  75. package/lib/internal/_randomFormatTime.mjs.map +1 -1
  76. package/lib/internal/_randomPattern.js.map +1 -1
  77. package/lib/internal/_randomPattern.mjs.map +1 -1
  78. package/lib/internal/_randomStringLength.d.ts +41 -10
  79. package/lib/internal/_randomStringLength.js +49 -13
  80. package/lib/internal/_randomStringLength.js.map +1 -1
  81. package/lib/internal/_randomStringLength.mjs +48 -13
  82. package/lib/internal/_randomStringLength.mjs.map +1 -1
  83. package/lib/internal/private/__notationRename.js.map +1 -1
  84. package/lib/internal/private/__notationRename.mjs.map +1 -1
  85. package/lib/internal/private/__randomComposition.d.ts +23 -0
  86. package/lib/internal/private/__randomComposition.js +48 -0
  87. package/lib/internal/private/__randomComposition.js.map +1 -0
  88. package/lib/internal/private/__randomComposition.mjs +54 -0
  89. package/lib/internal/private/__randomComposition.mjs.map +1 -0
  90. package/lib/internal/private/__randomEpoch.d.ts +19 -0
  91. package/lib/internal/private/__randomEpoch.js +31 -0
  92. package/lib/internal/private/__randomEpoch.js.map +1 -0
  93. package/lib/internal/private/__randomEpoch.mjs +28 -0
  94. package/lib/internal/private/__randomEpoch.mjs.map +1 -0
  95. package/native/cmd/ttsc-typia/build.go +3 -0
  96. package/native/cmd/ttsc-typia/callable_interface_function_semantics_transform_test.go +331 -0
  97. package/native/cmd/ttsc-typia/callable_type_literal_boundaries_transform_test.go +1184 -0
  98. package/native/cmd/ttsc-typia/compare_functional_union_membership_transform_test.go +434 -0
  99. package/native/cmd/ttsc-typia/compare_template_literal_union_transform_test.go +241 -0
  100. package/native/cmd/ttsc-typia/default_library_spoof_native_identity_transform_test.go +216 -0
  101. package/native/cmd/ttsc-typia/json_schema_dynamic_key_determinism_transform_test.go +246 -0
  102. package/native/cmd/ttsc-typia/json_stringify_contextual_undefined_transform_test.go +556 -0
  103. package/native/cmd/ttsc-typia/lib_replacement_native_identity_transform_test.go +277 -0
  104. package/native/cmd/ttsc-typia/native_named_intersection_union_transform_test.go +390 -0
  105. package/native/cmd/ttsc-typia/node_buffer_native_exports_is_transform_test.go +526 -0
  106. package/native/cmd/ttsc-typia/package_declaration_native_identity_is_transform_test.go +293 -0
  107. package/native/cmd/ttsc-typia/protobuf_diagnostic_code_transform_test.go +167 -0
  108. package/native/cmd/ttsc-typia/symbol_index_domain_transform_test.go +316 -0
  109. package/native/cmd/ttsc-typia/transform.go +23 -0
  110. package/native/cmd/ttsc-typia/transform_helpers_test.go +77 -2
  111. package/native/cmd/ttsc-typia/user_global_native_identity_transform_test.go +484 -0
  112. package/native/core/factories/ProtobufFactory.go +6 -1
  113. package/native/core/factories/internal/metadata/MetadataHelper.go +185 -30
  114. package/native/core/factories/internal/metadata/emplace_metadata_object.go +25 -0
  115. package/native/core/factories/internal/metadata/iterate_metadata_function.go +1 -1
  116. package/native/core/factories/internal/metadata/iterate_metadata_intersection.go +103 -23
  117. package/native/core/factories/internal/metadata/iterate_metadata_map.go +3 -7
  118. package/native/core/factories/internal/metadata/iterate_metadata_native.go +32 -14
  119. package/native/core/factories/internal/metadata/iterate_metadata_set.go +3 -7
  120. package/native/core/programmers/compare/CompareEqualProgrammer.go +27 -13
  121. package/native/core/programmers/helpers/FunctionProgrammer.go +6 -13
  122. package/native/core/programmers/helpers/StringifyJoinder.go +129 -50
  123. package/native/core/programmers/helpers/joiner_branch_coverage_test.go +116 -120
  124. package/native/core/programmers/iterate/iterate_check_coverage_test.go +76 -158
  125. package/native/core/programmers/iterate/iterate_utility_coverage_test.go +231 -270
  126. package/native/core/programmers/iterate/json_schema_object.go +49 -7
  127. package/native/core/programmers/iterate/json_schema_pattern_property_order_test.go +44 -0
  128. package/native/core/programmers/iterate/openapi_v3_downgrader.go +34 -1
  129. package/native/core/programmers/iterate/template_runtime_pattern.go +11 -0
  130. package/native/core/programmers/json/JsonStringifyProgrammer.go +47 -6
  131. package/native/core/programmers/llm/LlmApplicationProgrammer.go +9 -1
  132. package/native/core/programmers/protobuf/ProtobufMessageProgrammer.go +1 -1
  133. package/native/core/schemas/metadata/MetadataCollection.go +0 -9
  134. package/native/core/schemas/metadata/MetadataDefaultLibrary.go +81 -0
  135. package/native/core/schemas/metadata/MetadataObjectType.go +7 -18
  136. package/native/go.mod +4 -4
  137. package/native/transform/features/protobuf/ProtobufMessageTransformer.go +1 -1
  138. package/package.json +3 -7
  139. package/src/executable/FileSystemIdentity.ts +33 -0
  140. package/src/executable/TypiaGenerateWizard.ts +18 -12
  141. package/src/internal/_ProtobufReader.ts +40 -11
  142. package/src/internal/_jsonStringifyArray.ts +50 -0
  143. package/src/internal/_jsonStringifyElement.ts +19 -0
  144. package/src/internal/_jsonStringifyProperty.ts +30 -0
  145. package/src/internal/_llmApplicationFinalize.ts +6 -1
  146. package/src/internal/_randomFormatByte.ts +30 -3
  147. package/src/internal/_randomFormatDate.ts +4 -20
  148. package/src/internal/_randomFormatDatetime.ts +34 -20
  149. package/src/internal/_randomFormatDuration.ts +19 -4
  150. package/src/internal/_randomFormatIpv4.ts +43 -3
  151. package/src/internal/_randomFormatIpv6.ts +67 -3
  152. package/src/internal/_randomFormatJsonPointer.ts +23 -3
  153. package/src/internal/_randomFormatRegex.ts +21 -3
  154. package/src/internal/_randomFormatRelativeJsonPointer.ts +23 -10
  155. package/src/internal/_randomFormatTime.ts +45 -12
  156. package/src/internal/_randomPattern.ts +4 -1
  157. package/src/internal/_randomStringLength.ts +61 -17
  158. package/src/internal/private/__notationRename.ts +1 -4
  159. package/src/internal/private/__randomComposition.ts +50 -0
  160. package/src/internal/private/__randomEpoch.ts +34 -0
  161. package/native/adapter/visit.go +0 -173
  162. package/native/adapter/visit_property_chain_edges_test.go +0 -129
  163. package/native/core/programmers/helpers/disable_function_programmer_declare.go +0 -10
  164. package/native/core/programmers/iterate/check_union_array_like.go +0 -422
  165. package/native/core/programmers/iterate/prune_object_properties.go +0 -105
  166. package/native/core/programmers/iterate/stringify_dynamic_properties.go +0 -219
  167. package/native/core/programmers/iterate/stringify_native.go +0 -14
  168. package/native/core/programmers/iterate/stringify_regular_properties.go +0 -112
  169. package/native/core/schemas/metadata/MetadataApplication.go +0 -41
@@ -0,0 +1,484 @@
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "os"
6
+ "os/exec"
7
+ "path/filepath"
8
+ "strings"
9
+ "testing"
10
+ )
11
+
12
+ // TestUserGlobalNativeIdentityTransform keeps a user-authored global structural
13
+ // while a runtime-provided global of the same name stays runtime-native (#2200).
14
+ //
15
+ // Winning the checker's global type table proves only that a declaration is
16
+ // global. A project whose sole `File` or `Blob` declaration is its own `declare
17
+ // global` block wins that same lookup, so a resolution-only identity gate erases
18
+ // the user's members, emits `input instanceof File`, and throws `ReferenceError`
19
+ // wherever no runtime supplies that constructor. Native classification therefore
20
+ // has to ask which authority provides the constructor, and it must ask that
21
+ // question without demoting the genuine default-library, Node bare-global, or
22
+ // augmented natives that legitimately answer it.
23
+ //
24
+ // 1. Transform a project whose only File/Blob declarations are user globals in
25
+ // both the interface and the class spelling, one of them carrying its own
26
+ // `declare var` constructor binding, across is/assert/assertGuard/validate/
27
+ // equals/random, direct and factory forms, and alias, nested, intersection,
28
+ // union, and re-exported compositions.
29
+ // 2. Transform that project's json, protobuf, and llm schema surfaces, which a
30
+ // native classification removes from those consumers entirely.
31
+ // 3. Transform a global `type` alias spelling of the same collision in a second
32
+ // project, and near-miss control names in the first.
33
+ // 4. Transform a third project where @types/node provides the runtime bridge
34
+ // and the user contributes only an empty augmentation, requiring every
35
+ // default-library and Node-provided native to keep its `instanceof` check.
36
+ // 5. Execute every emitted validator in Node against structural user values and
37
+ // against the real runtime instances, requiring exact case counts so a
38
+ // dropped branch cannot pass silently.
39
+ func TestUserGlobalNativeIdentityTransform(t *testing.T) {
40
+ project := userGlobalNativeIdentityProject(t)
41
+ aliasProject := userGlobalNativeIdentityAliasProject(t)
42
+ providedProject := userGlobalNativeIdentityProvidedProject(t)
43
+ transform := func(dir string, file string) string {
44
+ t.Helper()
45
+ js, errText, code := ttscTypiaTestCapture(func() int {
46
+ return runTransform([]string{
47
+ "--cwd", dir,
48
+ "--tsconfig", "tsconfig.json",
49
+ "--file", file,
50
+ "--output", "js",
51
+ })
52
+ })
53
+ if code != 0 {
54
+ t.Fatalf("user global native identity transform %s/%s failed: code=%d stderr=\n%s", dir, file, code, errText)
55
+ }
56
+ return js
57
+ }
58
+
59
+ js := transform(project, "src/input.ts")
60
+ schemasJS := transform(project, "src/schemas.ts")
61
+ controlsJS := transform(project, "src/controls.ts")
62
+ aliasJS := transform(aliasProject, "src/input.ts")
63
+ providedJS := transform(providedProject, "src/input.ts")
64
+
65
+ failures := []string{}
66
+ for _, native := range []string{"instanceof File", "instanceof Blob"} {
67
+ for name, emit := range map[string]string{
68
+ "validator emit": js,
69
+ "schema emit": schemasJS,
70
+ "type alias emit": aliasJS,
71
+ "near-miss control": controlsJS,
72
+ } {
73
+ if strings.Contains(emit, native) {
74
+ failures = append(failures, fmt.Sprintf("%s promoted a user-authored global to %q", name, native))
75
+ }
76
+ }
77
+ }
78
+ for _, member := range []string{"userBlobBrand", "userFileBrand"} {
79
+ for name, emit := range map[string]string{
80
+ "validator emit": js,
81
+ "schema emit": schemasJS,
82
+ "type alias emit": aliasJS,
83
+ } {
84
+ if !strings.Contains(emit, member) {
85
+ failures = append(failures, fmt.Sprintf("%s dropped user-declared member %q", name, member))
86
+ }
87
+ }
88
+ }
89
+ for _, member := range []string{"intersectionBrand", "unionControl", "nestedHolder"} {
90
+ if !strings.Contains(js, member) {
91
+ failures = append(failures, fmt.Sprintf("validator emit dropped composition member %q", member))
92
+ }
93
+ }
94
+ for _, member := range []string{"nearMissBrand", "prefixBrand"} {
95
+ if !strings.Contains(controlsJS, member) {
96
+ failures = append(failures, fmt.Sprintf("near-miss control emit dropped member %q", member))
97
+ }
98
+ }
99
+ for _, kept := range []string{
100
+ "instanceof Date",
101
+ "instanceof RegExp",
102
+ "instanceof Uint8Array",
103
+ "instanceof Map",
104
+ "instanceof Set",
105
+ "instanceof WeakMap",
106
+ "instanceof WeakSet",
107
+ "instanceof File",
108
+ "instanceof Blob",
109
+ } {
110
+ if !strings.Contains(providedJS, kept) {
111
+ failures = append(failures, fmt.Sprintf("runtime-provided native lost %q", kept))
112
+ }
113
+ }
114
+
115
+ output, runtimeErr := userGlobalNativeIdentityRun(t, project, js, controlsJS)
116
+ if runtimeErr != nil {
117
+ failures = append(failures, fmt.Sprintf("user global runtime matrix failed: %v\n%s", runtimeErr, output))
118
+ }
119
+ // Counted from the runner's own table, which is the ground truth: 11 rows for
120
+ // the is/assert/assertGuard/validate/equals/random matrix, 15 for the
121
+ // createIs forms across direct, alias, re-export, branded intersection, union,
122
+ // and nested positions, and 2 near-miss name controls. The count is asserted
123
+ // rather than the exit code so a row that silently stops running cannot pass
124
+ // as a row that ran and agreed.
125
+ if expected := "RAN 28 USER GLOBAL CASES"; !strings.Contains(output, expected) {
126
+ failures = append(failures, fmt.Sprintf("user global runner did not report %q; got:\n%s", expected, output))
127
+ }
128
+ providedOutput, providedErr := userGlobalNativeIdentityProvidedRun(t, providedProject, providedJS)
129
+ if providedErr != nil {
130
+ failures = append(failures, fmt.Sprintf("runtime-provided matrix failed: %v\n%s", providedErr, providedOutput))
131
+ }
132
+ if expected := "RAN 18 PROVIDED CASES"; !strings.Contains(providedOutput, expected) {
133
+ failures = append(failures, fmt.Sprintf("provided runner did not report %q; got:\n%s", expected, providedOutput))
134
+ }
135
+
136
+ if len(failures) != 0 {
137
+ t.Fatalf(
138
+ "user global native identity mismatches:\n%s\n\nvalidator emit:\n%s\n\nschema emit:\n%s\n\nalias emit:\n%s\n\ncontrol emit:\n%s\n\nprovided emit:\n%s",
139
+ strings.Join(failures, "\n"),
140
+ js,
141
+ schemasJS,
142
+ aliasJS,
143
+ controlsJS,
144
+ providedJS,
145
+ )
146
+ }
147
+ }
148
+
149
+ func userGlobalNativeIdentityWriteProject(t *testing.T, prefix string, files map[string]string) string {
150
+ t.Helper()
151
+ root := ttscTypiaTestRepoRoot(t)
152
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
153
+ if err := os.MkdirAll(base, 0o755); err != nil {
154
+ t.Fatalf("mkdir temp base: %v", err)
155
+ }
156
+ dir, err := os.MkdirTemp(base, prefix)
157
+ if err != nil {
158
+ t.Fatalf("create temp fixture: %v", err)
159
+ }
160
+ t.Cleanup(func() {
161
+ _ = os.RemoveAll(dir)
162
+ })
163
+ for name, content := range files {
164
+ path := filepath.Join(dir, filepath.FromSlash(name))
165
+ if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
166
+ t.Fatalf("mkdir fixture path %s: %v", filepath.Dir(path), err)
167
+ }
168
+ if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
169
+ t.Fatalf("write fixture file %s: %v", path, err)
170
+ }
171
+ }
172
+ return dir
173
+ }
174
+
175
+ func userGlobalNativeIdentityProject(t *testing.T) string {
176
+ t.Helper()
177
+ return userGlobalNativeIdentityWriteProject(t, "user-global-native-identity-", map[string]string{
178
+ "tsconfig.json": userGlobalNativeIdentityTSConfig,
179
+ "src/globals.d.ts": userGlobalNativeIdentityGlobals,
180
+ "src/reexport.ts": userGlobalNativeIdentityReexport,
181
+ "src/input.ts": userGlobalNativeIdentitySource,
182
+ "src/schemas.ts": userGlobalNativeIdentitySchemaSource,
183
+ "src/controls.ts": userGlobalNativeIdentityControlSource,
184
+ })
185
+ }
186
+
187
+ func userGlobalNativeIdentityAliasProject(t *testing.T) string {
188
+ t.Helper()
189
+ return userGlobalNativeIdentityWriteProject(t, "user-global-native-identity-alias-", map[string]string{
190
+ "tsconfig.json": userGlobalNativeIdentityTSConfig,
191
+ "src/globals.d.ts": userGlobalNativeIdentityAliasGlobals,
192
+ "src/input.ts": userGlobalNativeIdentityAliasSource,
193
+ })
194
+ }
195
+
196
+ func userGlobalNativeIdentityProvidedProject(t *testing.T) string {
197
+ t.Helper()
198
+ return userGlobalNativeIdentityWriteProject(t, "user-global-native-identity-provided-", map[string]string{
199
+ "tsconfig.json": userGlobalNativeIdentityProvidedTSConfig,
200
+ "src/globals.d.ts": userGlobalNativeIdentityProvidedGlobals,
201
+ "src/input.ts": userGlobalNativeIdentityProvidedSource,
202
+ })
203
+ }
204
+
205
+ func userGlobalNativeIdentityRunner(t *testing.T, project string, modules map[string]string) (string, error) {
206
+ t.Helper()
207
+ node, err := exec.LookPath("node")
208
+ if err != nil {
209
+ t.Skip("node executable not found")
210
+ return "", nil
211
+ }
212
+ runtimeDir := filepath.Join(project, "runtime")
213
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
214
+ t.Fatalf("mkdir runtime dir: %v", err)
215
+ }
216
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
217
+ for name, content := range modules {
218
+ if err := os.WriteFile(filepath.Join(runtimeDir, name), []byte(content), 0o644); err != nil {
219
+ t.Fatalf("write runtime file %s: %v", name, err)
220
+ }
221
+ }
222
+ cmd := exec.Command(node, filepath.Join(runtimeDir, "run.cjs"))
223
+ cmd.Dir = runtimeDir
224
+ output, err := cmd.CombinedOutput()
225
+ return string(output), err
226
+ }
227
+
228
+ func userGlobalNativeIdentityRun(t *testing.T, project string, js string, controlsJS string) (string, error) {
229
+ t.Helper()
230
+ return userGlobalNativeIdentityRunner(t, project, map[string]string{
231
+ "input.cjs": ttscTypiaTestRewriteCommonJS(t, js),
232
+ "controls.cjs": ttscTypiaTestRewriteCommonJS(t, controlsJS),
233
+ "run.cjs": userGlobalNativeIdentityRuntimeRunner,
234
+ })
235
+ }
236
+
237
+ func userGlobalNativeIdentityProvidedRun(t *testing.T, project string, js string) (string, error) {
238
+ t.Helper()
239
+ return userGlobalNativeIdentityRunner(t, project, map[string]string{
240
+ "input.cjs": ttscTypiaTestRewriteCommonJS(t, js),
241
+ "run.cjs": userGlobalNativeIdentityProvidedRuntimeRunner,
242
+ })
243
+ }
244
+
245
+ const userGlobalNativeIdentityTSConfig = `{
246
+ "compilerOptions": {
247
+ "target": "ES2022",
248
+ "module": "commonjs",
249
+ "moduleResolution": "bundler",
250
+ "ignoreDeprecations": "6.0",
251
+ "lib": ["ES2022"],
252
+ "types": [],
253
+ "esModuleInterop": true,
254
+ "strict": true,
255
+ "skipLibCheck": true
256
+ },
257
+ "include": ["src"]
258
+ }
259
+ `
260
+
261
+ const userGlobalNativeIdentityProvidedTSConfig = `{
262
+ "compilerOptions": {
263
+ "target": "ES2022",
264
+ "module": "commonjs",
265
+ "moduleResolution": "bundler",
266
+ "ignoreDeprecations": "6.0",
267
+ "lib": ["ES2022"],
268
+ "types": ["node"],
269
+ "esModuleInterop": true,
270
+ "strict": true,
271
+ "skipLibCheck": true
272
+ },
273
+ "include": ["src"]
274
+ }
275
+ `
276
+
277
+ // userGlobalNativeIdentityGlobals is the whole runtime-native declaration set of
278
+ // its project: neither the DOM libraries nor @types/node is loaded, so Blob and
279
+ // File exist only because this file declares them. Blob is the interface-only
280
+ // spelling and File is the class spelling, which additionally gives File a
281
+ // user-owned constructor binding — the one signal a runtime provider would
282
+ // otherwise be recognized by.
283
+ const userGlobalNativeIdentityGlobals = `export {};
284
+
285
+ declare global {
286
+ interface Blob {
287
+ userBlobBrand: string;
288
+ }
289
+ class File {
290
+ userBlobBrand: string;
291
+ userFileBrand: string;
292
+ }
293
+ }
294
+ `
295
+
296
+ const userGlobalNativeIdentityReexport = `export type ReexportedFile = File;
297
+ `
298
+
299
+ const userGlobalNativeIdentitySource = `import typia from "typia";
300
+ import type { ReexportedFile } from "./reexport";
301
+
302
+ type FileAlias = File;
303
+ type BrandedFile = File & { intersectionBrand: string };
304
+ type FileUnion = BrandedFile | { unionControl: boolean };
305
+ type NestedFile = { nestedHolder: File };
306
+
307
+ export const isFile = (input: unknown): boolean => typia.is<File>(input);
308
+ export const assertFile = (input: unknown): File => typia.assert<File>(input);
309
+ export const assertGuardFile = (input: unknown): void => typia.assertGuard<File>(input);
310
+ export const validateFile = (input: unknown) => typia.validate<File>(input);
311
+ export const equalsFile = (input: unknown): boolean => typia.equals<File>(input);
312
+ export const randomBlob = (): Blob => typia.random<Blob>();
313
+
314
+ export const createdIsBlob = typia.createIs<Blob>();
315
+ export const createdIsFile = typia.createIs<File>();
316
+ export const createdIsAlias = typia.createIs<FileAlias>();
317
+ export const createdIsReexported = typia.createIs<ReexportedFile>();
318
+ export const createdIsBranded = typia.createIs<BrandedFile>();
319
+ export const createdIsUnion = typia.createIs<FileUnion>();
320
+ export const createdIsNested = typia.createIs<NestedFile>();
321
+ `
322
+
323
+ const userGlobalNativeIdentitySchemaSource = `import typia from "typia";
324
+
325
+ export const jsonSchema = typia.json.schema<File>();
326
+ export const jsonStringify = typia.json.createStringify<File>();
327
+ export const jsonIsStringify = typia.json.createIsStringify<File>();
328
+ export const protobufMessage = typia.protobuf.message<Blob>();
329
+ export const protobufEncode = typia.protobuf.createIsEncode<Blob>();
330
+ export const llmSchema = typia.llm.schema<File>({});
331
+ `
332
+
333
+ const userGlobalNativeIdentityControlSource = `import typia from "typia";
334
+
335
+ interface FileEntry {
336
+ nearMissBrand: string;
337
+ }
338
+ interface Blobby {
339
+ prefixBrand: string;
340
+ }
341
+
342
+ export const createdIsFileEntry = typia.createIs<FileEntry>();
343
+ export const createdIsBlobby = typia.createIs<Blobby>();
344
+ `
345
+
346
+ // userGlobalNativeIdentityAliasGlobals spells the same collision as a global
347
+ // `type` alias, whose symbol is an anonymous type literal rather than a named
348
+ // declaration. It is the negative twin that proves the classification is decided
349
+ // by declaration provenance rather than by the shape of the declaring node.
350
+ const userGlobalNativeIdentityAliasGlobals = `export {};
351
+
352
+ declare global {
353
+ type Blob = { userBlobBrand: string };
354
+ type File = { userBlobBrand: string; userFileBrand: string };
355
+ }
356
+ `
357
+
358
+ const userGlobalNativeIdentityAliasSource = `import typia from "typia";
359
+
360
+ export const isAliasFile = (input: unknown): boolean => typia.is<File>(input);
361
+ export const createdIsAliasBlob = typia.createIs<Blob>();
362
+ `
363
+
364
+ // userGlobalNativeIdentityProvidedGlobals is the positive control: @types/node
365
+ // bridges the node:buffer constructors to the bare globals, and the user adds
366
+ // only an empty augmentation. Merging a declaration into a runtime-provided
367
+ // global must not change what provides that global.
368
+ const userGlobalNativeIdentityProvidedGlobals = `export {};
369
+
370
+ declare global {
371
+ interface Blob {}
372
+ interface File {}
373
+ }
374
+ `
375
+
376
+ const userGlobalNativeIdentityProvidedSource = `import typia from "typia";
377
+
378
+ export const createdIsDate = typia.createIs<Date>();
379
+ export const createdIsRegExp = typia.createIs<RegExp>();
380
+ export const createdIsBytes = typia.createIs<Uint8Array>();
381
+ export const createdIsMap = typia.createIs<Map<string, number>>();
382
+ export const createdIsSet = typia.createIs<Set<string>>();
383
+ export const createdIsWeakMap = typia.createIs<WeakMap<object, string>>();
384
+ export const createdIsWeakSet = typia.createIs<WeakSet<object>>();
385
+ export const createdIsFile = typia.createIs<File>();
386
+ export const createdIsBlob = typia.createIs<Blob>();
387
+ `
388
+
389
+ const userGlobalNativeIdentityRuntimeRunner = `const validators = require("./input.cjs");
390
+ const controls = require("./controls.cjs");
391
+
392
+ let ran = 0;
393
+ const failures = [];
394
+ const eq = (name, actual, expected) => {
395
+ ran += 1;
396
+ if (actual !== expected) {
397
+ failures.push(name + ": expected " + expected + " but got " + actual);
398
+ }
399
+ };
400
+ const throws = (name, run) => {
401
+ ran += 1;
402
+ try {
403
+ run();
404
+ failures.push(name + ": expected a throw but none happened");
405
+ } catch {}
406
+ };
407
+
408
+ const userBlob = { userBlobBrand: "user" };
409
+ const userFile = { userBlobBrand: "user", userFileBrand: "user" };
410
+ const realBlob = new Blob(["x"]);
411
+ const realFile = new File(["x"], "x.txt");
412
+
413
+ eq("is user File", validators.isFile(userFile), true);
414
+ eq("is real File", validators.isFile(realFile), false);
415
+ eq("assert user File", validators.assertFile(userFile), userFile);
416
+ throws("assert real File", () => validators.assertFile(realFile));
417
+ eq("assertGuard user File", validators.assertGuardFile(userFile), undefined);
418
+ throws("assertGuard real File", () => validators.assertGuardFile(realFile));
419
+ eq("validate user File", validators.validateFile(userFile).success, true);
420
+ eq("validate real File", validators.validateFile(realFile).success, false);
421
+ eq("equals user File", validators.equalsFile(userFile), true);
422
+ eq("equals real File", validators.equalsFile(realFile), false);
423
+ eq("random Blob brand", typeof validators.randomBlob().userBlobBrand, "string");
424
+
425
+ eq("createIs user Blob", validators.createdIsBlob(userBlob), true);
426
+ eq("createIs real Blob", validators.createdIsBlob(realBlob), false);
427
+ eq("createIs user File", validators.createdIsFile(userFile), true);
428
+ eq("createIs real File", validators.createdIsFile(realFile), false);
429
+ eq("alias user File", validators.createdIsAlias(userFile), true);
430
+ eq("alias real File", validators.createdIsAlias(realFile), false);
431
+ eq("re-export user File", validators.createdIsReexported(userFile), true);
432
+ eq("re-export real File", validators.createdIsReexported(realFile), false);
433
+ eq("branded user File", validators.createdIsBranded({ ...userFile, intersectionBrand: "x" }), true);
434
+ eq("branded user File without brand", validators.createdIsBranded(userFile), false);
435
+ eq("union branded arm", validators.createdIsUnion({ ...userFile, intersectionBrand: "x" }), true);
436
+ eq("union control arm", validators.createdIsUnion({ unionControl: true }), true);
437
+ eq("union rejects real File", validators.createdIsUnion(realFile), false);
438
+ eq("nested user File", validators.createdIsNested({ nestedHolder: userFile }), true);
439
+ eq("nested real File", validators.createdIsNested({ nestedHolder: realFile }), false);
440
+
441
+ eq("near-miss FileEntry", controls.createdIsFileEntry({ nearMissBrand: "x" }), true);
442
+ eq("prefix Blobby", controls.createdIsBlobby({ prefixBrand: "x" }), true);
443
+
444
+ console.log("RAN " + ran + " USER GLOBAL CASES");
445
+ if (failures.length !== 0) {
446
+ throw new Error("MISMATCHES:\n" + failures.join("\n"));
447
+ }
448
+ `
449
+
450
+ const userGlobalNativeIdentityProvidedRuntimeRunner = `const validators = require("./input.cjs");
451
+
452
+ let ran = 0;
453
+ const failures = [];
454
+ const eq = (name, actual, expected) => {
455
+ ran += 1;
456
+ if (actual !== expected) {
457
+ failures.push(name + ": expected " + expected + " but got " + actual);
458
+ }
459
+ };
460
+
461
+ eq("Date real", validators.createdIsDate(new Date()), true);
462
+ eq("Date plain", validators.createdIsDate({}), false);
463
+ eq("RegExp real", validators.createdIsRegExp(/x/), true);
464
+ eq("RegExp plain", validators.createdIsRegExp({}), false);
465
+ eq("Uint8Array real", validators.createdIsBytes(new Uint8Array(1)), true);
466
+ eq("Uint8Array plain", validators.createdIsBytes({}), false);
467
+ eq("Map real", validators.createdIsMap(new Map([["x", 1]])), true);
468
+ eq("Map plain", validators.createdIsMap({}), false);
469
+ eq("Set real", validators.createdIsSet(new Set(["x"])), true);
470
+ eq("Set plain", validators.createdIsSet({}), false);
471
+ eq("WeakMap real", validators.createdIsWeakMap(new WeakMap()), true);
472
+ eq("WeakMap plain", validators.createdIsWeakMap({}), false);
473
+ eq("WeakSet real", validators.createdIsWeakSet(new WeakSet()), true);
474
+ eq("WeakSet plain", validators.createdIsWeakSet({}), false);
475
+ eq("File real", validators.createdIsFile(new File(["x"], "x.txt")), true);
476
+ eq("File plain", validators.createdIsFile({ name: "x.txt", size: 1 }), false);
477
+ eq("Blob real", validators.createdIsBlob(new Blob(["x"])), true);
478
+ eq("Blob plain", validators.createdIsBlob({ size: 1, type: "text/plain" }), false);
479
+
480
+ console.log("RAN " + ran + " PROVIDED CASES");
481
+ if (failures.length !== 0) {
482
+ throw new Error("MISMATCHES:\n" + failures.join("\n"));
483
+ }
484
+ `
@@ -17,6 +17,11 @@ type protobufFactoryNamespace struct{}
17
17
  var ProtobufFactory = protobufFactoryNamespace{}
18
18
 
19
19
  type ProtobufFactory_IProps struct {
20
+ // Method is the fully qualified typia API the call site invoked, exactly as
21
+ // it must appear in the diagnostic code (`typia.protobuf.encode`). It is the
22
+ // sole source of that code: composing the code here from a shorter spelling
23
+ // let the encode and decode programmers, which already pass the whole call
24
+ // accessor, report `typia.protobuf.typia.protobuf.encode`.
20
25
  Method string
21
26
  Checker *shimchecker.Checker
22
27
  Components *schemametadata.MetadataCollection
@@ -40,7 +45,7 @@ func (protobufFactoryNamespace) Metadata(props ProtobufFactory_IProps) *schemame
40
45
  Code string
41
46
  Errors []nativecontext.TransformerError_MetadataFactory_IError
42
47
  }{
43
- Code: "typia.protobuf." + props.Method,
48
+ Code: props.Method,
44
49
  Errors: protobufFactory_errors(result.Errors),
45
50
  }))
46
51
  }