@jsbot-tellus/core 2.9.1 → 2.10.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/dist/core/plugin/params/declaration.d.ts +2 -2
- package/dist/core/plugin/params/declaration.d.ts.map +1 -1
- package/dist/core/plugin/params/declaration.js +189 -24
- package/dist/core/plugin/params/declaration.js.map +1 -1
- package/dist/core/plugin/params/input.d.ts.map +1 -1
- package/dist/core/plugin/params/input.js +35 -12
- package/dist/core/plugin/params/input.js.map +1 -1
- package/dist/core/plugin/params/type-level.d.ts +13 -3
- package/dist/core/plugin/params/type-level.d.ts.map +1 -1
- package/dist/core/plugin/params/types.d.ts +13 -2
- package/dist/core/plugin/params/types.d.ts.map +1 -1
- package/dist/core/plugin/params/types.js +22 -0
- package/dist/core/plugin/params/types.js.map +1 -1
- package/docs/plugin-api.md +27 -3
- package/package.json +1 -1
- package/src/core/plugin/params/declaration.ts +269 -31
- package/src/core/plugin/params/input.ts +63 -12
- package/src/core/plugin/params/type-level.ts +114 -6
- package/src/core/plugin/params/types.ts +46 -2
|
@@ -11,7 +11,46 @@ type Trim<Source extends string> = TrimLeft<TrimRight<Source>>
|
|
|
11
11
|
type StripLength<Type extends string> =
|
|
12
12
|
Trim<Type> extends `${infer Base}(${string})` ? Trim<Base> : Trim<Type>
|
|
13
13
|
|
|
14
|
-
type
|
|
14
|
+
type Unescape<Source extends string> =
|
|
15
|
+
Source extends `${infer Head}\\${infer Next}${infer Rest}`
|
|
16
|
+
? `${Head}${Next}${Unescape<Rest>}`
|
|
17
|
+
: Source
|
|
18
|
+
|
|
19
|
+
type SplitUnionScan<
|
|
20
|
+
Source extends string,
|
|
21
|
+
Quote extends string | null = null,
|
|
22
|
+
Current extends string = '',
|
|
23
|
+
Acc extends string[] = [],
|
|
24
|
+
> = Source extends `${infer Char}${infer Rest}`
|
|
25
|
+
? Char extends '\\'
|
|
26
|
+
? Rest extends `${infer Next}${infer Tail}`
|
|
27
|
+
? SplitUnionScan<Tail, Quote, `${Current}${Char}${Next}`, Acc>
|
|
28
|
+
: [...Acc, `${Current}${Char}`]
|
|
29
|
+
: Char extends '"' | "'"
|
|
30
|
+
? Quote extends null
|
|
31
|
+
? SplitUnionScan<Rest, Char, `${Current}${Char}`, Acc>
|
|
32
|
+
: Char extends Quote
|
|
33
|
+
? SplitUnionScan<Rest, null, `${Current}${Char}`, Acc>
|
|
34
|
+
: SplitUnionScan<Rest, Quote, `${Current}${Char}`, Acc>
|
|
35
|
+
: Char extends '|'
|
|
36
|
+
? Quote extends null
|
|
37
|
+
? SplitUnionScan<Rest, null, '', [...Acc, Current]>
|
|
38
|
+
: SplitUnionScan<Rest, Quote, `${Current}${Char}`, Acc>
|
|
39
|
+
: SplitUnionScan<Rest, Quote, `${Current}${Char}`, Acc>
|
|
40
|
+
: [...Acc, Current]
|
|
41
|
+
|
|
42
|
+
type SplitUnion<Source extends string> = Source extends `${string}|${string}`
|
|
43
|
+
? SplitUnionScan<Source>
|
|
44
|
+
: [Source]
|
|
45
|
+
|
|
46
|
+
type LiteralValue<Type extends string> =
|
|
47
|
+
Trim<Type> extends `'${infer Inner}'`
|
|
48
|
+
? Unescape<Inner>
|
|
49
|
+
: Trim<Type> extends `"${infer Inner}"`
|
|
50
|
+
? Unescape<Inner>
|
|
51
|
+
: never
|
|
52
|
+
|
|
53
|
+
type BuiltinValue<Type extends string> =
|
|
15
54
|
StripLength<Type> extends 'string' | 'text'
|
|
16
55
|
? string
|
|
17
56
|
: StripLength<Type> extends
|
|
@@ -21,19 +60,88 @@ type ParamValue<Type extends string> =
|
|
|
21
60
|
? boolean
|
|
22
61
|
: unknown
|
|
23
62
|
|
|
63
|
+
type ParamValuePart<Type extends string> =
|
|
64
|
+
Trim<Type> extends `'${string}'` | `"${string}"`
|
|
65
|
+
? LiteralValue<Type>
|
|
66
|
+
: BuiltinValue<Type>
|
|
67
|
+
|
|
68
|
+
type ParamValue<Type extends string> =
|
|
69
|
+
SplitUnion<Type>[number] extends infer Part
|
|
70
|
+
? Part extends string
|
|
71
|
+
? ParamValuePart<Part>
|
|
72
|
+
: never
|
|
73
|
+
: never
|
|
74
|
+
|
|
75
|
+
type SplitTypeScan<
|
|
76
|
+
Source extends string,
|
|
77
|
+
Quote extends string | null = null,
|
|
78
|
+
Name extends string = '',
|
|
79
|
+
> = Source extends `${infer Char}${infer Rest}`
|
|
80
|
+
? Char extends '\\'
|
|
81
|
+
? Rest extends `${infer Next}${infer Tail}`
|
|
82
|
+
? SplitTypeScan<Tail, Quote, `${Name}${Char}${Next}`>
|
|
83
|
+
: [Name, null]
|
|
84
|
+
: Char extends '"' | "'"
|
|
85
|
+
? Quote extends null
|
|
86
|
+
? SplitTypeScan<Rest, Char, `${Name}${Char}`>
|
|
87
|
+
: Char extends Quote
|
|
88
|
+
? SplitTypeScan<Rest, null, `${Name}${Char}`>
|
|
89
|
+
: SplitTypeScan<Rest, Quote, `${Name}${Char}`>
|
|
90
|
+
: Char extends ':'
|
|
91
|
+
? Quote extends null
|
|
92
|
+
? [Name, Rest]
|
|
93
|
+
: SplitTypeScan<Rest, Quote, `${Name}${Char}`>
|
|
94
|
+
: SplitTypeScan<Rest, Quote, `${Name}${Char}`>
|
|
95
|
+
: [Name, null]
|
|
96
|
+
|
|
97
|
+
type SplitType<Source extends string> = Source extends `${string}:${string}`
|
|
98
|
+
? SplitTypeScan<Source>
|
|
99
|
+
: [Source, null]
|
|
100
|
+
|
|
101
|
+
type SplitDefaultScan<
|
|
102
|
+
Source extends string,
|
|
103
|
+
Quote extends string | null = null,
|
|
104
|
+
Head extends string = '',
|
|
105
|
+
> = Source extends `${infer Char}${infer Rest}`
|
|
106
|
+
? Char extends '\\'
|
|
107
|
+
? Rest extends `${infer Next}${infer Tail}`
|
|
108
|
+
? SplitDefaultScan<Tail, Quote, `${Head}${Char}${Next}`>
|
|
109
|
+
: [Head, false]
|
|
110
|
+
: Char extends '"' | "'"
|
|
111
|
+
? Quote extends null
|
|
112
|
+
? SplitDefaultScan<Rest, Char, `${Head}${Char}`>
|
|
113
|
+
: Char extends Quote
|
|
114
|
+
? SplitDefaultScan<Rest, null, `${Head}${Char}`>
|
|
115
|
+
: SplitDefaultScan<Rest, Quote, `${Head}${Char}`>
|
|
116
|
+
: Char extends '='
|
|
117
|
+
? Quote extends null
|
|
118
|
+
? [Head, true]
|
|
119
|
+
: SplitDefaultScan<Rest, Quote, `${Head}${Char}`>
|
|
120
|
+
: SplitDefaultScan<Rest, Quote, `${Head}${Char}`>
|
|
121
|
+
: [Head, false]
|
|
122
|
+
|
|
123
|
+
type SplitDefault<Source extends string> = Source extends `${string}=${string}`
|
|
124
|
+
? SplitDefaultScan<Source>
|
|
125
|
+
: [Source, false]
|
|
126
|
+
|
|
24
127
|
interface VariadicParam {
|
|
25
128
|
readonly variadic: true
|
|
26
129
|
}
|
|
27
130
|
|
|
28
|
-
type ParamType<Head extends string> =
|
|
29
|
-
|
|
30
|
-
|
|
131
|
+
type ParamType<Head extends string> =
|
|
132
|
+
SplitType<Head> extends [unknown, infer Type]
|
|
133
|
+
? Type extends string
|
|
134
|
+
? ParamValue<Type>
|
|
135
|
+
: string
|
|
136
|
+
: string
|
|
31
137
|
|
|
32
138
|
type ParamElement<Body extends string, Required extends boolean> =
|
|
33
139
|
Trim<Body> extends `...${string}`
|
|
34
140
|
? VariadicParam
|
|
35
|
-
: Trim<Body
|
|
36
|
-
?
|
|
141
|
+
: SplitDefault<Trim<Body>> extends [infer Head, true]
|
|
142
|
+
? Head extends string
|
|
143
|
+
? ParamType<Head>
|
|
144
|
+
: never
|
|
37
145
|
: Required extends true
|
|
38
146
|
? ParamType<Body>
|
|
39
147
|
: ParamType<Body> | undefined
|
|
@@ -35,14 +35,26 @@ export interface ParamLength {
|
|
|
35
35
|
max?: number | undefined
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
export interface ParamTypeCandidate {
|
|
39
|
+
kind: 'type'
|
|
40
|
+
type: CommandParamType
|
|
41
|
+
length?: ParamLength | undefined
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface ParamLiteralCandidate {
|
|
45
|
+
kind: 'literal'
|
|
46
|
+
value: string
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type ParamCandidate = ParamTypeCandidate | ParamLiteralCandidate
|
|
50
|
+
|
|
38
51
|
export interface ParamSpec {
|
|
39
52
|
name: string
|
|
40
|
-
|
|
53
|
+
candidates: ParamCandidate[]
|
|
41
54
|
required: boolean
|
|
42
55
|
rest: boolean
|
|
43
56
|
hasDefault: boolean
|
|
44
57
|
defaultValue?: unknown
|
|
45
|
-
length?: ParamLength | undefined
|
|
46
58
|
}
|
|
47
59
|
|
|
48
60
|
export interface InputToken {
|
|
@@ -53,3 +65,35 @@ export interface InputToken {
|
|
|
53
65
|
export function declarationError(message: string): Error {
|
|
54
66
|
return new Error(`参数声明错误:${message}`)
|
|
55
67
|
}
|
|
68
|
+
|
|
69
|
+
export function candidateLabel(candidate: ParamCandidate): string {
|
|
70
|
+
if (candidate.kind === 'literal') {
|
|
71
|
+
const escaped = candidate.value
|
|
72
|
+
.replace(/\\/g, '\\\\')
|
|
73
|
+
.replace(/'/g, "\\'")
|
|
74
|
+
|
|
75
|
+
return `'${escaped}'`
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const length = candidate.length
|
|
79
|
+
|
|
80
|
+
if (length === undefined) {
|
|
81
|
+
return candidate.type
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return `${candidate.type}(${length.min ?? ''}..${length.max ?? ''})`
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function joinCandidateLabels(
|
|
88
|
+
candidates: readonly ParamCandidate[]
|
|
89
|
+
): string {
|
|
90
|
+
const labels = candidates.map(candidateLabel)
|
|
91
|
+
|
|
92
|
+
if (labels.length === 0) return ''
|
|
93
|
+
|
|
94
|
+
if (labels.length === 1) return labels[0] ?? ''
|
|
95
|
+
|
|
96
|
+
const last = labels[labels.length - 1] ?? ''
|
|
97
|
+
|
|
98
|
+
return `${labels.slice(0, -1).join('、')} 或 ${last}`
|
|
99
|
+
}
|