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,293 @@
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "os"
6
+ "os/exec"
7
+ "path/filepath"
8
+ "strings"
9
+ "testing"
10
+ )
11
+
12
+ // TestPackageDeclarationNativeIdentityIsTransform pins runtime-native identity
13
+ // across ordinary package declarations and the genuine global controls (#2239).
14
+ //
15
+ // A declaration file is a normal published TypeScript package surface, so its
16
+ // source form cannot by itself establish that a Date/Map/Set/WeakMap symbol is
17
+ // the JavaScript native. The package types below are checker-equivalent to local
18
+ // structural controls and must keep their own members. Conversely, real global
19
+ // Date/Map/Set/WeakMap/WeakSet and Node-provided File/Blob types must retain
20
+ // their native checks.
21
+ //
22
+ // 1. Publish colliding structural declarations through a fixture package's
23
+ // index.d.ts and transform validators for them plus local controls.
24
+ // 2. Transform genuine global validators with DOM libraries excluded, making
25
+ // File and Blob come from the installed @types/node declaration package.
26
+ // 3. Inspect the emitted classification and execute all validators in Node,
27
+ // requiring an exact case count so an omitted branch cannot pass silently.
28
+ func TestPackageDeclarationNativeIdentityIsTransform(t *testing.T) {
29
+ project := packageDeclarationNativeIdentityProject(t)
30
+ transform := func(file string) string {
31
+ t.Helper()
32
+ out, errText, code := ttscTypiaTestCapture(func() int {
33
+ return runTransform([]string{
34
+ "--cwd", project,
35
+ "--tsconfig", "tsconfig.json",
36
+ "--file", file,
37
+ "--output", "js",
38
+ })
39
+ })
40
+ if code != 0 {
41
+ t.Fatalf("package declaration native identity transform %s failed: code=%d stderr=\n%s", file, code, errText)
42
+ }
43
+ return out
44
+ }
45
+
46
+ packageJS := transform("src/package.ts")
47
+ nativeJS := transform("src/native.ts")
48
+ failures := []string{}
49
+ for _, member := range []string{"stamp", "brandMap", "brandSet", "brandWeakMap"} {
50
+ if !strings.Contains(packageJS, member) {
51
+ failures = append(failures, fmt.Sprintf("package declaration member %q was dropped", member))
52
+ }
53
+ }
54
+ for _, gone := range []string{"instanceof Date", "instanceof Map", "instanceof Set", "instanceof WeakMap"} {
55
+ if strings.Contains(packageJS, gone) {
56
+ failures = append(failures, fmt.Sprintf("package declaration collision kept %q", gone))
57
+ }
58
+ }
59
+ for _, kept := range []string{
60
+ "instanceof Date",
61
+ "instanceof Map",
62
+ "instanceof Set",
63
+ "instanceof WeakMap",
64
+ "instanceof WeakSet",
65
+ "instanceof File",
66
+ "instanceof Blob",
67
+ } {
68
+ if !strings.Contains(nativeJS, kept) {
69
+ failures = append(failures, fmt.Sprintf("genuine native path %q was dropped", kept))
70
+ }
71
+ }
72
+ output, runtimeErr := packageDeclarationNativeIdentityRun(t, project, packageJS, nativeJS)
73
+ if runtimeErr != nil {
74
+ failures = append(failures, fmt.Sprintf("runtime matrix failed: %v\n%s", runtimeErr, output))
75
+ }
76
+ const expected = "RAN 30 CASES"
77
+ if !strings.Contains(output, expected) {
78
+ failures = append(failures, fmt.Sprintf("runtime runner did not report %q; got:\n%s", expected, output))
79
+ }
80
+ if len(failures) != 0 {
81
+ t.Fatalf("package declaration native identity mismatches:\n%s\n\npackage emit:\n%s\n\nnative emit:\n%s", strings.Join(failures, "\n"), packageJS, nativeJS)
82
+ }
83
+ }
84
+
85
+ func packageDeclarationNativeIdentityProject(t *testing.T) string {
86
+ t.Helper()
87
+ root := ttscTypiaTestRepoRoot(t)
88
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
89
+ if err := os.MkdirAll(base, 0o755); err != nil {
90
+ t.Fatalf("mkdir temp base: %v", err)
91
+ }
92
+ dir, err := os.MkdirTemp(base, "package-declaration-native-identity-")
93
+ if err != nil {
94
+ t.Fatalf("create temp fixture: %v", err)
95
+ }
96
+ t.Cleanup(func() {
97
+ _ = os.RemoveAll(dir)
98
+ })
99
+
100
+ src := filepath.Join(dir, "src")
101
+ dependency := filepath.Join(dir, "node_modules", "native-name-package")
102
+ for _, path := range []string{src, dependency} {
103
+ if err := os.MkdirAll(path, 0o755); err != nil {
104
+ t.Fatalf("mkdir fixture path %s: %v", path, err)
105
+ }
106
+ }
107
+ files := map[string]string{
108
+ filepath.Join(dir, "tsconfig.json"): packageDeclarationNativeIdentityTSConfig,
109
+ filepath.Join(dependency, "package.json"): packageDeclarationNativeIdentityPackageJSON,
110
+ filepath.Join(dependency, "index.d.ts"): packageDeclarationNativeIdentityDeclarations,
111
+ filepath.Join(src, "package.ts"): packageDeclarationNativeIdentitySource,
112
+ filepath.Join(src, "native.ts"): packageDeclarationNativeIdentityNativeSource,
113
+ }
114
+ for path, content := range files {
115
+ if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
116
+ t.Fatalf("write fixture file %s: %v", path, err)
117
+ }
118
+ }
119
+ return dir
120
+ }
121
+
122
+ func packageDeclarationNativeIdentityRun(t *testing.T, project string, packageJS string, nativeJS string) (string, error) {
123
+ t.Helper()
124
+ node, err := exec.LookPath("node")
125
+ if err != nil {
126
+ t.Skip("node executable not found")
127
+ return "", nil
128
+ }
129
+ runtimeDir := filepath.Join(project, "runtime")
130
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
131
+ t.Fatalf("mkdir runtime dir: %v", err)
132
+ }
133
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
134
+ modules := map[string]string{
135
+ "package.cjs": ttscTypiaTestRewriteCommonJS(t, packageJS),
136
+ "native.cjs": ttscTypiaTestRewriteCommonJS(t, nativeJS),
137
+ "run.cjs": packageDeclarationNativeIdentityRuntimeRunner,
138
+ }
139
+ for name, content := range modules {
140
+ if err := os.WriteFile(filepath.Join(runtimeDir, name), []byte(content), 0o644); err != nil {
141
+ t.Fatalf("write runtime file %s: %v", name, err)
142
+ }
143
+ }
144
+ cmd := exec.Command(node, filepath.Join(runtimeDir, "run.cjs"))
145
+ cmd.Dir = runtimeDir
146
+ output, err := cmd.CombinedOutput()
147
+ return string(output), err
148
+ }
149
+
150
+ const packageDeclarationNativeIdentityTSConfig = `{
151
+ "compilerOptions": {
152
+ "target": "ES2022",
153
+ "module": "commonjs",
154
+ "moduleResolution": "bundler",
155
+ "ignoreDeprecations": "6.0",
156
+ "lib": ["ES2022"],
157
+ "types": ["node"],
158
+ "esModuleInterop": true,
159
+ "strict": true,
160
+ "skipLibCheck": true
161
+ },
162
+ "include": ["src"]
163
+ }
164
+ `
165
+
166
+ const packageDeclarationNativeIdentityPackageJSON = `{
167
+ "name": "native-name-package",
168
+ "version": "1.0.0",
169
+ "types": "index.d.ts"
170
+ }
171
+ `
172
+
173
+ const packageDeclarationNativeIdentityDeclarations = `export interface Date {
174
+ stamp: number;
175
+ }
176
+ export interface Map<K, V> {
177
+ brandMap: K;
178
+ valueMap: V;
179
+ }
180
+ export interface Set<T> {
181
+ brandSet: T;
182
+ }
183
+ export interface WeakMap<K extends object, V> {
184
+ brandWeakMap: K;
185
+ valueWeakMap: V;
186
+ }
187
+ `
188
+
189
+ const packageDeclarationNativeIdentitySource = `import typia from "typia";
190
+ import type {
191
+ Date as PackageDate,
192
+ Map as PackageMap,
193
+ Set as PackageSet,
194
+ WeakMap as PackageWeakMap,
195
+ } from "native-name-package";
196
+
197
+ interface LocalDate {
198
+ stamp: number;
199
+ }
200
+ interface LocalMap<K, V> {
201
+ brandMap: K;
202
+ valueMap: V;
203
+ }
204
+ interface LocalSet<T> {
205
+ brandSet: T;
206
+ }
207
+ interface LocalWeakMap<K extends object, V> {
208
+ brandWeakMap: K;
209
+ valueWeakMap: V;
210
+ }
211
+
212
+ type Assert<T extends true> = T;
213
+ type Same<X, Y> = [X] extends [Y]
214
+ ? [Y] extends [X]
215
+ ? true
216
+ : false
217
+ : false;
218
+ type _PackageDateIsLocal = Assert<Same<PackageDate, LocalDate>>;
219
+ type _PackageMapIsLocal = Assert<Same<PackageMap<string, number>, LocalMap<string, number>>>;
220
+ type _PackageSetIsLocal = Assert<Same<PackageSet<string>, LocalSet<string>>>;
221
+ type _PackageWeakMapIsLocal = Assert<Same<PackageWeakMap<object, string>, LocalWeakMap<object, string>>>;
222
+
223
+ export const isPackageDate = typia.createIs<PackageDate>();
224
+ export const isPackageMap = typia.createIs<PackageMap<string, number>>();
225
+ export const isPackageSet = typia.createIs<PackageSet<string>>();
226
+ export const isPackageWeakMap = typia.createIs<PackageWeakMap<object, string>>();
227
+ export const isLocalDate = typia.createIs<LocalDate>();
228
+ export const isLocalMap = typia.createIs<LocalMap<string, number>>();
229
+ export const isLocalSet = typia.createIs<LocalSet<string>>();
230
+ export const isLocalWeakMap = typia.createIs<LocalWeakMap<object, string>>();
231
+ `
232
+
233
+ const packageDeclarationNativeIdentityNativeSource = `import typia from "typia";
234
+
235
+ export const isNativeDate = typia.createIs<Date>();
236
+ export const isNativeMap = typia.createIs<Map<string, number>>();
237
+ export const isNativeSet = typia.createIs<Set<string>>();
238
+ export const isNativeWeakMap = typia.createIs<WeakMap<object, string>>();
239
+ export const isNativeWeakSet = typia.createIs<WeakSet<object>>();
240
+ export const isNativeFile = typia.createIs<File>();
241
+ export const isNativeBlob = typia.createIs<Blob>();
242
+ `
243
+
244
+ const packageDeclarationNativeIdentityRuntimeRunner = `const packageTypes = require("./package.cjs");
245
+ const natives = require("./native.cjs");
246
+
247
+ let ran = 0;
248
+ const failures = [];
249
+ const eq = (name, actual, expected) => {
250
+ ran += 1;
251
+ if (actual !== expected) {
252
+ failures.push(name + ": expected " + expected + " but got " + actual);
253
+ }
254
+ };
255
+
256
+ eq("package Date valid", packageTypes.isPackageDate({ stamp: 1 }), true);
257
+ eq("package Date invalid", packageTypes.isPackageDate({}), false);
258
+ eq("package Date rejects native", packageTypes.isPackageDate(new Date()), false);
259
+ eq("package Map valid", packageTypes.isPackageMap({ brandMap: "x", valueMap: 1 }), true);
260
+ eq("package Map invalid", packageTypes.isPackageMap({ brandMap: "x" }), false);
261
+ eq("package Map rejects native", packageTypes.isPackageMap(new Map([["x", 1]])), false);
262
+ eq("package Set valid", packageTypes.isPackageSet({ brandSet: "x" }), true);
263
+ eq("package Set invalid", packageTypes.isPackageSet({}), false);
264
+ eq("package Set rejects native", packageTypes.isPackageSet(new Set(["x"])), false);
265
+ eq("package WeakMap valid", packageTypes.isPackageWeakMap({ brandWeakMap: {}, valueWeakMap: "x" }), true);
266
+ eq("package WeakMap invalid", packageTypes.isPackageWeakMap({ brandWeakMap: {} }), false);
267
+ eq("package WeakMap rejects native", packageTypes.isPackageWeakMap(new WeakMap()), false);
268
+
269
+ eq("local Date control", packageTypes.isLocalDate({ stamp: 1 }), true);
270
+ eq("local Map control", packageTypes.isLocalMap({ brandMap: "x", valueMap: 1 }), true);
271
+ eq("local Set control", packageTypes.isLocalSet({ brandSet: "x" }), true);
272
+ eq("local WeakMap control", packageTypes.isLocalWeakMap({ brandWeakMap: {}, valueWeakMap: "x" }), true);
273
+
274
+ eq("native Date real", natives.isNativeDate(new Date()), true);
275
+ eq("native Date plain", natives.isNativeDate({}), false);
276
+ eq("native Map real", natives.isNativeMap(new Map([["x", 1]])), true);
277
+ eq("native Map plain", natives.isNativeMap({}), false);
278
+ eq("native Set real", natives.isNativeSet(new Set(["x"])), true);
279
+ eq("native Set plain", natives.isNativeSet({}), false);
280
+ eq("native WeakMap real", natives.isNativeWeakMap(new WeakMap()), true);
281
+ eq("native WeakMap plain", natives.isNativeWeakMap({}), false);
282
+ eq("native WeakSet real", natives.isNativeWeakSet(new WeakSet()), true);
283
+ eq("native WeakSet plain", natives.isNativeWeakSet({}), false);
284
+ eq("Node File real", natives.isNativeFile(new File(["x"], "x.txt")), true);
285
+ eq("Node File plain", natives.isNativeFile({ name: "x.txt", size: 1 }), false);
286
+ eq("Node Blob real", natives.isNativeBlob(new Blob(["x"])), true);
287
+ eq("Node Blob plain", natives.isNativeBlob({ size: 1, type: "text/plain" }), false);
288
+
289
+ console.log("RAN " + ran + " CASES");
290
+ if (failures.length !== 0) {
291
+ throw new Error("MISMATCHES:\n" + failures.join("\n"));
292
+ }
293
+ `
@@ -0,0 +1,167 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "path/filepath"
6
+ "regexp"
7
+ "sort"
8
+ "strings"
9
+ "testing"
10
+ )
11
+
12
+ // TestProtobufDiagnosticCodeTransform verifies that a rejected protobuf call
13
+ // site is named by its own API in the diagnostic code (#2285).
14
+ //
15
+ // `ProtobufFactory.Metadata` used to compose the code as `"typia.protobuf." +
16
+ // props.Method`, while the encode and decode programmers pass the whole call
17
+ // accessor (`ModuloMethodText`, the same text `TypeGuardError.method` carries).
18
+ // Sixteen of the seventeen entry points therefore reported
19
+ // `TS(typia.protobuf.typia.protobuf.encode)`; only `protobuf.message` was
20
+ // correct, because its programmer passed a bare literal. The code is the only
21
+ // machine-readable identity a typia rejection has, so a code that names no API
22
+ // is a silent loss for anyone searching it.
23
+ //
24
+ // The oracle is the fixture source, not another copy of the expected string: a
25
+ // diagnostic code is correct only when the accessor it names is literally the
26
+ // accessor written at a call site in that file. A concatenation defect cannot
27
+ // satisfy that, and neither can a misspelling.
28
+ //
29
+ // 1. Write one fixture that calls every protobuf entry point with `bigint`,
30
+ // which none of them supports.
31
+ // 2. Transform it and collect every diagnostic code the transform reported.
32
+ // 3. Require each code to be an accessor present in the fixture, and require
33
+ // every entry point to have been named.
34
+ func TestProtobufDiagnosticCodeTransform(t *testing.T) {
35
+ methods := []string{
36
+ "message",
37
+ "encode",
38
+ "decode",
39
+ "assertEncode",
40
+ "assertDecode",
41
+ "isEncode",
42
+ "isDecode",
43
+ "validateEncode",
44
+ "validateDecode",
45
+ "createEncode",
46
+ "createDecode",
47
+ "createAssertEncode",
48
+ "createAssertDecode",
49
+ "createIsEncode",
50
+ "createIsDecode",
51
+ "createValidateEncode",
52
+ "createValidateDecode",
53
+ }
54
+ project, source := protobufDiagnosticCodeProject(t, methods)
55
+ out, errText, code := ttscTypiaTestCapture(func() int {
56
+ return runTransform([]string{
57
+ "--cwd", project,
58
+ "--tsconfig", "tsconfig.json",
59
+ })
60
+ })
61
+ if code == 0 {
62
+ t.Fatalf("protobuf fixture transformed successfully, want failure:\nstdout=%s\nstderr=%s", out, errText)
63
+ }
64
+
65
+ codes := map[string]bool{}
66
+ for _, match := range protobufDiagnosticCodePattern.FindAllStringSubmatch(out, -1) {
67
+ codes[match[1]] = true
68
+ }
69
+ if len(codes) == 0 {
70
+ t.Fatalf("no typia diagnostic code was reported:\nstdout=%s\nstderr=%s", out, errText)
71
+ }
72
+
73
+ unnamed := []string{}
74
+ for reported := range codes {
75
+ if !strings.Contains(source, reported+"<") {
76
+ unnamed = append(unnamed, reported)
77
+ }
78
+ }
79
+ sort.Strings(unnamed)
80
+ if len(unnamed) != 0 {
81
+ t.Fatalf(
82
+ "diagnostic code(s) name no call site in the fixture: %s",
83
+ strings.Join(unnamed, ", "),
84
+ )
85
+ }
86
+
87
+ missing := []string{}
88
+ for _, method := range methods {
89
+ if !codes["typia.protobuf."+method] {
90
+ missing = append(missing, method)
91
+ }
92
+ }
93
+ if len(missing) != 0 {
94
+ t.Fatalf(
95
+ "no diagnostic named these entry points: %s\nstdout=%s",
96
+ strings.Join(missing, ", "),
97
+ out,
98
+ )
99
+ }
100
+ }
101
+
102
+ // The command reports diagnostics as JSON, and `code` is the field ttsc renders
103
+ // as `error TS(<code>)`; reading it here keeps the assertion on the value the
104
+ // transform produced rather than on one renderer's formatting.
105
+ var protobufDiagnosticCodePattern = regexp.MustCompile(`"code":"([^"]+)"`)
106
+
107
+ func protobufDiagnosticCodeProject(t *testing.T, methods []string) (string, string) {
108
+ t.Helper()
109
+ root := ttscTypiaTestRepoRoot(t)
110
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
111
+ if err := os.MkdirAll(base, 0o755); err != nil {
112
+ t.Fatalf("mkdir temp base: %v", err)
113
+ }
114
+ dir, err := os.MkdirTemp(base, "protobuf-code-")
115
+ if err != nil {
116
+ t.Fatalf("create temp fixture: %v", err)
117
+ }
118
+ t.Cleanup(func() {
119
+ _ = os.RemoveAll(dir)
120
+ })
121
+ src := filepath.Join(dir, "src")
122
+ if err := os.MkdirAll(src, 0o755); err != nil {
123
+ t.Fatalf("mkdir fixture src: %v", err)
124
+ }
125
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(protobufDiagnosticCodeTSConfig), 0o644); err != nil {
126
+ t.Fatalf("write tsconfig: %v", err)
127
+ }
128
+ lines := []string{`import typia from "typia";`, ""}
129
+ for _, method := range methods {
130
+ lines = append(lines, protobufDiagnosticCodeCall(method))
131
+ }
132
+ source := strings.Join(lines, "\n") + "\n"
133
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(source), 0o644); err != nil {
134
+ t.Fatalf("write source: %v", err)
135
+ }
136
+ return dir, source
137
+ }
138
+
139
+ // protobufDiagnosticCodeCall writes the call form each entry point takes: the
140
+ // factories take no value argument, the encoders take the message, and the
141
+ // decoders take the buffer.
142
+ func protobufDiagnosticCodeCall(method string) string {
143
+ call := "typia.protobuf." + method + "<bigint>"
144
+ switch {
145
+ case method == "message" || strings.HasPrefix(method, "create"):
146
+ return call + "();"
147
+ case strings.HasSuffix(method, "Decode"):
148
+ return call + "(new Uint8Array());"
149
+ default:
150
+ return call + "(1n as any);"
151
+ }
152
+ }
153
+
154
+ const protobufDiagnosticCodeTSConfig = `{
155
+ "compilerOptions": {
156
+ "target": "ES2022",
157
+ "module": "commonjs",
158
+ "moduleResolution": "bundler",
159
+ "ignoreDeprecations": "6.0",
160
+ "types": ["*"],
161
+ "esModuleInterop": true,
162
+ "strict": true,
163
+ "skipLibCheck": true
164
+ },
165
+ "include": ["src"]
166
+ }
167
+ `