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,44 @@
1
+ package iterate
2
+
3
+ import (
4
+ "slices"
5
+ "testing"
6
+
7
+ nativemetadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
8
+ )
9
+
10
+ // TestJsonSchemaPatternPropertyOrderPreservesFirstPosition verifies repeated patterns keep one ordered slot.
11
+ //
12
+ // The legacy TypeScript producer stored pairs in a plain object: assigning an
13
+ // existing pattern replaced its value without moving or duplicating its first
14
+ // insertion position. The Go order record must preserve that overwrite contract.
15
+ //
16
+ // 1. Insert two patterns, then replace the first pattern with new metadata and schema values.
17
+ // 2. Assert the ordered keys remain unique and the map retains the replacement pair.
18
+ func TestJsonSchemaPatternPropertyOrderPreservesFirstPosition(t *testing.T) {
19
+ first := &nativemetadata.MetadataSchema{}
20
+ replacement := &nativemetadata.MetadataSchema{}
21
+ extra := json_schema_superfluous{
22
+ patternProperties: map[string]json_schema_metadata_schema_pair{},
23
+ }
24
+ extra.setPatternProperty("first", json_schema_metadata_schema_pair{
25
+ metadata: first,
26
+ schema: JsonSchema{"type": "string"},
27
+ })
28
+ extra.setPatternProperty("second", json_schema_metadata_schema_pair{
29
+ metadata: &nativemetadata.MetadataSchema{},
30
+ schema: JsonSchema{"type": "boolean"},
31
+ })
32
+ extra.setPatternProperty("first", json_schema_metadata_schema_pair{
33
+ metadata: replacement,
34
+ schema: JsonSchema{"type": "number"},
35
+ })
36
+
37
+ if slices.Equal(extra.patternPropertyKeys, []string{"first", "second"}) == false {
38
+ t.Fatalf("pattern property order was %v", extra.patternPropertyKeys)
39
+ }
40
+ pair := extra.patternProperties["first"]
41
+ if pair.metadata != replacement || pair.schema["type"] != "number" {
42
+ t.Fatalf("replacement pair was not retained: %#v", pair)
43
+ }
44
+ }
@@ -454,7 +454,40 @@ func openApiV3Downgrader_omit_examples(schema JsonSchema) JsonSchema {
454
454
  }
455
455
  output[key] = value
456
456
  }
457
- return output
457
+ return openApiV3Downgrader_exclusive_bounds(output)
458
+ }
459
+
460
+ // openApiV3Downgrader_exclusive_bounds rewrites an exclusive numeric bound into
461
+ // the form the 3.0 dialect defines.
462
+ //
463
+ // 3.0's Schema Object descends from JSON Schema draft-04, where
464
+ // `exclusiveMinimum` and `exclusiveMaximum` are booleans qualifying `minimum`
465
+ // and `maximum`; the numeric spelling belongs to 3.1. Carrying the number
466
+ // through left a document that declares itself 3.0 with a 3.1 keyword, and a
467
+ // 3.0 reader taking the value as the boolean its dialect declares finds no
468
+ // `minimum` beside it and drops the bound entirely (#2300).
469
+ //
470
+ // The upgrader already performs the inverse — a boolean `exclusiveMinimum: true`
471
+ // becomes the numeric bound and the redundant `minimum` is dropped — so this
472
+ // makes the pair a round trip.
473
+ func openApiV3Downgrader_exclusive_bounds(schema JsonSchema) JsonSchema {
474
+ for _, pair := range [][2]string{
475
+ {"exclusiveMinimum", "minimum"},
476
+ {"exclusiveMaximum", "maximum"},
477
+ } {
478
+ value, ok := schema[pair[0]]
479
+ if ok == false {
480
+ continue
481
+ }
482
+ if _, boolean := value.(bool); boolean {
483
+ continue
484
+ }
485
+ if openApiV3Downgrader_is_nil(value) == false {
486
+ schema[pair[1]] = value
487
+ schema[pair[0]] = true
488
+ }
489
+ }
490
+ return schema
458
491
  }
459
492
 
460
493
  // openApiV3Downgrader_shallow_clone copies a schema's own keys, leaving nested
