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,277 @@
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "os"
6
+ "os/exec"
7
+ "path/filepath"
8
+ "strings"
9
+ "testing"
10
+ )
11
+
12
+ // TestLibReplacementNativeIdentityTransform keeps a `libReplacement` project's
13
+ // natives native even though their declaration file lives in node_modules
14
+ // (#2200).
15
+ //
16
+ // Runtime-native identity requires a runtime authority to declare the global, so
17
+ // which files count as a TypeScript default library became load-bearing. Under
18
+ // `libReplacement` the compiler resolves `lib.es2015.collection.d.ts` to
19
+ // `@typescript/lib-es2015/collection`, an ordinary package file whose name does
20
+ // not even begin with `lib.` — so a file-name rule answers "not a default
21
+ // library" and would demote Map, Set, WeakMap, and WeakSet to structural checks
22
+ // that accept any object. Only the program's own classification is right here,
23
+ // and this fixture is what proves the transform consults it.
24
+ //
25
+ // 1. Publish `@typescript/lib-es2015/collection.d.ts` carrying the real
26
+ // Map/Set/WeakMap/WeakSet declarations plus a probe interface that exists
27
+ // nowhere else, and enable `libReplacement`.
28
+ // 2. Transform validators for the four replaced collection natives, for Date
29
+ // and Uint8Array as bundled-library controls, and for the probe.
30
+ // 3. Require the probe to transform at all, which fails unless the replacement
31
+ // file — not the bundled lib — is what the program loaded.
32
+ // 4. Require every native to keep its `instanceof` check and execute all of
33
+ // them in Node against real instances and plain objects.
34
+ func TestLibReplacementNativeIdentityTransform(t *testing.T) {
35
+ project := libReplacementNativeIdentityProject(t)
36
+ js, errText, code := ttscTypiaTestCapture(func() int {
37
+ return runTransform([]string{
38
+ "--cwd", project,
39
+ "--tsconfig", "tsconfig.json",
40
+ "--file", "src/input.ts",
41
+ "--output", "js",
42
+ })
43
+ })
44
+ if code != 0 {
45
+ t.Fatalf("lib replacement transform failed: code=%d stderr=\n%s", code, errText)
46
+ }
47
+
48
+ failures := []string{}
49
+ if !strings.Contains(js, "libReplacementMarker") {
50
+ failures = append(failures, "emit lost the replacement-only probe member; the project did not load the replaced lib file")
51
+ }
52
+ for _, kept := range []string{
53
+ "instanceof Map",
54
+ "instanceof Set",
55
+ "instanceof WeakMap",
56
+ "instanceof WeakSet",
57
+ "instanceof Date",
58
+ "instanceof Uint8Array",
59
+ } {
60
+ if !strings.Contains(js, kept) {
61
+ failures = append(failures, fmt.Sprintf("replaced or bundled default library native lost %q", kept))
62
+ }
63
+ }
64
+
65
+ output, runtimeErr := libReplacementNativeIdentityRun(t, project, js)
66
+ if runtimeErr != nil {
67
+ failures = append(failures, fmt.Sprintf("runtime matrix failed: %v\n%s", runtimeErr, output))
68
+ }
69
+ if expected := "RAN 13 REPLACEMENT CASES"; !strings.Contains(output, expected) {
70
+ failures = append(failures, fmt.Sprintf("replacement runner did not report %q; got:\n%s", expected, output))
71
+ }
72
+ if len(failures) != 0 {
73
+ t.Fatalf("lib replacement native identity mismatches:\n%s\n\nemit:\n%s", strings.Join(failures, "\n"), js)
74
+ }
75
+ }
76
+
77
+ func libReplacementNativeIdentityProject(t *testing.T) string {
78
+ t.Helper()
79
+ root := ttscTypiaTestRepoRoot(t)
80
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
81
+ if err := os.MkdirAll(base, 0o755); err != nil {
82
+ t.Fatalf("mkdir temp base: %v", err)
83
+ }
84
+ dir, err := os.MkdirTemp(base, "lib-replacement-native-identity-")
85
+ if err != nil {
86
+ t.Fatalf("create temp fixture: %v", err)
87
+ }
88
+ t.Cleanup(func() {
89
+ _ = os.RemoveAll(dir)
90
+ })
91
+ for name, content := range map[string]string{
92
+ "tsconfig.json": libReplacementNativeIdentityTSConfig,
93
+ "node_modules/@typescript/lib-es2015/package.json": libReplacementNativeIdentityPackageJSON,
94
+ "node_modules/@typescript/lib-es2015/collection.d.ts": libReplacementNativeIdentityCollectionLib,
95
+ "src/input.ts": libReplacementNativeIdentitySource,
96
+ } {
97
+ path := filepath.Join(dir, filepath.FromSlash(name))
98
+ if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
99
+ t.Fatalf("mkdir fixture path %s: %v", filepath.Dir(path), err)
100
+ }
101
+ if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
102
+ t.Fatalf("write fixture file %s: %v", path, err)
103
+ }
104
+ }
105
+ return dir
106
+ }
107
+
108
+ func libReplacementNativeIdentityRun(t *testing.T, project string, js string) (string, error) {
109
+ t.Helper()
110
+ node, err := exec.LookPath("node")
111
+ if err != nil {
112
+ t.Skip("node executable not found")
113
+ return "", nil
114
+ }
115
+ runtimeDir := filepath.Join(project, "runtime")
116
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
117
+ t.Fatalf("mkdir runtime dir: %v", err)
118
+ }
119
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
120
+ for name, content := range map[string]string{
121
+ "input.cjs": ttscTypiaTestRewriteCommonJS(t, js),
122
+ "run.cjs": libReplacementNativeIdentityRuntimeRunner,
123
+ } {
124
+ if err := os.WriteFile(filepath.Join(runtimeDir, name), []byte(content), 0o644); err != nil {
125
+ t.Fatalf("write runtime file %s: %v", name, err)
126
+ }
127
+ }
128
+ cmd := exec.Command(node, filepath.Join(runtimeDir, "run.cjs"))
129
+ cmd.Dir = runtimeDir
130
+ output, err := cmd.CombinedOutput()
131
+ return string(output), err
132
+ }
133
+
134
+ const libReplacementNativeIdentityTSConfig = `{
135
+ "compilerOptions": {
136
+ "target": "ES2022",
137
+ "module": "commonjs",
138
+ "moduleResolution": "bundler",
139
+ "ignoreDeprecations": "6.0",
140
+ "lib": ["ES2022"],
141
+ "types": [],
142
+ "libReplacement": true,
143
+ "esModuleInterop": true,
144
+ "strict": true,
145
+ "skipLibCheck": true
146
+ },
147
+ "include": ["src"]
148
+ }
149
+ `
150
+
151
+ const libReplacementNativeIdentityPackageJSON = `{
152
+ "name": "@typescript/lib-es2015",
153
+ "version": "1.0.0"
154
+ }
155
+ `
156
+
157
+ // libReplacementNativeIdentityCollectionLib is the replacement TypeScript loads
158
+ // instead of its bundled `lib.es2015.collection.d.ts`. The collection
159
+ // declarations are transcribed from that file so the rest of the standard
160
+ // library still typechecks against them; `LibReplacementProbe` is the one
161
+ // addition, and it is what proves the program loaded this file.
162
+ const libReplacementNativeIdentityCollectionLib = `interface LibReplacementProbe {
163
+ libReplacementMarker: string;
164
+ }
165
+
166
+ interface Map<K, V> {
167
+ clear(): void;
168
+ delete(key: K): boolean;
169
+ forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
170
+ get(key: K): V | undefined;
171
+ has(key: K): boolean;
172
+ set(key: K, value: V): this;
173
+ readonly size: number;
174
+ }
175
+
176
+ interface MapConstructor {
177
+ new (): Map<any, any>;
178
+ new <K, V>(entries?: readonly (readonly [K, V])[] | null): Map<K, V>;
179
+ readonly prototype: Map<any, any>;
180
+ }
181
+ declare var Map: MapConstructor;
182
+
183
+ interface ReadonlyMap<K, V> {
184
+ forEach(callbackfn: (value: V, key: K, map: ReadonlyMap<K, V>) => void, thisArg?: any): void;
185
+ get(key: K): V | undefined;
186
+ has(key: K): boolean;
187
+ readonly size: number;
188
+ }
189
+
190
+ interface WeakMap<K extends WeakKey, V> {
191
+ delete(key: K): boolean;
192
+ get(key: K): V | undefined;
193
+ has(key: K): boolean;
194
+ set(key: K, value: V): this;
195
+ }
196
+
197
+ interface WeakMapConstructor {
198
+ new <K extends WeakKey = WeakKey, V = any>(entries?: readonly (readonly [K, V])[] | null): WeakMap<K, V>;
199
+ readonly prototype: WeakMap<WeakKey, any>;
200
+ }
201
+ declare var WeakMap: WeakMapConstructor;
202
+
203
+ interface Set<T> {
204
+ add(value: T): this;
205
+ clear(): void;
206
+ delete(value: T): boolean;
207
+ forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: any): void;
208
+ has(value: T): boolean;
209
+ readonly size: number;
210
+ }
211
+
212
+ interface SetConstructor {
213
+ new <T = any>(values?: readonly T[] | null): Set<T>;
214
+ readonly prototype: Set<any>;
215
+ }
216
+ declare var Set: SetConstructor;
217
+
218
+ interface ReadonlySet<T> {
219
+ forEach(callbackfn: (value: T, value2: T, set: ReadonlySet<T>) => void, thisArg?: any): void;
220
+ has(value: T): boolean;
221
+ readonly size: number;
222
+ }
223
+
224
+ interface WeakSet<T extends WeakKey> {
225
+ add(value: T): this;
226
+ delete(value: T): boolean;
227
+ has(value: T): boolean;
228
+ }
229
+
230
+ interface WeakSetConstructor {
231
+ new <T extends WeakKey = WeakKey>(values?: readonly T[] | null): WeakSet<T>;
232
+ readonly prototype: WeakSet<WeakKey>;
233
+ }
234
+ declare var WeakSet: WeakSetConstructor;
235
+ `
236
+
237
+ const libReplacementNativeIdentitySource = `import typia from "typia";
238
+
239
+ export const createdIsProbe = typia.createIs<LibReplacementProbe>();
240
+ export const createdIsMap = typia.createIs<Map<string, number>>();
241
+ export const createdIsSet = typia.createIs<Set<string>>();
242
+ export const createdIsWeakMap = typia.createIs<WeakMap<object, string>>();
243
+ export const createdIsWeakSet = typia.createIs<WeakSet<object>>();
244
+ export const createdIsDate = typia.createIs<Date>();
245
+ export const createdIsBytes = typia.createIs<Uint8Array>();
246
+ `
247
+
248
+ const libReplacementNativeIdentityRuntimeRunner = `const validators = require("./input.cjs");
249
+
250
+ let ran = 0;
251
+ const failures = [];
252
+ const eq = (name, actual, expected) => {
253
+ ran += 1;
254
+ if (actual !== expected) {
255
+ failures.push(name + ": expected " + expected + " but got " + actual);
256
+ }
257
+ };
258
+
259
+ eq("probe structural", validators.createdIsProbe({ libReplacementMarker: "x" }), true);
260
+ eq("Map real", validators.createdIsMap(new Map([["x", 1]])), true);
261
+ eq("Map plain", validators.createdIsMap({}), false);
262
+ eq("Set real", validators.createdIsSet(new Set(["x"])), true);
263
+ eq("Set plain", validators.createdIsSet({}), false);
264
+ eq("WeakMap real", validators.createdIsWeakMap(new WeakMap()), true);
265
+ eq("WeakMap plain", validators.createdIsWeakMap({}), false);
266
+ eq("WeakSet real", validators.createdIsWeakSet(new WeakSet()), true);
267
+ eq("WeakSet plain", validators.createdIsWeakSet({}), false);
268
+ eq("Date real", validators.createdIsDate(new Date()), true);
269
+ eq("Date plain", validators.createdIsDate({}), false);
270
+ eq("Uint8Array real", validators.createdIsBytes(new Uint8Array(1)), true);
271
+ eq("Uint8Array plain", validators.createdIsBytes({}), false);
272
+
273
+ console.log("RAN " + ran + " REPLACEMENT CASES");
274
+ if (failures.length !== 0) {
275
+ throw new Error("MISMATCHES:\n" + failures.join("\n"));
276
+ }
277
+ `
@@ -0,0 +1,185 @@
1
+ package main
2
+
3
+ import (
4
+ "encoding/json"
5
+ "os"
6
+ "path/filepath"
7
+ "strings"
8
+ "testing"
9
+ )
10
+
11
+ // TestLocalFunctionNamedLikeTypiaOperationTransform verifies the shadowed-typia
12
+ // diagnostic does not fire on a name collision (#2328).
13
+ //
14
+ // The diagnostic that reports a redeclared typia call keys off the called name,
15
+ // and those names are ordinary words: a project may well own its own
16
+ // `createAssert`, import one from an unrelated package, or augment typia with a
17
+ // name that only exists under one of its namespaces. Reporting any of them
18
+ // would break builds that are correct today, so the name alone must never be
19
+ // enough — the callee has to reach typia through typia's own module specifier
20
+ // and spell the operation in the namespace it lives in.
21
+ //
22
+ // 1. Build a project that defines a local `createAssert`, imports a `createIs`
23
+ // from a relative module and a `createValidate` from a package whose name
24
+ // merely begins with "typia", and augments typia with a root `parse` — an
25
+ // operation name that exists only under a namespace.
26
+ // 2. Require a clean no-emit build, which proves every decoy really resolves,
27
+ // and a project transform with no diagnostic.
28
+ // 3. Require the one genuine `typia.createIs` call in the same file to still
29
+ // be rewritten, so silence is not the transform giving up on the file.
30
+ func TestLocalFunctionNamedLikeTypiaOperationTransform(t *testing.T) {
31
+ project := localTypiaNameCollisionProject(t)
32
+
33
+ // A no-emit build reports semantic diagnostics as well as typia's own, so a
34
+ // decoy that silently stopped resolving fails here instead of turning the
35
+ // rest of this test into a tautology.
36
+ out, errText, code := ttscTypiaTestCapture(func() int {
37
+ return runBuild([]string{
38
+ "--cwd", project,
39
+ "--tsconfig", "tsconfig.json",
40
+ "--noEmit",
41
+ })
42
+ })
43
+ if code != 0 {
44
+ t.Fatalf("name collision fixture is not clean, got %d\nstdout=%s\nstderr=%s", code, out, errText)
45
+ }
46
+
47
+ out, errText, code = ttscTypiaTestCapture(func() int {
48
+ return runTransform([]string{
49
+ "--cwd", project,
50
+ "--tsconfig", "tsconfig.json",
51
+ })
52
+ })
53
+ if code != 0 {
54
+ t.Fatalf("name collisions must not fail the transform, got %d\nstdout=%s\nstderr=%s", code, out, errText)
55
+ }
56
+ var result transformProjectOutput
57
+ if err := json.Unmarshal([]byte(out), &result); err != nil {
58
+ t.Fatalf("decode transform output: %v\n%s", err, out)
59
+ }
60
+ if len(result.Diagnostics) != 0 {
61
+ t.Fatalf("name collisions produced diagnostics: %+v", result.Diagnostics)
62
+ }
63
+
64
+ js, errText, code := ttscTypiaTestCapture(func() int {
65
+ return runTransform([]string{
66
+ "--cwd", project,
67
+ "--tsconfig", "tsconfig.json",
68
+ "--file", "src/main.ts",
69
+ "--output", "js",
70
+ })
71
+ })
72
+ if code != 0 {
73
+ t.Fatalf("name collision fixture failed to emit: code=%d stderr=\n%s", code, errText)
74
+ }
75
+ // The genuine call becomes an inline validator; the decoys stay ordinary
76
+ // calls. Type arguments are erased either way, so the emitted body is the
77
+ // only evidence that the transform ran on one and not the others.
78
+ if !strings.Contains(js, `"number" === typeof`) {
79
+ t.Fatalf("the genuine typia call did not emit its validator:\n%s", js)
80
+ }
81
+ for _, decoy := range []string{"createAssert()", "createIs)()", "createValidate)()", "parse)(\"{}\")"} {
82
+ if !strings.Contains(js, decoy) {
83
+ t.Fatalf("decoy call %q was rewritten or lost:\n%s", decoy, js)
84
+ }
85
+ }
86
+ }
87
+
88
+ func localTypiaNameCollisionProject(t *testing.T) string {
89
+ t.Helper()
90
+ dir := t.TempDir()
91
+ src := filepath.Join(dir, "src")
92
+ if err := os.MkdirAll(src, 0o755); err != nil {
93
+ t.Fatalf("mkdir fixture src: %v", err)
94
+ }
95
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(transformDiagnosticTSConfig), 0o644); err != nil {
96
+ t.Fatalf("write tsconfig: %v", err)
97
+ }
98
+ ttscTypiaTestWriteFactoryStub(t, dir)
99
+ localTypiaNameCollisionWriteNeighborStub(t, dir)
100
+ for name, body := range map[string]string{
101
+ "helpers.ts": localTypiaNameCollisionHelpers,
102
+ "augmentation.ts": localTypiaNameCollisionAugmentation,
103
+ "main.ts": localTypiaNameCollisionSource,
104
+ } {
105
+ if err := os.WriteFile(filepath.Join(src, name), []byte(body), 0o644); err != nil {
106
+ t.Fatalf("write fixture %s: %v", name, err)
107
+ }
108
+ }
109
+ return dir
110
+ }
111
+
112
+ // localTypiaNameCollisionWriteNeighborStub installs a package whose name merely
113
+ // begins with "typia" and exports an operation name typia owns. It pins the
114
+ // one-past-boundary of the specifier test: the call reaches the specifier check
115
+ // under a name that matches, and only the specifier can reject it.
116
+ func localTypiaNameCollisionWriteNeighborStub(t *testing.T, project string) {
117
+ t.Helper()
118
+ root := filepath.Join(project, "node_modules", "typia-neighbor")
119
+ if err := os.MkdirAll(root, 0o755); err != nil {
120
+ t.Fatalf("mkdir typia-neighbor stub: %v", err)
121
+ }
122
+ files := map[string]string{
123
+ "package.json": `{
124
+ "name": "typia-neighbor",
125
+ "version": "0.0.0-test",
126
+ "main": "./index.js",
127
+ "types": "./index.d.ts",
128
+ "exports": {
129
+ ".": {
130
+ "types": "./index.d.ts",
131
+ "default": "./index.js"
132
+ }
133
+ }
134
+ }
135
+ `,
136
+ "index.d.ts": "export declare function createValidate<T>(): (input: unknown) => T;\n",
137
+ "index.js": "exports.createValidate = () => (input) => input;\n",
138
+ }
139
+ for name, body := range files {
140
+ if err := os.WriteFile(filepath.Join(root, name), []byte(body), 0o644); err != nil {
141
+ t.Fatalf("write typia-neighbor stub %s: %v", name, err)
142
+ }
143
+ }
144
+ }
145
+
146
+ const localTypiaNameCollisionHelpers = `export const createIs =
147
+ <T,>() =>
148
+ (input: unknown): input is T =>
149
+ input !== undefined;
150
+ `
151
+
152
+ // A module augmentation that adds a root-level `parse` to typia. The leading
153
+ // `import "typia"` makes this file a module, so the block merges with the
154
+ // installed typia instead of replacing it. `parse` is an operation name under
155
+ // the `llm` namespace and nowhere else, so a gate that matched a flat union of
156
+ // every namespace's names would report this call — a build that works today.
157
+ const localTypiaNameCollisionAugmentation = `import "typia";
158
+
159
+ declare module "typia" {
160
+ export function parse(text: string): unknown;
161
+ }
162
+ `
163
+
164
+ const localTypiaNameCollisionSource = `import { createValidate } from "typia-neighbor";
165
+ import { parse } from "typia";
166
+ import typia from "typia";
167
+
168
+ import "./augmentation";
169
+ import { createIs } from "./helpers";
170
+
171
+ export interface User {
172
+ id: number;
173
+ }
174
+
175
+ const createAssert =
176
+ <T,>() =>
177
+ (input: unknown): T =>
178
+ input as T;
179
+
180
+ export const localAssert = createAssert<User>();
181
+ export const relativeIs = createIs<User>();
182
+ export const neighborValidate = createValidate<User>();
183
+ export const augmented = parse("{}");
184
+ export const genuineIs = typia.createIs<User>();
185
+ `