typia 13.0.1 → 13.0.2
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.
|
@@ -14,7 +14,7 @@ type ImportProgrammer struct {
|
|
|
14
14
|
options_ ImportProgrammer_IOptions
|
|
15
15
|
// emit_ switches import emission to AST-integration mode. When set, imports
|
|
16
16
|
// become namespace imports created by emit_.Factory, and every reference is a
|
|
17
|
-
// member access on
|
|
17
|
+
// member access on a cloned unique name so tsgo's module transform owns the
|
|
18
18
|
// CommonJS aliasing. Nil keeps the legacy text-emission path with named,
|
|
19
19
|
// default, namespace imports and bare identifier references.
|
|
20
20
|
emit_ *shimprinter.EmitContext
|
|
@@ -51,6 +51,7 @@ type ImportProgrammer_TypeProps struct {
|
|
|
51
51
|
type importProgrammer_asset struct {
|
|
52
52
|
file string
|
|
53
53
|
modSpec *shimast.Node
|
|
54
|
+
binding *shimast.Node
|
|
54
55
|
Default *ImportProgrammer_IDefault
|
|
55
56
|
namespace *ImportProgrammer_INamespace
|
|
56
57
|
instances map[string]ImportProgrammer_IInstance
|
|
@@ -80,8 +81,7 @@ func (p *ImportProgrammer) SetEmitContext(ec *shimprinter.EmitContext) {
|
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
// moduleSpecifier returns the asset's module-specifier string literal, allocated
|
|
83
|
-
// once and reused
|
|
84
|
-
// alias prints identically in the import declaration and every reference.
|
|
84
|
+
// once and reused by the namespace import declaration.
|
|
85
85
|
func (p *ImportProgrammer) moduleSpecifier(asset *importProgrammer_asset) *shimast.Node {
|
|
86
86
|
if asset.modSpec == nil {
|
|
87
87
|
asset.modSpec = p.emit_.Factory.NewStringLiteral(asset.file, shimast.TokenFlagsNone)
|
|
@@ -89,11 +89,20 @@ func (p *ImportProgrammer) moduleSpecifier(asset *importProgrammer_asset) *shima
|
|
|
89
89
|
return asset.modSpec
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
// namespaceName returns a clone of the asset's unique generated identifier.
|
|
93
|
+
// Clones preserve the generated-name id while keeping distinct AST parents.
|
|
94
|
+
func (p *ImportProgrammer) namespaceName(asset *importProgrammer_asset) *shimast.Node {
|
|
95
|
+
if asset.binding == nil {
|
|
96
|
+
asset.binding = p.emit_.Factory.NewUniqueName(importProgrammer_moduleIdentifier(asset.file))
|
|
97
|
+
}
|
|
98
|
+
return asset.binding.Clone(p.emit_.Factory)
|
|
99
|
+
}
|
|
100
|
+
|
|
92
101
|
// member builds `<namespace>.<name>` for the file, where <namespace> is the
|
|
93
102
|
// generated name tsgo's module-transform binds to `require(file)`.
|
|
94
103
|
func (p *ImportProgrammer) member(asset *importProgrammer_asset, name string) *shimast.Node {
|
|
95
104
|
return p.emit_.Factory.NewPropertyAccessExpression(
|
|
96
|
-
p.
|
|
105
|
+
p.namespaceName(asset),
|
|
97
106
|
nil,
|
|
98
107
|
p.emit_.Factory.NewIdentifier(name),
|
|
99
108
|
shimast.NodeFlagsNone,
|
|
@@ -137,7 +146,7 @@ func (p *ImportProgrammer) Namespace(props ImportProgrammer_INamespace) *shimast
|
|
|
137
146
|
asset.namespace = ©
|
|
138
147
|
}
|
|
139
148
|
if p.emit_ != nil {
|
|
140
|
-
return p.
|
|
149
|
+
return p.namespaceName(asset)
|
|
141
150
|
}
|
|
142
151
|
return EmitFactory(p.emit_, importProgrammer_factory).NewIdentifier(asset.namespace.Name)
|
|
143
152
|
}
|
|
@@ -222,7 +231,7 @@ func (p *ImportProgrammer) ToStatements() []*shimast.Node {
|
|
|
222
231
|
p.emit_.Factory.NewImportClause(
|
|
223
232
|
0,
|
|
224
233
|
nil,
|
|
225
|
-
p.emit_.Factory.NewNamespaceImport(p.
|
|
234
|
+
p.emit_.Factory.NewNamespaceImport(p.namespaceName(asset)),
|
|
226
235
|
),
|
|
227
236
|
modSpec,
|
|
228
237
|
nil,
|
|
@@ -334,6 +343,31 @@ func importProgrammer_fileRank(file string) int {
|
|
|
334
343
|
return 500
|
|
335
344
|
}
|
|
336
345
|
|
|
346
|
+
func importProgrammer_moduleIdentifier(file string) string {
|
|
347
|
+
if index := strings.LastIndexAny(file, "/\\"); index != -1 {
|
|
348
|
+
file = file[index+1:]
|
|
349
|
+
}
|
|
350
|
+
if file == "" {
|
|
351
|
+
return "module"
|
|
352
|
+
}
|
|
353
|
+
var builder strings.Builder
|
|
354
|
+
for i := 0; i < len(file); i++ {
|
|
355
|
+
ch := file[i]
|
|
356
|
+
if i == 0 && '0' <= ch && ch <= '9' {
|
|
357
|
+
builder.WriteByte('_')
|
|
358
|
+
}
|
|
359
|
+
if ('a' <= ch && ch <= 'z') ||
|
|
360
|
+
('A' <= ch && ch <= 'Z') ||
|
|
361
|
+
('0' <= ch && ch <= '9') ||
|
|
362
|
+
ch == '_' {
|
|
363
|
+
builder.WriteByte(ch)
|
|
364
|
+
} else {
|
|
365
|
+
builder.WriteByte('_')
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return builder.String()
|
|
369
|
+
}
|
|
370
|
+
|
|
337
371
|
func (p *ImportProgrammer) take(file string) *importProgrammer_asset {
|
|
338
372
|
if asset, ok := p.assets_[file]; ok {
|
|
339
373
|
return asset
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//go:build typia_native_internal
|
|
2
|
+
// +build typia_native_internal
|
|
3
|
+
|
|
4
|
+
package context
|
|
5
|
+
|
|
6
|
+
import "testing"
|
|
7
|
+
|
|
8
|
+
// TestImportProgrammerModuleIdentifier verifies module names become valid bases.
|
|
9
|
+
//
|
|
10
|
+
// Unique generated names still need a readable JavaScript identifier base.
|
|
11
|
+
// Scoped packages, punctuation, leading digits, and Windows-style separators
|
|
12
|
+
// must not reintroduce invalid namespace import bindings.
|
|
13
|
+
//
|
|
14
|
+
// 1. Convert representative internal, scoped, numeric, and empty module names.
|
|
15
|
+
// 2. Assert each result matches the identifier base used by the printer.
|
|
16
|
+
func TestImportProgrammerModuleIdentifier(t *testing.T) {
|
|
17
|
+
cases := map[string]string{
|
|
18
|
+
"typia/lib/internal/_randomNumber": "_randomNumber",
|
|
19
|
+
"@scope/package-name": "package_name",
|
|
20
|
+
"123-module": "_123_module",
|
|
21
|
+
`scope\windows-name`: "windows_name",
|
|
22
|
+
"": "module",
|
|
23
|
+
}
|
|
24
|
+
for input, expected := range cases {
|
|
25
|
+
if actual := importProgrammer_moduleIdentifier(input); actual != expected {
|
|
26
|
+
t.Fatalf("identifier mismatch for %q: expected %q, got %q", input, expected, actual)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typia",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.2",
|
|
4
4
|
"description": "Superfast runtime validators with only one line",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"inquirer": "^8.2.5",
|
|
51
51
|
"randexp": "^0.5.3",
|
|
52
52
|
"tinyglobby": "^0.2.12",
|
|
53
|
-
"@typia/
|
|
54
|
-
"@typia/
|
|
53
|
+
"@typia/interface": "^13.0.2",
|
|
54
|
+
"@typia/utils": "^13.0.2"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/inquirer": "^8.2.5",
|