@@ -25,6 +25,17 @@ type templateCapture struct {
25
25
  Atomic *nativemetadata.MetadataAtomic
26
26
  }
27
27
 
28
+ // TemplateRuntimePattern returns the structural regular-expression pattern the
29
+ // runtime template checker uses for one template-literal row.
30
+ //
31
+ // Consumers that only need template membership can share the checker's exact
32
+ // pattern without duplicating its lowering. Runtime tag conditions remain owned
33
+ // by Check_template because they require the checker context and capture map.
34
+ func TemplateRuntimePattern(row []*nativemetadata.MetadataSchema) string {
35
+ pattern, _ := template_runtime_pattern(row)
36
+ return pattern
37
+ }
38
+
28
39
  // template_runtime_pattern builds the structural regex of a template literal for
29
40
  // the runtime checker and, alongside it, the capture map of every constrained
30
41
  // interpolation placeholder.
@@ -278,7 +278,34 @@ func jsonStringifyProgrammer_decode(props struct {
278
278
  Value: func() *shimast.Node {
279
279
  next := props
280
280
  next.Metadata = metadata
281
- return jsonStringifyProgrammer_decode_to_json(next)
281
+ resolved := jsonStringifyProgrammer_decode_to_json(next)
282
+ if isDate {
283
+ return resolved
284
+ }
285
+ // The arm's own test is `typeof input.toJSON === "function"`, but an arm
286
+ // test is not always emitted — a sole arm needs no choice, and a final
287
+ // arm is the else — while this value *calls* `toJSON`. Leaving the call
288
+ // to be guarded by the arm meant a value whose `toJSON` is not callable
289
+ // threw `input.toJSON is not a function` from inside the serializer,
290
+ // including under `isStringify` and `validateStringify`, whose contract
291
+ // is to answer rather than throw (samchon/typia#2271).
292
+ //
293
+ // The guard therefore belongs to the call. `JSON.stringify` ignores a
294
+ // non-callable `toJSON` and serializes the object itself, and the
295
+ // metadata already carries that shape, so the fallback describes the
296
+ // original rather than inventing an answer. `Date` keeps the plain form:
297
+ // its arm is `instanceof Date`, and a real Date's `toJSON` is callable.
298
+ original := props
299
+ original.Metadata = props.Metadata.Escaped.Original
300
+ return nativefactories.ExpressionFactory.Conditional(
301
+ nativeprogrammers.IsProgrammer.Decode_to_json(struct {
302
+ Input *shimast.Expression
303
+ CheckNull bool
304
+ }{Input: props.Input, CheckNull: false}),
305
+ resolved,
306
+ jsonStringifyProgrammer_decode(original),
307
+ props.Context.Emit,
308
+ )
282
309
  },
283
310
  })
284
311
  } else if len(props.Metadata.Functions) != 0 {
@@ -697,9 +724,10 @@ func jsonStringifyProgrammer_decode_array_inline(props jsonStringifyProgrammer_d
697
724
  Arrow *shimast.Node
698
725
  }) *shimast.Node {
699
726
  return nativehelpers.StringifyJoiner.Array(nativehelpers.StringifyJoiner_ArrayProps{
700
- Input: next.Input,
701
- Arrow: next.Arrow,
702
- Emit: props.Context.Emit,
727
+ Context: props.Context,
728
+ Input: next.Input,
729
+ Arrow: next.Arrow,
730
+ Emit: props.Context.Emit,
703
731
  })
704
732
  },
705
733
  Array: props.Array,
@@ -772,7 +800,7 @@ func jsonStringifyProgrammer_decode_tuple_inline(props jsonStringifyProgrammer_d
772
800
  } else {
773
801
  explore.Postfix = fmt.Sprintf("\"[%d]\"", index)
774
802
  }
