1
- import { DefaultMap } from "./map.js" ;
2
-
3
1
/**
4
2
* This type provides a flag that can be used to turn off more lax overloads intended for
5
3
* plugin use only to catch type errors in the TypeDoc codebase. The prepublishOnly npm
@@ -36,12 +34,6 @@ export type IfInternal<T, F> = InternalOnly extends true ? T : F;
36
34
*/
37
35
export type NeverIfInternal < T > = IfInternal < never , T > ;
38
36
39
- /**
40
- * Resolves a string type into a union of characters, `"ab"` turns into `"a" | "b"`.
41
- */
42
- export type Chars < T extends string > = T extends `${infer C } ${infer R } ` ? C | Chars < R > :
43
- never ;
44
-
45
37
/**
46
38
* Utility to help type checking ensure that there is no uncovered case.
47
39
*/
@@ -51,76 +43,6 @@ export function assertNever(x: never): never {
51
43
) ;
52
44
}
53
45
54
- // From MDN
55
- export function escapeRegExp ( s : string ) {
56
- return s . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, "\\$&" ) ; // $& means the whole matched string
57
- }
58
-
59
- export function dedent ( text : string ) {
60
- const lines = text . split ( / \r ? \n / ) ;
61
- while ( lines . length && lines [ 0 ] . search ( / \S / ) === - 1 ) {
62
- lines . shift ( ) ;
63
- }
64
- while ( lines . length && lines [ lines . length - 1 ] . search ( / \S / ) === - 1 ) {
65
- lines . pop ( ) ;
66
- }
67
-
68
- const minIndent = lines . reduce (
69
- ( indent , line ) => line . length ? Math . min ( indent , line . search ( / \S / ) ) : indent ,
70
- Infinity ,
71
- ) ;
72
-
73
- return lines . map ( ( line ) => line . substring ( minIndent ) ) . join ( "\n" ) ;
74
- }
75
-
76
- // Based on https://en.wikipedia.org/wiki/Levenshtein_distance#Iterative_with_two_matrix_rows
77
- // Slightly modified for improved match results for options
78
- export function editDistance ( s : string , t : string ) : number {
79
- if ( s . length < t . length ) return editDistance ( t , s ) ;
80
-
81
- let v0 = Array . from ( { length : t . length + 1 } , ( _ , i ) => i ) ;
82
- let v1 = Array . from ( { length : t . length + 1 } , ( ) => 0 ) ;
83
-
84
- for ( let i = 0 ; i < s . length ; i ++ ) {
85
- v1 [ 0 ] = i + 1 ;
86
-
87
- for ( let j = 0 ; j < s . length ; j ++ ) {
88
- const deletionCost = v0 [ j + 1 ] + 1 ;
89
- const insertionCost = v1 [ j ] + 1 ;
90
- let substitutionCost : number ;
91
- if ( s [ i ] === t [ j ] ) {
92
- substitutionCost = v0 [ j ] ;
93
- } else if ( s [ i ] ?. toUpperCase ( ) === t [ j ] ?. toUpperCase ( ) ) {
94
- substitutionCost = v0 [ j ] + 1 ;
95
- } else {
96
- substitutionCost = v0 [ j ] + 3 ;
97
- }
98
-
99
- v1 [ j + 1 ] = Math . min ( deletionCost , insertionCost , substitutionCost ) ;
100
- }
101
-
102
- [ v0 , v1 ] = [ v1 , v0 ] ;
103
- }
104
-
105
- return v0 [ t . length ] ;
106
- }
107
-
108
- export function getSimilarValues ( values : Iterable < string > , compareTo : string ) {
109
- const results = new DefaultMap < number , string [ ] > ( ( ) => [ ] ) ;
110
- let lowest = Infinity ;
111
- for ( const name of values ) {
112
- const distance = editDistance ( compareTo , name ) ;
113
- lowest = Math . min ( lowest , distance ) ;
114
- results . get ( distance ) . push ( name ) ;
115
- }
116
-
117
- // Experimenting a bit, it seems an edit distance of 3 is roughly the
118
- // right metric for relevant "similar" results without showing obviously wrong suggestions
119
- return results
120
- . get ( lowest )
121
- . concat ( results . get ( lowest + 1 ) , results . get ( lowest + 2 ) ) ;
122
- }
123
-
124
46
export function NonEnumerable (
125
47
_cls : unknown ,
126
48
context : ClassFieldDecoratorContext ,
0 commit comments