typia 13.3.0 → 14.0.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.
- package/lib/internal/_randomPattern.js +20 -3
- package/lib/internal/_randomPattern.js.map +1 -1
- package/lib/internal/_randomPattern.mjs +5 -1
- package/lib/internal/_randomPattern.mjs.map +1 -1
- package/lib/internal/_randomStringLength.js +9 -2
- package/lib/internal/_randomStringLength.js.map +1 -1
- package/lib/internal/_randomStringLength.mjs +3 -1
- package/lib/internal/_randomStringLength.mjs.map +1 -1
- package/lib/transform.mjs +1 -1
- package/native/cmd/ttsc-typia/dynamic_key_tags_transform_test.go +206 -0
- package/native/cmd/ttsc-typia/notation_kebab_case_transform_test.go +2 -2
- package/native/cmd/ttsc-typia/project_catalog_transform_coverage_test.go +84 -85
- package/native/cmd/ttsc-typia/template_literal_type_tags_transform_test.go +3 -1
- package/native/cmd/ttsc-typia/transform.go +2 -2
- package/native/cmd/ttsc-typia/transform_helpers_test.go +12 -0
- package/native/core/factories/MetadataCommentTagFactory.go +96 -27
- package/native/core/factories/metadata_comment_tag_factory_coverage_test.go +2 -2
- package/native/core/factories/metadata_comment_tag_factory_rejects_out_of_range_integer_test.go +124 -0
- package/native/core/programmers/AssertProgrammer.go +20 -6
- package/native/core/programmers/RandomProgrammer.go +78 -6
- package/native/core/programmers/ValidateProgrammer.go +21 -6
- package/native/core/programmers/helpers/RandomJoiner.go +8 -1
- package/native/core/programmers/iterate/check_dynamic_properties.go +177 -3
- package/native/core/programmers/iterate/check_object.go +12 -1
- package/package.json +3 -12
- package/src/internal/_randomPattern.ts +18 -3
- package/src/internal/_randomStringLength.ts +9 -2
- package/lib/executable/FileSystemIdentity.d.ts +0 -44
- package/lib/executable/FileSystemIdentity.js +0 -213
- package/lib/executable/FileSystemIdentity.js.map +0 -1
- package/lib/executable/FileSystemIdentity.mjs +0 -133
- package/lib/executable/FileSystemIdentity.mjs.map +0 -1
- package/lib/executable/TypiaGenerateWizard.d.ts +0 -9
- package/lib/executable/TypiaGenerateWizard.js +0 -852
- package/lib/executable/TypiaGenerateWizard.js.map +0 -1
- package/lib/executable/TypiaGenerateWizard.mjs +0 -618
- package/lib/executable/TypiaGenerateWizard.mjs.map +0 -1
- package/lib/executable/generate/ttsc.d.ts +0 -1
- package/lib/executable/generate/ttsc.js +0 -53
- package/lib/executable/generate/ttsc.js.map +0 -1
- package/lib/executable/generate/ttsc.mjs +0 -37
- package/lib/executable/generate/ttsc.mjs.map +0 -1
- package/lib/executable/typia.d.ts +0 -2
- package/lib/executable/typia.js +0 -84
- package/lib/executable/typia.js.map +0 -1
- package/lib/executable/typia.mjs +0 -60
- package/lib/executable/typia.mjs.map +0 -1
- package/src/executable/FileSystemIdentity.ts +0 -222
- package/src/executable/TypiaGenerateWizard.ts +0 -1133
- package/src/executable/generate/ttsc.ts +0 -70
- package/src/executable/typia.ts +0 -80
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
package iterate
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
+
"strings"
|
|
5
|
+
|
|
4
6
|
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
5
7
|
shimprinter "github.com/microsoft/typescript-go/shim/printer"
|
|
6
8
|
nativecontext "github.com/samchon/typia/packages/typia/native/core/context"
|
|
7
9
|
nativefactories "github.com/samchon/typia/packages/typia/native/core/factories"
|
|
8
10
|
nativehelpers "github.com/samchon/typia/packages/typia/native/core/programmers/helpers"
|
|
11
|
+
nativemetadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
|
|
9
12
|
)
|
|
10
13
|
|
|
11
14
|
type Check_dynamic_propertiesProps struct {
|
|
@@ -126,7 +129,11 @@ func check_dynamic_property(props Check_dynamic_propertiesProps) *shimast.Node {
|
|
|
126
129
|
nil,
|
|
127
130
|
))
|
|
128
131
|
}
|
|
129
|
-
|
|
132
|
+
// terminated marks that `statements` already ends in an unconditional return,
|
|
133
|
+
// so nothing after it could run. A signature that accepts every key sets it
|
|
134
|
+
// from the loop; a declared key type that covers every key sets it from the
|
|
135
|
+
// tail below.
|
|
136
|
+
terminated := false
|
|
130
137
|
|
|
131
138
|
if len(props.Regular) != 0 {
|
|
132
139
|
add(is_regular_property(props.Regular, props.Context.Emit), props.Config.Positive)
|
|
@@ -156,13 +163,58 @@ func check_dynamic_property(props Check_dynamic_propertiesProps) *shimast.Node {
|
|
|
156
163
|
})
|
|
157
164
|
if condition.Kind == shimast.KindTrueKeyword {
|
|
158
165
|
statements = append(statements, f.NewReturnStatement(entry.Expression))
|
|
159
|
-
|
|
166
|
+
terminated = true
|
|
160
167
|
break
|
|
161
168
|
}
|
|
162
169
|
add(condition, entry.Expression)
|
|
163
170
|
}
|
|
164
171
|
|
|
165
|
-
if !
|
|
172
|
+
if !terminated {
|
|
173
|
+
// Reaching here means the key satisfied no dynamic signature. Two different
|
|
174
|
+
// things bring a key here, and they are not the same failure.
|
|
175
|
+
//
|
|
176
|
+
// A key whose *declared type* no signature covers -- `wrong` against
|
|
177
|
+
// `[key: `prefix_${string}`]` -- is an extra property. Nothing declares it,
|
|
178
|
+
// so `is` accepts it as it accepts any surplus property, and `equals`
|
|
179
|
+
// reports it through `Superfluous`.
|
|
180
|
+
//
|
|
181
|
+
// A key the declaration does cover but whose *type tag* it breaks -- `ab`
|
|
182
|
+
// against `[key: string & tags.MinLength<3>]` -- is a declared property
|
|
183
|
+
// with an invalid key. It used to reach the same accepting tail, which made
|
|
184
|
+
// every key tag inert: `[key: string & tags.Format<"uuid">]` accepted any
|
|
185
|
+
// key at all, while the emitted check sat right above, used only to decide
|
|
186
|
+
// *which* signature's value type to apply (#2347).
|
|
187
|
+
//
|
|
188
|
+
// So the tag failure is separated out first, by re-asking the same key
|
|
189
|
+
// question with every type tag removed. What is left is exactly the
|
|
190
|
+
// declared key type, and a key that answers it is a member of the object
|
|
191
|
+
// whose key broke a constraint -- never a surplus property.
|
|
192
|
+
shape := check_dynamic_properties_key_shape(props, key)
|
|
193
|
+
if shape != nil {
|
|
194
|
+
var invalid *shimast.Node
|
|
195
|
+
if props.Config.InvalidKey != nil {
|
|
196
|
+
invalid = props.Config.InvalidKey(
|
|
197
|
+
value,
|
|
198
|
+
check_dynamic_properties_key_expected(props.Dynamic),
|
|
199
|
+
check_dynamic_properties_invalid_key_description(props.Context.Emit),
|
|
200
|
+
)
|
|
201
|
+
} else {
|
|
202
|
+
// A programmer with no better report reduces both to the same answer,
|
|
203
|
+
// as `is` does with `false`.
|
|
204
|
+
invalid = props.Config.Superfluous(value, check_dynamic_properties_superfluous_description(props.Context.Emit))
|
|
205
|
+
}
|
|
206
|
+
if shape.Kind == shimast.KindTrueKeyword {
|
|
207
|
+
// Every key the signature accepts is covered -- a string index
|
|
208
|
+
// signature covers every key `Object.keys` can yield -- so the surplus
|
|
209
|
+
// tail below is unreachable and is not emitted.
|
|
210
|
+
statements = append(statements, f.NewReturnStatement(invalid))
|
|
211
|
+
terminated = true
|
|
212
|
+
} else {
|
|
213
|
+
add(shape, invalid)
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if !terminated {
|
|
166
218
|
output := props.Config.Positive
|
|
167
219
|
if props.Config.Equals {
|
|
168
220
|
output = props.Config.Superfluous(value, check_dynamic_properties_superfluous_description(props.Context.Emit))
|
|
@@ -257,6 +309,128 @@ func check_dynamic_properties_internal(context nativecontext.ITypiaContext, name
|
|
|
257
309
|
return f.NewIdentifier(name)
|
|
258
310
|
}
|
|
259
311
|
|
|
312
|
+
// The condition that the key belongs to some index signature's declared key
|
|
313
|
+
// type while breaking that signature's type tags -- the question the tail has
|
|
314
|
+
// to answer to tell an invalid key from a surplus property.
|
|
315
|
+
//
|
|
316
|
+
// It is the same `Check_dynamic_key` question asked of every signature with its
|
|
317
|
+
// type tags removed, joined with `||`. The tail runs only after each full
|
|
318
|
+
// condition returned false, so a signature whose declared type still answers
|
|
319
|
+
// yes is one whose tags are what the key broke.
|
|
320
|
+
//
|
|
321
|
+
// Nil when no signature carries a key tag. Then each stripped condition equals
|
|
322
|
+
// the full one the tail already refuted, so the check could never fire, and an
|
|
323
|
+
// object with untagged index signatures emits exactly what it emitted before.
|
|
324
|
+
func check_dynamic_properties_key_shape(props Check_dynamic_propertiesProps, key *shimast.Expression) *shimast.Node {
|
|
325
|
+
tagged := false
|
|
326
|
+
for _, entry := range props.Dynamic {
|
|
327
|
+
if check_dynamic_properties_key_tagged(entry.Key) {
|
|
328
|
+
tagged = true
|
|
329
|
+
break
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if !tagged {
|
|
333
|
+
return nil
|
|
334
|
+
}
|
|
335
|
+
conditions := make([]*shimast.Node, 0, len(props.Dynamic))
|
|
336
|
+
for _, entry := range props.Dynamic {
|
|
337
|
+
condition := Check_dynamic_key(Check_dynamic_keyProps{
|
|
338
|
+
Context: props.Context,
|
|
339
|
+
Metadata: check_dynamic_properties_key_untagged(entry.Key),
|
|
340
|
+
Input: key,
|
|
341
|
+
})
|
|
342
|
+
if condition.Kind == shimast.KindTrueKeyword {
|
|
343
|
+
return condition
|
|
344
|
+
}
|
|
345
|
+
conditions = append(conditions, condition)
|
|
346
|
+
}
|
|
347
|
+
return check_dynamic_key_reduce(conditions, shimast.KindBarBarToken, props.Context.Emit)
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Whether the key declaration constrains more than its own type, which is what
|
|
351
|
+
// makes the stripped question differ from the full one.
|
|
352
|
+
//
|
|
353
|
+
// One tag carrying a runtime check is enough, and the row it sits in need not
|
|
354
|
+
// carry them all. `Check_string` and `Check_number` filter per tag, so
|
|
355
|
+
// `[key: number & Minimum<0> & <a tag with no runtime check>]` still emits the
|
|
356
|
+
// minimum -- reading the row as all-or-nothing here would have declared that
|
|
357
|
+
// key untagged and left its minimum inert, which is the defect #2347 closed.
|
|
358
|
+
//
|
|
359
|
+
// Answering yes where the stripped question turns out identical costs an
|
|
360
|
+
// unreachable branch, never a wrong answer: the tail is reached only after
|
|
361
|
+
// every full condition refused the key, so a stripped condition equal to one of
|
|
362
|
+
// them refuses it too.
|
|
363
|
+
func check_dynamic_properties_key_tagged(metadata *nativemetadata.MetadataSchema) bool {
|
|
364
|
+
for _, atomic := range metadata.Atomics {
|
|
365
|
+
for _, row := range atomic.Tags {
|
|
366
|
+
for _, tag := range row {
|
|
367
|
+
if tag.Validate != "" {
|
|
368
|
+
return true
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return false
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// The key declaration with its type tags removed, leaving the declared type
|
|
377
|
+
// alone. Templates, constants, and natives carry no tags, so only the atomics
|
|
378
|
+
// are rebuilt; the clone keeps the original reportable name untouched.
|
|
379
|
+
func check_dynamic_properties_key_untagged(metadata *nativemetadata.MetadataSchema) *nativemetadata.MetadataSchema {
|
|
380
|
+
clone := *metadata
|
|
381
|
+
clone.Atomics = make([]*nativemetadata.MetadataAtomic, 0, len(metadata.Atomics))
|
|
382
|
+
for _, atomic := range metadata.Atomics {
|
|
383
|
+
clone.Atomics = append(clone.Atomics, nativemetadata.MetadataAtomic_create(nativemetadata.MetadataAtomic{
|
|
384
|
+
Type: atomic.Type,
|
|
385
|
+
}))
|
|
386
|
+
}
|
|
387
|
+
return &clone
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// The type every declared key would have satisfied, for the report. Several
|
|
391
|
+
// signatures join with `|`, which is how the declaration reads.
|
|
392
|
+
func check_dynamic_properties_key_expected(dynamic []nativehelpers.IExpressionEntry) string {
|
|
393
|
+
names := make([]string, 0, len(dynamic))
|
|
394
|
+
for _, entry := range dynamic {
|
|
395
|
+
names = append(names, entry.Key.GetName())
|
|
396
|
+
}
|
|
397
|
+
return strings.Join(names, " | ")
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// The advice `Superfluous` gives -- remove the property -- is wrong here. The
|
|
401
|
+
// property is declared; its key is what broke.
|
|
402
|
+
func check_dynamic_properties_invalid_key_description(emit ...*shimprinter.EmitContext) *shimast.Node {
|
|
403
|
+
f := nativecontext.EmitFactoryOf(check_dynamic_properties_factory, emit...)
|
|
404
|
+
return f.NewCallExpression(
|
|
405
|
+
nativefactories.IdentifierFactory.Access(
|
|
406
|
+
nil,
|
|
407
|
+
f.NewArrayLiteralExpression(
|
|
408
|
+
f.NewNodeList([]*shimast.Node{
|
|
409
|
+
f.NewTemplateExpression(
|
|
410
|
+
f.NewTemplateHead("The key `", "The key \\`", shimast.TokenFlagsNone),
|
|
411
|
+
f.NewNodeList([]*shimast.Node{
|
|
412
|
+
f.NewTemplateSpan(
|
|
413
|
+
f.NewIdentifier("key"),
|
|
414
|
+
f.NewTemplateTail("` does not satisfy the type its index signature declares.", "\\` does not satisfy the type its index signature declares.", shimast.TokenFlagsNone),
|
|
415
|
+
),
|
|
416
|
+
}),
|
|
417
|
+
),
|
|
418
|
+
f.NewStringLiteral("", shimast.TokenFlagsNone),
|
|
419
|
+
f.NewStringLiteral("Please correct the key next time.", shimast.TokenFlagsNone),
|
|
420
|
+
}),
|
|
421
|
+
true,
|
|
422
|
+
),
|
|
423
|
+
"join",
|
|
424
|
+
),
|
|
425
|
+
nil,
|
|
426
|
+
nil,
|
|
427
|
+
f.NewNodeList([]*shimast.Node{
|
|
428
|
+
f.NewStringLiteral("\n", shimast.TokenFlagsNone),
|
|
429
|
+
}),
|
|
430
|
+
shimast.NodeFlagsNone,
|
|
431
|
+
)
|
|
432
|
+
}
|
|
433
|
+
|
|
260
434
|
func check_dynamic_properties_superfluous_description(emit ...*shimprinter.EmitContext) *shimast.Node {
|
|
261
435
|
f := nativecontext.EmitFactoryOf(check_dynamic_properties_factory, emit...)
|
|
262
436
|
return f.NewCallExpression(
|
|
@@ -22,7 +22,18 @@ type Check_object_IConfig struct {
|
|
|
22
22
|
Reduce func(a *shimast.Expression, b *shimast.Expression) *shimast.Node
|
|
23
23
|
Positive *shimast.Expression
|
|
24
24
|
Superfluous func(value *shimast.Expression, description *shimast.Expression) *shimast.Node
|
|
25
|
-
|
|
25
|
+
// InvalidKey reports a dynamic key an index signature declares but whose type
|
|
26
|
+
// tag it breaks. A key no signature declares at all is a surplus property and
|
|
27
|
+
// goes to `Superfluous` instead.
|
|
28
|
+
//
|
|
29
|
+
// `Superfluous` is the wrong report for this one: it says the property is not
|
|
30
|
+
// defined in the object type and advises removing it, which is false and
|
|
31
|
+
// unhelpful when the property *is* declared and only its key broke a
|
|
32
|
+
// constraint. A programmer that has no better answer may leave this nil, and
|
|
33
|
+
// `Superfluous` is used instead -- the outcome is identical, only the message
|
|
34
|
+
// differs.
|
|
35
|
+
InvalidKey func(value *shimast.Expression, expected string, description *shimast.Expression) *shimast.Node
|
|
36
|
+
Entries *shimast.Expression
|
|
26
37
|
}
|
|
27
38
|
|
|
28
39
|
func Check_object(props Check_objectProps) *shimast.Node {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typia",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0",
|
|
4
4
|
"description": "Superfast runtime validators with only one line",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -26,9 +26,6 @@
|
|
|
26
26
|
},
|
|
27
27
|
"./package.json": "./package.json"
|
|
28
28
|
},
|
|
29
|
-
"bin": {
|
|
30
|
-
"typia": "./lib/executable/typia.js"
|
|
31
|
-
},
|
|
32
29
|
"ttsc": {
|
|
33
30
|
"plugin": {
|
|
34
31
|
"transform": "typia/lib/transform"
|
|
@@ -46,12 +43,9 @@
|
|
|
46
43
|
"homepage": "https://typia.io",
|
|
47
44
|
"dependencies": {
|
|
48
45
|
"@standard-schema/spec": "^1.0.0",
|
|
49
|
-
"commander": "^10.0.0",
|
|
50
|
-
"inquirer": "^8.2.5",
|
|
51
46
|
"randexp": "^0.5.3",
|
|
52
|
-
"
|
|
53
|
-
"@typia/
|
|
54
|
-
"@typia/utils": "^13.3.0"
|
|
47
|
+
"@typia/interface": "^14.0.0",
|
|
48
|
+
"@typia/utils": "^14.0.0"
|
|
55
49
|
},
|
|
56
50
|
"peerDependencies": {
|
|
57
51
|
"ttsc": ">=0.19.2"
|
|
@@ -62,12 +56,9 @@
|
|
|
62
56
|
}
|
|
63
57
|
},
|
|
64
58
|
"devDependencies": {
|
|
65
|
-
"@types/inquirer": "^8.2.5",
|
|
66
59
|
"@types/node": "^25.3.0",
|
|
67
|
-
"chalk": "^4.0.0",
|
|
68
60
|
"rimraf": "^6.1.2",
|
|
69
61
|
"rolldown": "^1.1.5",
|
|
70
|
-
"suppress-warnings": "^1.0.2",
|
|
71
62
|
"ttsc": "^0.19.2",
|
|
72
63
|
"typescript": "^7.0.2"
|
|
73
64
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import RandExp from "randexp";
|
|
2
2
|
|
|
3
3
|
import { _ILengthProps } from "./_randomStringLength";
|
|
4
|
+
import { _stringLength } from "./_stringLength";
|
|
4
5
|
|
|
5
6
|
export const _randomPattern = (
|
|
6
7
|
regex: RegExp,
|
|
@@ -16,14 +17,28 @@ export const _randomPattern = (
|
|
|
16
17
|
if (max !== undefined) r.max = max;
|
|
17
18
|
else if (min !== undefined && min * 2 > r.max) r.max = min * 2;
|
|
18
19
|
|
|
20
|
+
// The verification counts characters, not UTF-16 code units, because that is
|
|
21
|
+
// what `MinLength` and `MaxLength` compare against. `Pattern` compiles to a
|
|
22
|
+
// flagless `RegExp`, so a quantifier binds one code unit wherever its atom is
|
|
23
|
+
// a bare astral character: under `^😀+$` the `+` repeats the trailing low
|
|
24
|
+
// surrogate alone, and RandExp draws `\ud83d` + k * `\ude00` -- k characters
|
|
25
|
+
// in k + 1 code units. Measuring in code units accepted a two-character draw
|
|
26
|
+
// for `MinLength<3>` and handed back a value the generated validator rejects.
|
|
27
|
+
// Group the atom (`^(?:😀)+$`) and the arithmetic changes to 2k units for k
|
|
28
|
+
// characters; the two counts still differ, which is the point.
|
|
29
|
+
//
|
|
30
|
+
// The count is taken only after the pattern matches, and only when a bound
|
|
31
|
+
// exists, so an unbounded draw still walks nothing.
|
|
19
32
|
const bounded: boolean = min !== undefined || max !== undefined;
|
|
20
33
|
const limit: number = bounded ? 1024 : 10;
|
|
21
34
|
for (let i: number = 0; i < limit; ++i) {
|
|
22
35
|
const str: string = r.gen();
|
|
36
|
+
if (regex.test(str) === false) continue;
|
|
37
|
+
if (bounded === false) return str;
|
|
38
|
+
const length: number = _stringLength(str);
|
|
23
39
|
if (
|
|
24
|
-
|
|
25
|
-
(
|
|
26
|
-
(max === undefined || str.length <= max)
|
|
40
|
+
(min === undefined || length >= min) &&
|
|
41
|
+
(max === undefined || length <= max)
|
|
27
42
|
)
|
|
28
43
|
return str;
|
|
29
44
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { _randomInteger } from "./_randomInteger";
|
|
2
2
|
import { _randomString } from "./_randomString";
|
|
3
|
+
import { _stringLength } from "./_stringLength";
|
|
3
4
|
|
|
4
5
|
export const _RANDOM_LENGTH_ERROR =
|
|
5
6
|
"unable to generate a random string satisfying both the format and the length constraints.";
|
|
@@ -106,9 +107,15 @@ export const _randomFormatLength = (
|
|
|
106
107
|
return generate();
|
|
107
108
|
for (let i: number = 0; i < 256; ++i) {
|
|
108
109
|
const value: string = generate();
|
|
110
|
+
// Characters, not UTF-16 code units: `minLength` and `maxLength` are the
|
|
111
|
+
// bounds the generated validator compares in characters. `uuid` and `date`,
|
|
112
|
+
// the only two shapes routed through here, are ASCII, so the two counts
|
|
113
|
+
// agree for them today -- this keeps one measure so a later non-ASCII
|
|
114
|
+
// format cannot reintroduce the divergence unnoticed.
|
|
115
|
+
const length: number = _stringLength(value);
|
|
109
116
|
if (
|
|
110
|
-
(props.minLength === undefined ||
|
|
111
|
-
(props.maxLength === undefined ||
|
|
117
|
+
(props.minLength === undefined || length >= props.minLength) &&
|
|
118
|
+
(props.maxLength === undefined || length <= props.maxLength)
|
|
112
119
|
)
|
|
113
120
|
return value;
|
|
114
121
|
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
export declare namespace FileSystemIdentity {
|
|
4
|
-
interface IIdentity {
|
|
5
|
-
readonly caseSensitive: boolean;
|
|
6
|
-
contains(file: string, directory: string): boolean;
|
|
7
|
-
filesystemKey(file: string): string;
|
|
8
|
-
isDeclarationFile(file: string): boolean;
|
|
9
|
-
isSamePath(x: string, y: string): boolean;
|
|
10
|
-
isSupportedExtension(file: string): boolean;
|
|
11
|
-
projectFileKey(file: string): string;
|
|
12
|
-
}
|
|
13
|
-
function create(caseSensitive: boolean, pathApi?: typeof path.posix): IIdentity;
|
|
14
|
-
class Policy {
|
|
15
|
-
private caseSensitive_;
|
|
16
|
-
private location_;
|
|
17
|
-
observe(caseSensitive: boolean | undefined, location: string): void;
|
|
18
|
-
get(): IIdentity;
|
|
19
|
-
}
|
|
20
|
-
function inspectDirectory(directory: string): Promise<boolean | undefined>;
|
|
21
|
-
function probeDirectory(directory: string): Promise<boolean>;
|
|
22
|
-
/**
|
|
23
|
-
* Builds the key that decides whether two paths are the same filesystem
|
|
24
|
-
* object.
|
|
25
|
-
*
|
|
26
|
-
* The identity is read from `fs.BigIntStats` rather than `fs.Stats`, because
|
|
27
|
-
* `fs.Stats.ino` is a JavaScript number. An NTFS file ID is `(sequenceNumber
|
|
28
|
-
* << 48) | mftRecordIndex` and routinely exceeds `Number.MAX_SAFE_INTEGER` —
|
|
29
|
-
* in a 4000-directory probe, 1879 of them did — where the spacing between
|
|
30
|
-
* representable doubles is 8 or more. Two entries sharing a sequence number
|
|
31
|
-
* with MFT record indices within that spacing round to one double. The
|
|
32
|
-
* traversal callers would then treat a distinct directory or file as already
|
|
33
|
-
* visited and skip it with no diagnostic, and the overwrite guard would
|
|
34
|
-
* refuse a legitimate output (samchon/typia#2269).
|
|
35
|
-
*
|
|
36
|
-
* A filesystem that reports no inode at all keeps the canonical path
|
|
37
|
-
* fallback, which is the only identity available there.
|
|
38
|
-
*
|
|
39
|
-
* @param stat Stats read with `{ bigint: true }`.
|
|
40
|
-
* @param realpath Canonical path of the same object.
|
|
41
|
-
* @returns Key that is equal for two paths only when they are one object.
|
|
42
|
-
*/
|
|
43
|
-
function identityKey(stat: Pick<fs.BigIntStats, "dev" | "ino">, realpath: string): string;
|
|
44
|
-
}
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.FileSystemIdentity = void 0;
|
|
16
|
-
const fs_1 = __importDefault(require("fs"));
|
|
17
|
-
const path_1 = __importDefault(require("path"));
|
|
18
|
-
var FileSystemIdentity;
|
|
19
|
-
(function (FileSystemIdentity) {
|
|
20
|
-
function create(caseSensitive, pathApi = path_1.default) {
|
|
21
|
-
const fold = (value) => caseSensitive ? value : value.toLowerCase();
|
|
22
|
-
const filesystemKey = (file) => fold(pathApi.normalize(file));
|
|
23
|
-
return {
|
|
24
|
-
caseSensitive,
|
|
25
|
-
contains: (file, directory) => {
|
|
26
|
-
const fileKey = filesystemKey(pathApi.resolve(file));
|
|
27
|
-
const directoryKey = filesystemKey(pathApi.resolve(directory));
|
|
28
|
-
const prefix = directoryKey.endsWith(pathApi.sep)
|
|
29
|
-
? directoryKey
|
|
30
|
-
: `${directoryKey}${pathApi.sep}`;
|
|
31
|
-
return fileKey === directoryKey || fileKey.startsWith(prefix);
|
|
32
|
-
},
|
|
33
|
-
filesystemKey,
|
|
34
|
-
isDeclarationFile: (file) => DTS_PATTERN.test(fold(pathApi.basename(file))),
|
|
35
|
-
isSamePath: (x, y) => filesystemKey(x) === filesystemKey(y),
|
|
36
|
-
isSupportedExtension: (file) => {
|
|
37
|
-
const filename = fold(pathApi.basename(file));
|
|
38
|
-
return (TS_PATTERN.test(filename) && DTS_PATTERN.test(filename) === false);
|
|
39
|
-
},
|
|
40
|
-
projectFileKey: fold,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
FileSystemIdentity.create = create;
|
|
44
|
-
class Policy {
|
|
45
|
-
observe(caseSensitive, location) {
|
|
46
|
-
if (caseSensitive === undefined)
|
|
47
|
-
return;
|
|
48
|
-
if (this.caseSensitive_ === undefined) {
|
|
49
|
-
this.caseSensitive_ = caseSensitive;
|
|
50
|
-
this.location_ = location;
|
|
51
|
-
}
|
|
52
|
-
else if (this.caseSensitive_ !== caseSensitive) {
|
|
53
|
-
throw new URIError(`Error on TypiaGenerateWizard.generate(): inconsistent filesystem case behavior between ${this.location_} and ${location}.`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
get() {
|
|
57
|
-
if (this.caseSensitive_ === undefined) {
|
|
58
|
-
throw new URIError("Error on TypiaGenerateWizard.generate(): unable to determine filesystem case behavior for this run.");
|
|
59
|
-
}
|
|
60
|
-
return create(this.caseSensitive_);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
FileSystemIdentity.Policy = Policy;
|
|
64
|
-
function inspectDirectory(directory) {
|
|
65
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
-
const names = yield fs_1.default.promises.readdir(directory);
|
|
67
|
-
const entries = new Set(names);
|
|
68
|
-
for (const name of names) {
|
|
69
|
-
const alternate = alternateCase(name);
|
|
70
|
-
if (alternate === undefined)
|
|
71
|
-
continue;
|
|
72
|
-
if (entries.has(alternate))
|
|
73
|
-
return true;
|
|
74
|
-
try {
|
|
75
|
-
yield fs_1.default.promises.lstat(path_1.default.join(directory, alternate));
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
78
|
-
catch (error) {
|
|
79
|
-
if (isMissingFileError(error))
|
|
80
|
-
return true;
|
|
81
|
-
throw error;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return undefined;
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
FileSystemIdentity.inspectDirectory = inspectDirectory;
|
|
88
|
-
function probeDirectory(directory) {
|
|
89
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
90
|
-
const inspected = yield inspectDirectory(directory);
|
|
91
|
-
if (inspected !== undefined)
|
|
92
|
-
return inspected;
|
|
93
|
-
for (let attempt = 0; attempt < 10; ++attempt) {
|
|
94
|
-
const name = `.typia-case-probe-${process.pid}-${Date.now()}-${Math.random()
|
|
95
|
-
.toString(36)
|
|
96
|
-
.slice(2)}`.toLowerCase();
|
|
97
|
-
const original = path_1.default.join(directory, name);
|
|
98
|
-
const alternate = path_1.default.join(directory, name.toUpperCase());
|
|
99
|
-
let handle;
|
|
100
|
-
try {
|
|
101
|
-
handle = yield fs_1.default.promises.open(original, "wx");
|
|
102
|
-
}
|
|
103
|
-
catch (error) {
|
|
104
|
-
if (isAlreadyExistsError(error))
|
|
105
|
-
continue;
|
|
106
|
-
throw new URIError(`Error on TypiaGenerateWizard.generate(): unable to probe filesystem case behavior at ${directory}: ${formatUnknownError(error)}`);
|
|
107
|
-
}
|
|
108
|
-
let closed = false;
|
|
109
|
-
try {
|
|
110
|
-
yield handle.close();
|
|
111
|
-
closed = true;
|
|
112
|
-
try {
|
|
113
|
-
yield fs_1.default.promises.lstat(alternate);
|
|
114
|
-
return false;
|
|
115
|
-
}
|
|
116
|
-
catch (error) {
|
|
117
|
-
if (isMissingFileError(error))
|
|
118
|
-
return true;
|
|
119
|
-
throw error;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
finally {
|
|
123
|
-
let cleanupError;
|
|
124
|
-
if (closed === false) {
|
|
125
|
-
try {
|
|
126
|
-
yield handle.close();
|
|
127
|
-
}
|
|
128
|
-
catch (error) {
|
|
129
|
-
cleanupError = error;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
try {
|
|
133
|
-
yield fs_1.default.promises.unlink(original);
|
|
134
|
-
}
|
|
135
|
-
catch (error) {
|
|
136
|
-
if (isMissingFileError(error) === false)
|
|
137
|
-
cleanupError !== null && cleanupError !== void 0 ? cleanupError : (cleanupError = error);
|
|
138
|
-
}
|
|
139
|
-
if (cleanupError !== undefined) {
|
|
140
|
-
throw new URIError(`Error on TypiaGenerateWizard.generate(): unable to clean filesystem case probe ${original}: ${formatUnknownError(cleanupError)}`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
throw new URIError(`Error on TypiaGenerateWizard.generate(): unable to reserve a filesystem case probe at ${directory}.`);
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
FileSystemIdentity.probeDirectory = probeDirectory;
|
|
148
|
-
/**
|
|
149
|
-
* Builds the key that decides whether two paths are the same filesystem
|
|
150
|
-
* object.
|
|
151
|
-
*
|
|
152
|
-
* The identity is read from `fs.BigIntStats` rather than `fs.Stats`, because
|
|
153
|
-
* `fs.Stats.ino` is a JavaScript number. An NTFS file ID is `(sequenceNumber
|
|
154
|
-
* << 48) | mftRecordIndex` and routinely exceeds `Number.MAX_SAFE_INTEGER` —
|
|
155
|
-
* in a 4000-directory probe, 1879 of them did — where the spacing between
|
|
156
|
-
* representable doubles is 8 or more. Two entries sharing a sequence number
|
|
157
|
-
* with MFT record indices within that spacing round to one double. The
|
|
158
|
-
* traversal callers would then treat a distinct directory or file as already
|
|
159
|
-
* visited and skip it with no diagnostic, and the overwrite guard would
|
|
160
|
-
* refuse a legitimate output (samchon/typia#2269).
|
|
161
|
-
*
|
|
162
|
-
* A filesystem that reports no inode at all keeps the canonical path
|
|
163
|
-
* fallback, which is the only identity available there.
|
|
164
|
-
*
|
|
165
|
-
* @param stat Stats read with `{ bigint: true }`.
|
|
166
|
-
* @param realpath Canonical path of the same object.
|
|
167
|
-
* @returns Key that is equal for two paths only when they are one object.
|
|
168
|
-
*/
|
|
169
|
-
function identityKey(stat, realpath) {
|
|
170
|
-
// `BigInt(0)` rather than `0n`: this package compiles at ES2016, where a
|
|
171
|
-
// BigInt literal is a syntax error, while the constructor and the `bigint`
|
|
172
|
-
// type are fine.
|
|
173
|
-
return stat.ino === BigInt(0)
|
|
174
|
-
? `path:${path_1.default.normalize(realpath)}`
|
|
175
|
-
: `inode:${stat.dev}:${stat.ino}`;
|
|
176
|
-
}
|
|
177
|
-
FileSystemIdentity.identityKey = identityKey;
|
|
178
|
-
function alternateCase(name) {
|
|
179
|
-
let changed = false;
|
|
180
|
-
let output = "";
|
|
181
|
-
for (const character of name) {
|
|
182
|
-
if (character >= "a" && character <= "z") {
|
|
183
|
-
output += character.toUpperCase();
|
|
184
|
-
changed = true;
|
|
185
|
-
}
|
|
186
|
-
else if (character >= "A" && character <= "Z") {
|
|
187
|
-
output += character.toLowerCase();
|
|
188
|
-
changed = true;
|
|
189
|
-
}
|
|
190
|
-
else
|
|
191
|
-
output += character;
|
|
192
|
-
}
|
|
193
|
-
return changed ? output : undefined;
|
|
194
|
-
}
|
|
195
|
-
function isAlreadyExistsError(error) {
|
|
196
|
-
return (typeof error === "object" &&
|
|
197
|
-
error !== null &&
|
|
198
|
-
"code" in error &&
|
|
199
|
-
error.code === "EEXIST");
|
|
200
|
-
}
|
|
201
|
-
function isMissingFileError(error) {
|
|
202
|
-
return (typeof error === "object" &&
|
|
203
|
-
error !== null &&
|
|
204
|
-
"code" in error &&
|
|
205
|
-
error.code === "ENOENT");
|
|
206
|
-
}
|
|
207
|
-
function formatUnknownError(error) {
|
|
208
|
-
return error instanceof Error ? error.message : String(error);
|
|
209
|
-
}
|
|
210
|
-
})(FileSystemIdentity || (exports.FileSystemIdentity = FileSystemIdentity = {}));
|
|
211
|
-
const TS_PATTERN = /\.[cm]?tsx?$/;
|
|
212
|
-
const DTS_PATTERN = /\.d\.[cm]?tsx?$/;
|
|
213
|
-
//# sourceMappingURL=FileSystemIdentity.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"FileSystemIdentity.js","sourceRoot":"","sources":["../../src/executable/FileSystemIdentity.ts"],"names":[],"mappings":"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"}
|