775
- elements = append(elements, jsonStringifyProgrammer_decode(struct {
803
+ code := jsonStringifyProgrammer_decode(struct {
776
804
  Context nativecontext.ITypiaContext
777
805
  Config nativeinternal.FeatureProgrammer_IConfig
778
806
  Functor *nativehelpers.FunctionProgrammer
@@ -788,7 +816,20 @@ func jsonStringifyProgrammer_decode_tuple_inline(props jsonStringifyProgrammer_d
788
816
  Metadata: elem,
789
817
  Explore: explore,
790
818
  Validated: props.Validated,
791
- }))
819
+ })
820
+ if nativehelpers.StringifyJoiner_ResultUndefinable(elem) {
821
+ // A tuple slot holds its position, so an element that serializes to
822
+ // nothing is `null` rather than omitted; without this its text was the
823
+ // literal `undefined` (#2253).
824
+ code = f.NewCallExpression(
825
+ jsonStringifyProgrammer_internal(props.Context, "jsonStringifyElement"),
826
+ nil,
827
+ nil,
828
+ f.NewNodeList([]*shimast.Node{code}),
829
+ shimast.NodeFlagsNone,
830
+ )
831
+ }
832
+ elements = append(elements, code)
792
833
  }
793
834
  var rest *shimast.Node
794
835
  if len(props.Tuple.Elements) != 0 {
@@ -240,7 +240,15 @@ func (llmApplicationProgrammerNamespace) WriteApplication(props struct {
240
240
  functions = append(functions, written)
241
241
  }
242
242
  }
243
- result := map[string]any{"functions": functions}
243
+ // The call site's schema configuration is resolved here and nowhere else, so
244
+ // it travels with the emitted application; the runtime finalizer only adds
245
+ // the validate hook to it. Rebuilding it at runtime reported `strict: false`
246
+ // for a strict build (issue #2293).
247
+ strict, _ := props.Config["strict"].(bool)
248
+ result := map[string]any{
249
+ "config": map[string]any{"strict": strict},
250
+ "functions": functions,
251
+ }
244
252
  if len(metadata.Objects) != 0 {
245
253
  if object := metadata.Objects[0].Type; object != nil {
246
254
  if description := llmApplicationProgrammer_describe(object.Description, object.JsDocTags); description != nil && len(*description) != 0 {
@@ -35,7 +35,7 @@ func (protobufMessageProgrammerNamespace) Write(props ProtobufMessageProgrammer_
35
35
  f := nativecontext.EmitFactoryOf(protobufMessageProgrammer_factory, props.Context.Emit)
36
36
  collection := schemametadata.NewMetadataCollection()
37
37
  nativefactories.ProtobufFactory.Metadata(nativefactories.ProtobufFactory_IProps{
38
- Method: "message",
38
+ Method: "typia.protobuf.message",
39
39
  Checker: props.Context.Checker,
40
40
  Components: collection,
41
41
  Type: props.Type,
@@ -784,15 +784,6 @@ func metadataCollection_isOpenApiNameRune(ch rune) bool {
784
784
  ch == '_'
785
785
  }
786
786
 
787
- func MetadataCollection_escape(str string) string {
788
- for _, pair := range metadataCollection_replacers {
789
- if pair.After != "" {
790
- str = strings.ReplaceAll(str, pair.After, pair.Before)
791
- }
792
- }
793
- return str
794
- }
795
-
796
787
  type metadataCollection_replacer struct {
797
788
  Before string
798
789
  After string
@@ -819,11 +810,31 @@ var metadataCollection_replacers = []metadataCollection_replacer{
819
810
  }
820
811
 
821
812
  func metadataCollection_getFullName(checker *nativechecker.Checker, typ *nativechecker.Type) string {
813
+ return metadataCollection_getFullNameOf(checker, typ, nil)
814
+ }
815
+
816
+ // metadataCollection_getFullNameOf carries the types whose name is still being
817
+ // composed on the current path. A recursive type graph reaches the same *Type
818
+ // again before its name is finished: `type Rec<T> = T extends Date ? string : T
819
+ // extends (infer U)[] ? Rec<U>[] : never` instantiated at `Date | Node[]`
820
+ // resolves to the union `string | Rec<Node>[]`, whose array member is a
821
+ // reference whose sole type argument is that very union. Walking union member ->
822
+ // array reference -> type argument returns to the union, so the unguarded walk
823
+ // never terminates and overflows the plugin's stack instead of naming the type
824
+ // (#2331). A type reached a second time on one path is therefore named by its
825
+ // own symbol with its arguments left unexpanded -- the recursion's placeholder,
826
+ // `Array<string | Array>` for the example above -- and a symbol-less one by the
827
+ // anonymous marker the collection already allocates unique names from. Expanding
828
+ // the checker's elided rendering there instead would name every such component
829
+ // after a several-hundred-character structural dump.
830
+ func metadataCollection_getFullNameOf(
831
+ checker *nativechecker.Checker,
832
+ typ *nativechecker.Type,
833
+ visiting map[*nativechecker.Type]bool,
834
+ ) string {
822
835
  if checker == nil || typ == nil {
823
836
  return "__type"
824
837
  }
825
- rendered := metadataCollection_sanitizeName(checker.TypeToString(typ))
826
-
827
838
  // Mirror TypeFactory.getFullName: prefer the alias symbol, then the type's
828
839
  // own symbol. getTypeNameSymbol already returns t.alias.symbol first (the
829
840
  // alias symbol), so a non-nil result that differs from typ.Symbol() means the
@@ -835,6 +846,13 @@ func metadataCollection_getFullName(checker *nativechecker.Checker, typ *nativec
835
846
  if symbol == nil {
836
847
  symbol = rawSymbol
837
848
  }
849
+ if visiting[typ] {
850
+ if symbol != nil {
851
+ return metadataCollection_getName(symbol)
852
+ }
853
+ return "__type"
854
+ }
855
+ rendered := metadataCollection_sanitizeName(checker.TypeToString(typ))
838
856
  if symbol == nil {
839
857
  if typ.IsUnion() || typ.IsIntersection() {
840
858
  joiner := " | "
@@ -843,9 +861,11 @@ func metadataCollection_getFullName(checker *nativechecker.Checker, typ *nativec
843
861
  }
844
862
  children := typ.Types()
845
863
  names := make([]string, 0, len(children))
864
+ visiting = metadataCollection_markVisiting(visiting, typ)
846
865
  for _, child := range children {
847
- names = append(names, metadataCollection_getFullName(checker, child))
866
+ names = append(names, metadataCollection_getFullNameOf(checker, child, visiting))
848
867
  }
868
+ delete(visiting, typ)
849
869
  return strings.Join(names, joiner)
850
870
  }
851
871
  if rendered != "" {
@@ -873,16 +893,29 @@ func metadataCollection_getFullName(checker *nativechecker.Checker, typ *nativec
873
893
  }
874
894
  return name
875
895
  }
896
+ visiting = metadataCollection_markVisiting(visiting, typ)
897
+ defer delete(visiting, typ)
876
898
  if name == "Promise" {
877
- return metadataCollection_getFullName(checker, generic[0])
899
+ return metadataCollection_getFullNameOf(checker, generic[0], visiting)
878
900
  }
879
901
  names := make([]string, 0, len(generic))
880
902
  for _, child := range generic {
881
- names = append(names, metadataCollection_getFullName(checker, child))
903
+ names = append(names, metadataCollection_getFullNameOf(checker, child, visiting))
882
904
  }
883
905
  return name + "<" + strings.Join(names, ", ") + ">"
884
906
  }
885
907
 
908
+ func metadataCollection_markVisiting(
909
+ visiting map[*nativechecker.Type]bool,
910
+ typ *nativechecker.Type,
911
+ ) map[*nativechecker.Type]bool {
912
+ if visiting == nil {
913
+ visiting = map[*nativechecker.Type]bool{}
914
+ }
915
+ visiting[typ] = true
916
+ return visiting
917
+ }
918
+
886
919
  func metadataCollection_getName(symbol *nativeast.Symbol) string {
887
920
  if symbol == nil || len(symbol.Declarations) == 0 || symbol.Declarations[0].Parent == nil {
888
921
  return "__type"
@@ -0,0 +1,81 @@
1
+ package metadata
2
+
3
+ import (
4
+ "strings"
5
+ "sync"
6
+
7
+ nativeast "github.com/microsoft/typescript-go/shim/ast"
8
+ nativechecker "github.com/microsoft/typescript-go/shim/checker"
9
+ )
10
+
11
+ // MetadataDefaultLibrary routes the compiler's own default-library
12
+ // classification to metadata analysis, which decides runtime-native identity
13
+ // from it: a global is the JavaScript built-in only when a runtime authority —
14
+ // a TypeScript default library, or Node's `buffer` core module — declares it
15
+ // (#2200).
16
+ //
17
+ // Only the program knows which files those are. `bundled:///libs/lib.es2022.d.ts`
18
+ // under the embedded default, an on-disk path under `noembed`, and
19
+ // `node_modules/@typescript/lib-es2022/index.d.ts` under `libReplacement` are
20
+ // all the same authority, and none of them is recognizable from the file name:
21
+ // the last one does not even start with `lib.`, while `lib.d.ts` is an ordinary
22
+ // published file name that any dependency or `typeRoots` package may use
23
+ // (samchon/typia#2108 recorded the same lesson for dependency reporting).
24
+ //
25
+ // The registry is keyed by checker for the same reason MetadataDependency is:
26
+ // analysis code deep inside the metadata iterators holds the checker but no
27
+ // transform context, while one transform host drives one program at a time. A
28
+ // sync.Map keeps unrelated programs in the same process (tests) isolated.
29
+ //
30
+ // When no classifier is registered the file name is the only evidence left, so
31
+ // the fallback is the historical `lib.*.d.ts` base-name test. That keeps a host
32
+ // that never registers on exactly the behavior this package had before the
33
+ // registry existed rather than silently classifying every real native as a
34
+ // user declaration.
35
+ var metadataDefaultLibrary_classifiers sync.Map
36
+
37
+ // MetadataDefaultLibrary_register records the program-level classifier for
38
+ // `checker`. Register it once per loaded program, before any transform runs.
39
+ func MetadataDefaultLibrary_register(checker *nativechecker.Checker, classifier func(*nativeast.SourceFile) bool) {
40
+ if checker == nil || classifier == nil {
41
+ return
42
+ }
43
+ metadataDefaultLibrary_classifiers.Store(checker, classifier)
44
+ }
45
+
46
+ // MetadataDefaultLibrary_release removes the classifier registered for
47
+ // `checker`.
48
+ func MetadataDefaultLibrary_release(checker *nativechecker.Checker) {
49
+ if checker == nil {
50
+ return
51
+ }
52
+ metadataDefaultLibrary_classifiers.Delete(checker)
53
+ }
54
+
55
+ // MetadataDefaultLibrary_is reports whether `source` is one of the program's
56
+ // default library files.
57
+ func MetadataDefaultLibrary_is(checker *nativechecker.Checker, source *nativeast.SourceFile) bool {
58
+ if source == nil {
59
+ return false
60
+ }
61
+ if checker != nil {
62
+ if stored, ok := metadataDefaultLibrary_classifiers.Load(checker); ok {
63
+ if classifier, ok := stored.(func(*nativeast.SourceFile) bool); ok {
64
+ return classifier(source)
65
+ }
66
+ }
67
+ }
68
+ return MetadataDefaultLibrary_isFileNamed(source.FileName())
69
+ }
70
+
71
+ // MetadataDefaultLibrary_isFileNamed is the registry's file-name fallback,
72
+ // exported so the one predicate that still answers without a checker keeps
73
+ // using the same rule.
74
+ func MetadataDefaultLibrary_isFileNamed(fileName string) bool {
75
+ slash := strings.ReplaceAll(fileName, "\\", "/")
76
+ base := slash
77
+ if index := strings.LastIndex(slash, "/"); index >= 0 {
78
+ base = slash[index+1:]
79
+ }
80
+ return strings.HasPrefix(base, "lib.") && strings.HasSuffix(base, ".d.ts")
81
+ }
@@ -13,25 +13,25 @@ type IMetadataSchema_IObjectType struct {
13
13
  }
14
14
 
15
15
  type MetadataObjectType struct {
16
- Name string
17
- DisplayName string
16
+ Name string
17
+ DisplayName string
18
18
  // Source is the absolute-or-as-declared path of the file declaring a named
19
19
  // class, captured at analysis time so plain.classify can value-import a
20
20
  // cross-module class it reconstructs (Object.create / new / from). nil for
21
21
  // anonymous/literal shapes and types with no locatable declaration. Read
22
22
  // in-process by the classify programmer; not serialized (classify is
23
23
  // single-pass), and ignored by clone/prune.
24
- Source *string
24
+ Source *string
25
25
  // SourceDefault is true when the class is the default export of Source, so a
26
26
  // cross-module classify value-import uses a default (not named) import.
27
- SourceDefault bool
27
+ SourceDefault bool
28
28
  // PrivateFields is true when the named class declaration carries at least one
29
29
  // ES `#private` member (a member named with a PrivateIdentifier). Such slots
30
30
  // are installed only by running the constructor; plain.classify's field-copy
31
31
  // (Object.create + assign) cannot restore them, so classify rejects any such
32
32
  // class at a field-copied position. Read in-process by the classify
33
33
  // programmer; ignored by clone/prune, not serialized.
34
- PrivateFields bool
34
+ PrivateFields bool
35
35
  // IsClass is true when this object's declaration is a `class` (declaration or
36
36
  // expression), so it has a runtime VALUE binding plain.classify can
37
37
  // `Object.create(<name>.prototype)`/`new` against. False for an interface, a
@@ -39,7 +39,7 @@ type MetadataObjectType struct {
39
39
  // value, so classify field-copies a plain {} instead of referencing a
40
40
  // type-only name. Read in-process by the classify programmer; ignored by
41
41
  // clone/prune, not serialized.
42
- IsClass bool
42
+ IsClass bool
43
43
  // ValueRef overrides the runtime VALUE-binding name plain.classify uses when
44
44
  // the class's metadata Name is not a usable runtime constructor reference —
45
45
  // namely a NAMED class EXPRESSION (`const X = class Beast {...}`), whose Name
@@ -56,7 +56,7 @@ type MetadataObjectType struct {
56
56
  Validated bool
57
57
  Recursive bool
58
58
  Nullables []bool
59
- Parent_objects_ []*MetadataObject
59
+ Parent_objects_ []*MetadataObject
60
60
  Check_properties_ []*MetadataProperty
61
61
  Tagged_ bool
62
62
  literal_ *bool
@@ -205,17 +205,6 @@ func (obj *MetadataObjectType) ToJSON() IMetadataSchema_IObjectType {
205
205
  }
206
206
  }
207
207
 
208
- func MetadataObjectType_intersects(x *MetadataObjectType, y *MetadataObjectType) bool {
209
- for _, prop := range x.Properties {
210
- for _, oppo := range y.Properties {
211
- if prop.Key.GetName() == oppo.Key.GetName() {
212
- return true
213
- }
214
- }
215
- }
216
- return false
217
- }
218
-
219
208
  func MetadataObjectType_covers(x *MetadataObjectType, y *MetadataObjectType) bool {
220
209
  if len(x.Properties) < len(y.Properties) {
221
210
  return false
package/native/go.mod CHANGED
@@ -5,10 +5,10 @@ go 1.26
5
5
  // Build-time floor: the driver reference-graph SDK
6
6
  // (driver.NewTransformGraph / driver.TransformGraph / driver.TransformOutputKey)
7
7
  // this plugin consumes exists only in ttsc >= 0.19.2. That floor is enforced
8
- // through typia's package.json peerDependencies (ttsc / @ttsc/unplugin), not
9
- // here: ttsc builds this plugin from source on the user's machine and its
10
- // buildSourcePlugin generates `replace github.com/samchon/ttsc/packages/ttsc
11
- // v0.0.0 => <installed ttsc root>`, so the require below must stay v0.0.0 or the
8
+ // through typia's package.json `ttsc` peerDependency, not here: ttsc builds
9
+ // this plugin from source on the user's machine and its buildSourcePlugin
10
+ // generates `replace github.com/samchon/ttsc/packages/ttsc v0.0.0 =>
11
+ // <installed ttsc root>`, so the require below must stay v0.0.0 or the
12
12
  // generated replace no longer matches and the plugin build fails to resolve.
13
13
  require (
14
14
  github.com/microsoft/typescript-go/shim/ast v0.0.0
@@ -63,6 +63,7 @@ func (callExpressionTransformerNamespace) Transform(props CallExpressionTransfor
63
63
  location, _ := filepath.Abs(sourceFile.FileName())
64
64
  module, ok := callExpressionTransformer_targetModule(location)
65
65
  if ok == false {
66
+ callExpressionTransformer_rejectShadowedTypia(props, location)
66
67
  return props.Expression.AsNode()
67
68
  }
68
69
  typ := props.Context.Checker.GetTypeAtLocation(declaration)
@@ -127,6 +128,172 @@ func callExpressionTransformer_targetModule(location string) (string, bool) {
127
128
  return "", false
128
129
  }
129
130
 
131
+ // callExpressionTransformer_rejectShadowedTypia raises a diagnostic when a call
132
+ // the file-path identity test rejected is nevertheless a typia call the author
133
+ // expects to be transformed, and names the file that declared it instead.
134
+ //
135
+ // Attribution by declaration file is deliberate: accepting a callee declared
136
+ // anywhere else would let any package claim typia's transform, which is the
137
+ // boundary default_library_spoof_native_identity_transform_test.go and
138
+ // lib_replacement_native_identity_transform_test.go protect. That check is not
139
+ // relaxed here. Silence is what needs correcting. A project-local `declare
140
+ // module "typia"` moves the resolved signature's declaration out of typia's own
141
+ // files, so the call is left untransformed with no diagnostic at all and the
142
+ // failure surfaces only at run time as `no transform has been configured`
143
+ // (samchon/typia#2328).
144
+ //
145
+ // Three conditions have to hold together, so an unrelated local function that
146
+ // happens to share a name with a typia operation cannot trip this:
147
+ //
148
+ // 1. the callee spells an operation this transformer owns, in the namespace it
149
+ // actually lives in — `typia.json.assertParse`, never `typia.assertParse`;
150
+ // 2. the root of the callee expression resolves to an import binding; and
151
+ // 3. that import's module specifier is typia's own.
152
+ //
153
+ // Known gap: an alias chain is not followed, so a project that re-exports typia
154
+ // through its own barrel and then shadows it is still silent. The specifier of
155
+ // the import the call actually reads is the only evidence this collects.
156
+ func callExpressionTransformer_rejectShadowedTypia(props CallExpressionTransformer_TransformProps, location string) {
157
+ code, ok := callExpressionTransformer_calleeOperation(props.Expression.Expression)
158
+ if ok == false {
159
+ return
160
+ }
161
+ root := callExpressionTransformer_calleeRoot(props.Expression.Expression)
162
+ if root == nil || root.Kind != shimast.KindIdentifier {
163
+ return
164
+ }
165
+ symbol := props.Context.Checker.GetSymbolAtLocation(root)
166
+ if symbol == nil || symbol.Flags&shimast.SymbolFlagsAlias == 0 {
167
+ return
168
+ }
169
+ for _, declaration := range symbol.Declarations {
170
+ if callExpressionTransformer_importsTypia(declaration) == false {
171
+ continue
172
+ }
173
+ // State only what was observed. The declaration file is the fact; a
174
+ // `declare module "typia"` is the usual cause but not the only way to move
175
+ // a declaration, and naming it as the cause would misdirect anyone whose
176
+ // build got here another way.
177
+ panic(nativecontext.NewTransformerError(nativecontext.TransformerError_IProps{
178
+ Code: code,
179
+ Message: "this call was declared in " +
180
+ filepath.ToSlash(location) +
181
+ ", not in typia's own module, so no transform was applied. A project-local `declare module \"typia\"` is the usual cause; remove it, or give the redeclaration another module name.",
182
+ }))
183
+ }
184
+ }
185
+
186
+ // callExpressionTransformer_calleeOperation answers whether a callee expression
187
+ // spells one of this transformer's operations, and returns the diagnostic code
188
+ // for it — the written spelling, qualified as `typia.json.assertParse`.
189
+ //
190
+ // The namespace is part of the spelling. `typia.json.assertParse` names the
191
+ // `json` table, while `typia.createAssert` and a bare named import name the root
192
+ // `module` table; a root-level `typia.assertParse` matches nothing, because that
193
+ // operation does not live there. Matching a flat union of every table's names
194
+ // instead would report a module augmentation that adds an unrelated `parse` or
195
+ // `schema` to typia, which is a build that works today.
196
+ //
197
+ // Known gap: taking the namespace from the spelling means a renamed binding
198
+ // (`import { json as j } from "typia"; j.assertParse(...)`) is not recognized.
199
+ func callExpressionTransformer_calleeOperation(callee *shimast.Node) (string, bool) {
200
+ method := ""
201
+ first := true
202
+ // Segments to the left of the method, nearest first: `typia.json.assertParse`
203
+ // collects ["json", "typia"].
204
+ parts := []string{}
205
+ for current := callee; current != nil; {
206
+ if len(parts) > 2 {
207
+ return "", false
208
+ }
209
+ segment := ""
210
+ switch current.Kind {
211
+ case shimast.KindPropertyAccessExpression:
212
+ access := current.AsPropertyAccessExpression()
213
+ name := access.Name()
214
+ if name == nil || name.Kind != shimast.KindIdentifier {
215
+ return "", false
216
+ }
217
+ segment = name.Text()
218
+ current = access.Expression
219
+ case shimast.KindIdentifier:
220
+ segment = current.Text()
221
+ current = nil
222
+ default:
223
+ return "", false
224
+ }
225
+ if first {
226
+ method = segment
227
+ first = false
228
+ } else {
229
+ parts = append(parts, segment)
230
+ }
231
+ }
232
+ if method == "" || len(parts) > 2 {
233
+ return "", false
234
+ }
235
+ functors := callExpressionTransformer_FUNCTORS()
236
+ // `typia.json.assertParse` and `json.assertParse` both name the `json` table
237
+ // through the segment directly left of the method.
238
+ if len(parts) != 0 {
239
+ if _, found := functors[parts[0]][method]; found {
240
+ return "typia." + parts[0] + "." + method, true
241
+ }
242
+ }
243
+ // `typia.createAssert` and a bare `createAssert` name the root table. The
244
+ // qualifier, when present, is the imported binding rather than a namespace.
245
+ if len(parts) <= 1 {
246
+ if _, found := functors["module"][method]; found {
247
+ return "typia." + method, true
248
+ }
249
+ }
250
+ return "", false
251
+ }
252
+
253
+ // callExpressionTransformer_calleeRoot walks a property-access chain down to the
254
+ // expression it starts from, which is the binding that has to come from typia.
255
+ func callExpressionTransformer_calleeRoot(callee *shimast.Node) *shimast.Node {
256
+ current := callee
257
+ for current != nil && current.Kind == shimast.KindPropertyAccessExpression {
258
+ current = current.AsPropertyAccessExpression().Expression
259
+ }
260
+ return current
261
+ }
262
+
263
+ // callExpressionTransformer_importsTypia answers whether an alias declaration
264
+ // belongs to an import whose module specifier is typia's own. Both `import ...
265
+ // from "typia"` and `import typia = require("typia")` are matched; the walk
266
+ // stops at the source file so a local declaration can never reach an unrelated
267
+ // import above it.
268
+ func callExpressionTransformer_importsTypia(declaration *shimast.Node) bool {
269
+ for node := declaration; node != nil; node = node.Parent {
270
+ switch node.Kind {
271
+ case shimast.KindImportDeclaration:
272
+ return callExpressionTransformer_isTypiaSpecifier(node.ModuleSpecifier())
273
+ case shimast.KindImportEqualsDeclaration:
274
+ reference := node.AsImportEqualsDeclaration().ModuleReference
275
+ if reference == nil || reference.Kind != shimast.KindExternalModuleReference {
276
+ return false
277
+ }
278
+ return callExpressionTransformer_isTypiaSpecifier(reference.AsExternalModuleReference().Expression)
279
+ case shimast.KindSourceFile:
280
+ return false
281
+ }
282
+ }
283
+ return false
284
+ }
285
+
286
+ // callExpressionTransformer_isTypiaSpecifier accepts typia's own package name
287
+ // and its subpaths, and nothing that merely begins with those letters: a
288
+ // `typia-codegen` package is a different package.
289
+ func callExpressionTransformer_isTypiaSpecifier(specifier *shimast.Node) bool {
290
+ if specifier == nil || specifier.Kind != shimast.KindStringLiteral {
291
+ return false
292
+ }
293
+ text := specifier.AsStringLiteral().Text
294
+ return text == "typia" || strings.HasPrefix(text, "typia/")
295
+ }
296
+
130
297
  func callExpressionTransformer_sourceFile(node *shimast.Node) *shimast.SourceFile {
131
298
  for current := node; current != nil; current = current.Parent {
132
299
  if current.Kind == shimast.KindSourceFile {