@gunshi/shared 0.26.3
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/LICENSE +20 -0
- package/README.md +9 -0
- package/lib/index.d.ts +562 -0
- package/lib/index.js +152 -0
- package/package.json +66 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 kazuya kawaguchi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
import en_US_default from "@gunshi/resources/en-US";
|
|
2
|
+
|
|
3
|
+
//#region rolldown:runtime
|
|
4
|
+
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region ../../node_modules/.pnpm/args-tokens@0.20.1/node_modules/args-tokens/lib/parser-FiQIAw-2.d.ts
|
|
7
|
+
//#region src/parser.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* Entry point of argument parser.
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* forked from `nodejs/node` (`pkgjs/parseargs`)
|
|
14
|
+
* repository url: https://github.com/nodejs/node (https://github.com/pkgjs/parseargs)
|
|
15
|
+
* code url: https://github.com/nodejs/node/blob/main/lib/internal/util/parse_args/parse_args.js
|
|
16
|
+
*
|
|
17
|
+
* @author kazuya kawaguchi (a.k.a. kazupon)
|
|
18
|
+
* @license MIT
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Argument token Kind.
|
|
22
|
+
* - `option`: option token, support short option (e.g. `-x`) and long option (e.g. `--foo`)
|
|
23
|
+
* - `option-terminator`: option terminator (`--`) token, see guideline 10 in https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html
|
|
24
|
+
* - `positional`: positional token
|
|
25
|
+
*/
|
|
26
|
+
type ArgTokenKind = "option" | "option-terminator" | "positional";
|
|
27
|
+
/**
|
|
28
|
+
* Argument token.
|
|
29
|
+
*/
|
|
30
|
+
interface ArgToken {
|
|
31
|
+
/**
|
|
32
|
+
* Argument token kind.
|
|
33
|
+
*/
|
|
34
|
+
kind: ArgTokenKind;
|
|
35
|
+
/**
|
|
36
|
+
* Argument token index, e.g `--foo bar` => `--foo` index is 0, `bar` index is 1.
|
|
37
|
+
*/
|
|
38
|
+
index: number;
|
|
39
|
+
/**
|
|
40
|
+
* Option name, e.g. `--foo` => `foo`, `-x` => `x`.
|
|
41
|
+
*/
|
|
42
|
+
name?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Raw option name, e.g. `--foo` => `--foo`, `-x` => `-x`.
|
|
45
|
+
*/
|
|
46
|
+
rawName?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Option value, e.g. `--foo=bar` => `bar`, `-x=bar` => `bar`.
|
|
49
|
+
* If the `allowCompatible` option is `true`, short option value will be same as Node.js `parseArgs` behavior.
|
|
50
|
+
*/
|
|
51
|
+
value?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Inline value, e.g. `--foo=bar` => `true`, `-x=bar` => `true`.
|
|
54
|
+
*/
|
|
55
|
+
inlineValue?: boolean;
|
|
56
|
+
} //#endregion
|
|
57
|
+
//#region ../../node_modules/.pnpm/args-tokens@0.20.1/node_modules/args-tokens/lib/resolver-U72Jg6Ll.d.ts
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Parser Options.
|
|
61
|
+
*/
|
|
62
|
+
//#region src/resolver.d.ts
|
|
63
|
+
/**
|
|
64
|
+
* An argument schema
|
|
65
|
+
* This schema is similar to the schema of the `node:utils`.
|
|
66
|
+
* difference is that:
|
|
67
|
+
* - `required` property and `description` property are added
|
|
68
|
+
* - `type` is not only 'string' and 'boolean', but also 'number', 'enum', 'positional', 'custom' too.
|
|
69
|
+
* - `default` property type, not support multiple types
|
|
70
|
+
*/
|
|
71
|
+
interface ArgSchema {
|
|
72
|
+
/**
|
|
73
|
+
* Type of argument.
|
|
74
|
+
*/
|
|
75
|
+
type: "string" | "boolean" | "number" | "enum" | "positional" | "custom";
|
|
76
|
+
/**
|
|
77
|
+
* A single character alias for the argument.
|
|
78
|
+
*/
|
|
79
|
+
short?: string;
|
|
80
|
+
/**
|
|
81
|
+
* A description of the argument.
|
|
82
|
+
*/
|
|
83
|
+
description?: string;
|
|
84
|
+
/**
|
|
85
|
+
* Whether the argument is required or not.
|
|
86
|
+
*/
|
|
87
|
+
required?: true;
|
|
88
|
+
/**
|
|
89
|
+
* Whether the argument allow multiple values or not.
|
|
90
|
+
*/
|
|
91
|
+
multiple?: true;
|
|
92
|
+
/**
|
|
93
|
+
* Whether the negatable option for `boolean` type
|
|
94
|
+
*/
|
|
95
|
+
negatable?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* The allowed values of the argument, and string only. This property is only used when the type is 'enum'.
|
|
98
|
+
*/
|
|
99
|
+
choices?: string[] | readonly string[];
|
|
100
|
+
/**
|
|
101
|
+
* The default value of the argument.
|
|
102
|
+
* if the type is 'enum', the default value must be one of the allowed values.
|
|
103
|
+
*/
|
|
104
|
+
default?: string | boolean | number;
|
|
105
|
+
/**
|
|
106
|
+
* Whether to convert the argument name to kebab-case.
|
|
107
|
+
*/
|
|
108
|
+
toKebab?: true;
|
|
109
|
+
/**
|
|
110
|
+
* A function to parse the value of the argument. if the type is 'custom', this function is required.
|
|
111
|
+
* If argument value will be invalid, this function have to throw an error.
|
|
112
|
+
* @param value
|
|
113
|
+
* @returns Parsed value
|
|
114
|
+
* @throws An Error, If the value is invalid. Error type should be `Error` or extends it
|
|
115
|
+
*/
|
|
116
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
117
|
+
parse?: (value: string) => any;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* An object that contains {@link ArgSchema | argument schema}.
|
|
121
|
+
*/
|
|
122
|
+
interface Args {
|
|
123
|
+
[option: string]: ArgSchema;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* An object that contains the values of the arguments.
|
|
127
|
+
*/
|
|
128
|
+
type ArgValues<T> = T extends Args ? ResolveArgValues<T, { [Arg in keyof T]: ExtractOptionValue<T[Arg]> }> : {
|
|
129
|
+
[option: string]: string | boolean | number | (string | boolean | number)[] | undefined;
|
|
130
|
+
};
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
132
|
+
type IsFunction<T> = T extends ((...args: any[]) => any) ? true : false;
|
|
133
|
+
/**
|
|
134
|
+
* @internal
|
|
135
|
+
*/
|
|
136
|
+
type ExtractOptionValue<A extends ArgSchema> = A["type"] extends "string" ? ResolveOptionValue<A, string> : A["type"] extends "boolean" ? ResolveOptionValue<A, boolean> : A["type"] extends "number" ? ResolveOptionValue<A, number> : A["type"] extends "positional" ? ResolveOptionValue<A, string> : A["type"] extends "enum" ? A["choices"] extends string[] | readonly string[] ? ResolveOptionValue<A, A["choices"][number]> : never : A["type"] extends "custom" ? IsFunction<A["parse"]> extends true ? ResolveOptionValue<A, ReturnType<NonNullable<A["parse"]>>> : never : ResolveOptionValue<A, string | boolean | number>;
|
|
137
|
+
type ResolveOptionValue<A extends ArgSchema, T> = A["multiple"] extends true ? T[] : T;
|
|
138
|
+
/**
|
|
139
|
+
* @internal
|
|
140
|
+
*/
|
|
141
|
+
type ResolveArgValues<A extends Args, V extends Record<keyof A, unknown>> = { -readonly [Arg in keyof A]?: V[Arg] } & FilterArgs<A, V, "default"> & FilterArgs<A, V, "required"> & FilterPositionalArgs<A, V> extends infer P ? { [K in keyof P]: P[K] } : never;
|
|
142
|
+
/**
|
|
143
|
+
* @internal
|
|
144
|
+
*/
|
|
145
|
+
type FilterArgs<A extends Args, V extends Record<keyof A, unknown>, K extends keyof ArgSchema> = { [Arg in keyof A as A[Arg][K] extends {} ? Arg : never]: V[Arg] };
|
|
146
|
+
/**
|
|
147
|
+
* @internal
|
|
148
|
+
*/
|
|
149
|
+
type FilterPositionalArgs<A extends Args, V extends Record<keyof A, unknown>> = { [Arg in keyof A as A[Arg]["type"] extends "positional" ? Arg : never]: V[Arg] };
|
|
150
|
+
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region ../gunshi/src/types.d.ts
|
|
153
|
+
/**
|
|
154
|
+
* An arguments for {@link resolveArgs | resolve arguments}.
|
|
155
|
+
*/
|
|
156
|
+
type Awaitable<T> = T | Promise<T>;
|
|
157
|
+
/**
|
|
158
|
+
* Extend command context type. This type is used to extend the command context with additional properties at {@link CommandContext.extensions}.
|
|
159
|
+
*/
|
|
160
|
+
type ExtendContext = Record<string, unknown>;
|
|
161
|
+
/**
|
|
162
|
+
* Gunshi unified parameter type.
|
|
163
|
+
* This type combines both argument definitions and command context extensions.
|
|
164
|
+
*/
|
|
165
|
+
interface GunshiParams<P extends {
|
|
166
|
+
args?: Args;
|
|
167
|
+
extensions?: ExtendContext;
|
|
168
|
+
} = {
|
|
169
|
+
args: Args;
|
|
170
|
+
extensions: {};
|
|
171
|
+
}> {
|
|
172
|
+
/**
|
|
173
|
+
* Command argument definitions
|
|
174
|
+
*/
|
|
175
|
+
args: P extends {
|
|
176
|
+
args: infer A extends Args;
|
|
177
|
+
} ? A : Args;
|
|
178
|
+
/**
|
|
179
|
+
* Command context extensions
|
|
180
|
+
*/
|
|
181
|
+
extensions: P extends {
|
|
182
|
+
extensions: infer E extends ExtendContext;
|
|
183
|
+
} ? E : {};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Default Gunshi parameters
|
|
187
|
+
*/
|
|
188
|
+
type DefaultGunshiParams = GunshiParams;
|
|
189
|
+
/**
|
|
190
|
+
* Generic constraint for command-related types.
|
|
191
|
+
* This type constraint allows both GunshiParams and objects with extensions.
|
|
192
|
+
*/
|
|
193
|
+
type GunshiParamsConstraint = GunshiParams<any> | {
|
|
194
|
+
extensions: ExtendContext;
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* Type helper to extract args from G
|
|
198
|
+
* @internal
|
|
199
|
+
*/
|
|
200
|
+
type ExtractArgs<G> = G extends GunshiParams<any> ? G['args'] : Args;
|
|
201
|
+
/**
|
|
202
|
+
* Type helper to extract extensions from G
|
|
203
|
+
* @internal
|
|
204
|
+
*/
|
|
205
|
+
type ExtractExtensions<G> = G extends GunshiParams<any> ? G['extensions'] : G extends {
|
|
206
|
+
extensions: infer E;
|
|
207
|
+
} ? E : {};
|
|
208
|
+
/**
|
|
209
|
+
* Type helper to normalize G to GunshiParams
|
|
210
|
+
* @internal
|
|
211
|
+
*/
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Command environment.
|
|
215
|
+
*/
|
|
216
|
+
interface CommandEnvironment<G extends GunshiParamsConstraint = DefaultGunshiParams> {
|
|
217
|
+
/**
|
|
218
|
+
* Current working directory.
|
|
219
|
+
* @see {@link CliOptions.cwd}
|
|
220
|
+
*/
|
|
221
|
+
cwd: string | undefined;
|
|
222
|
+
/**
|
|
223
|
+
* Command name.
|
|
224
|
+
* @see {@link CliOptions.name}
|
|
225
|
+
*/
|
|
226
|
+
name: string | undefined;
|
|
227
|
+
/**
|
|
228
|
+
* Command description.
|
|
229
|
+
* @see {@link CliOptions.description}
|
|
230
|
+
*
|
|
231
|
+
*/
|
|
232
|
+
description: string | undefined;
|
|
233
|
+
/**
|
|
234
|
+
* Command version.
|
|
235
|
+
* @see {@link CliOptions.version}
|
|
236
|
+
*/
|
|
237
|
+
version: string | undefined;
|
|
238
|
+
/**
|
|
239
|
+
* Left margin of the command output.
|
|
240
|
+
* @default 2
|
|
241
|
+
* @see {@link CliOptions.leftMargin}
|
|
242
|
+
*/
|
|
243
|
+
leftMargin: number;
|
|
244
|
+
/**
|
|
245
|
+
* Middle margin of the command output.
|
|
246
|
+
* @default 10
|
|
247
|
+
* @see {@link CliOptions.middleMargin}
|
|
248
|
+
*/
|
|
249
|
+
middleMargin: number;
|
|
250
|
+
/**
|
|
251
|
+
* Whether to display the usage option type.
|
|
252
|
+
* @default false
|
|
253
|
+
* @see {@link CliOptions.usageOptionType}
|
|
254
|
+
*/
|
|
255
|
+
usageOptionType: boolean;
|
|
256
|
+
/**
|
|
257
|
+
* Whether to display the option value.
|
|
258
|
+
* @default true
|
|
259
|
+
* @see {@link CliOptions.usageOptionValue}
|
|
260
|
+
*/
|
|
261
|
+
usageOptionValue: boolean;
|
|
262
|
+
/**
|
|
263
|
+
* Whether to display the command usage.
|
|
264
|
+
* @default false
|
|
265
|
+
* @see {@link CliOptions.usageSilent}
|
|
266
|
+
*/
|
|
267
|
+
usageSilent: boolean;
|
|
268
|
+
/**
|
|
269
|
+
* Sub commands.
|
|
270
|
+
* @see {@link CliOptions.subCommands}
|
|
271
|
+
*/
|
|
272
|
+
subCommands: Map<string, Command<any> | LazyCommand<any>> | undefined;
|
|
273
|
+
/**
|
|
274
|
+
* Render function the command usage.
|
|
275
|
+
*/
|
|
276
|
+
renderUsage: ((ctx: Readonly<CommandContext<G>>) => Promise<string>) | null | undefined;
|
|
277
|
+
/**
|
|
278
|
+
* Render function the header section in the command usage.
|
|
279
|
+
*/
|
|
280
|
+
renderHeader: ((ctx: Readonly<CommandContext<G>>) => Promise<string>) | null | undefined;
|
|
281
|
+
/**
|
|
282
|
+
* Render function the validation errors.
|
|
283
|
+
*/
|
|
284
|
+
renderValidationErrors: ((ctx: Readonly<CommandContext<G>>, error: AggregateError) => Promise<string>) | null | undefined;
|
|
285
|
+
/**
|
|
286
|
+
* Hook that runs before any command execution
|
|
287
|
+
* @see {@link CliOptions.onBeforeCommand}
|
|
288
|
+
*/
|
|
289
|
+
onBeforeCommand: ((ctx: Readonly<CommandContext<G>>) => Awaitable<void>) | undefined;
|
|
290
|
+
/**
|
|
291
|
+
* Hook that runs after successful command execution
|
|
292
|
+
* @see {@link CliOptions.onAfterCommand}
|
|
293
|
+
*/
|
|
294
|
+
onAfterCommand: ((ctx: Readonly<CommandContext<G>>, result: string | void) => Awaitable<void>) | undefined;
|
|
295
|
+
/**
|
|
296
|
+
* Hook that runs when a command throws an error
|
|
297
|
+
* @see {@link CliOptions.onErrorCommand}
|
|
298
|
+
*/
|
|
299
|
+
onErrorCommand: ((ctx: Readonly<CommandContext<G>>, error: Error) => Awaitable<void>) | undefined;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* CLI options of `cli` function.
|
|
303
|
+
*/
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Command call mode.
|
|
307
|
+
*/
|
|
308
|
+
type CommandCallMode = 'entry' | 'subCommand' | 'unexpected';
|
|
309
|
+
/**
|
|
310
|
+
* Command context.
|
|
311
|
+
* Command context is the context of the command execution.
|
|
312
|
+
*/
|
|
313
|
+
interface CommandContext<G extends GunshiParamsConstraint = DefaultGunshiParams> {
|
|
314
|
+
/**
|
|
315
|
+
* Command name, that is the command that is executed.
|
|
316
|
+
* The command name is same {@link CommandEnvironment.name}.
|
|
317
|
+
*/
|
|
318
|
+
name: string | undefined;
|
|
319
|
+
/**
|
|
320
|
+
* Command description, that is the description of the command that is executed.
|
|
321
|
+
* The command description is same {@link CommandEnvironment.description}.
|
|
322
|
+
*/
|
|
323
|
+
description: string | undefined;
|
|
324
|
+
/**
|
|
325
|
+
* Command environment, that is the environment of the command that is executed.
|
|
326
|
+
* The command environment is same {@link CommandEnvironment}.
|
|
327
|
+
*/
|
|
328
|
+
env: Readonly<CommandEnvironment<G>>;
|
|
329
|
+
/**
|
|
330
|
+
* Command arguments, that is the arguments of the command that is executed.
|
|
331
|
+
* The command arguments is same {@link Command.args}.
|
|
332
|
+
*/
|
|
333
|
+
args: ExtractArgs<G>;
|
|
334
|
+
/**
|
|
335
|
+
* Command values, that is the values of the command that is executed.
|
|
336
|
+
* Resolve values with `resolveArgs` from command arguments and {@link Command.args}.
|
|
337
|
+
*/
|
|
338
|
+
values: ArgValues<ExtractArgs<G>>;
|
|
339
|
+
/**
|
|
340
|
+
* Command positionals arguments, that is the positionals of the command that is executed.
|
|
341
|
+
* Resolve positionals with `resolveArgs` from command arguments.
|
|
342
|
+
*/
|
|
343
|
+
positionals: string[];
|
|
344
|
+
/**
|
|
345
|
+
* Command rest arguments, that is the remaining argument not resolved by the optional command option delimiter `--`.
|
|
346
|
+
*/
|
|
347
|
+
rest: string[];
|
|
348
|
+
/**
|
|
349
|
+
* Original command line arguments.
|
|
350
|
+
* This argument is passed from `cli` function.
|
|
351
|
+
*/
|
|
352
|
+
_: string[];
|
|
353
|
+
/**
|
|
354
|
+
* Argument tokens, that is parsed by `parseArgs` function.
|
|
355
|
+
*/
|
|
356
|
+
tokens: ArgToken[];
|
|
357
|
+
/**
|
|
358
|
+
* Whether the currently executing command has been executed with the sub-command name omitted.
|
|
359
|
+
*/
|
|
360
|
+
omitted: boolean;
|
|
361
|
+
/**
|
|
362
|
+
* Command call mode.
|
|
363
|
+
* The command call mode is `entry` when the command is executed as an entry command, and `subCommand` when the command is executed as a sub-command.
|
|
364
|
+
*/
|
|
365
|
+
callMode: CommandCallMode;
|
|
366
|
+
/**
|
|
367
|
+
* Whether to convert the camel-case style argument name to kebab-case.
|
|
368
|
+
* This context value is set from {@link Command.toKebab} option.
|
|
369
|
+
*/
|
|
370
|
+
toKebab?: boolean;
|
|
371
|
+
/**
|
|
372
|
+
* Output a message.
|
|
373
|
+
* If {@link CommandEnvironment.usageSilent} is true, the message is not output.
|
|
374
|
+
* @param message an output message, @see {@link console.log}
|
|
375
|
+
* @param optionalParams an optional parameters, @see {@link console.log}
|
|
376
|
+
* @internal
|
|
377
|
+
*/
|
|
378
|
+
log: (message?: any, ...optionalParams: any[]) => void;
|
|
379
|
+
/**
|
|
380
|
+
* Command context extensions.
|
|
381
|
+
*/
|
|
382
|
+
extensions: keyof ExtractExtensions<G> extends never ? undefined : ExtractExtensions<G>;
|
|
383
|
+
/**
|
|
384
|
+
* Validation error from argument parsing.
|
|
385
|
+
* This will be set if argument validation fails during CLI execution.
|
|
386
|
+
*/
|
|
387
|
+
validationError?: AggregateError;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* CommandContextCore type (base type without extensions)
|
|
391
|
+
*/
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Command interface.
|
|
395
|
+
*/
|
|
396
|
+
interface Command<G extends GunshiParamsConstraint = DefaultGunshiParams> {
|
|
397
|
+
/**
|
|
398
|
+
* Command name.
|
|
399
|
+
* It's used to find command line arguments to execute from sub commands, and it's recommended to specify.
|
|
400
|
+
*/
|
|
401
|
+
name?: string;
|
|
402
|
+
/**
|
|
403
|
+
* Command description.
|
|
404
|
+
* It's used to describe the command in usage and it's recommended to specify.
|
|
405
|
+
*/
|
|
406
|
+
description?: string;
|
|
407
|
+
/**
|
|
408
|
+
* Command arguments.
|
|
409
|
+
* Each argument can include a description property to describe the argument in usage.
|
|
410
|
+
*/
|
|
411
|
+
args?: ExtractArgs<G>;
|
|
412
|
+
/**
|
|
413
|
+
* Command examples.
|
|
414
|
+
* examples of how to use the command.
|
|
415
|
+
*/
|
|
416
|
+
examples?: string | CommandExamplesFetcher<G>;
|
|
417
|
+
/**
|
|
418
|
+
* Command runner. it's the command to be executed
|
|
419
|
+
*/
|
|
420
|
+
run?: CommandRunner<G>;
|
|
421
|
+
/**
|
|
422
|
+
* Whether to convert the camel-case style argument name to kebab-case.
|
|
423
|
+
* If you will set to `true`, All {@link Command.args} names will be converted to kebab-case.
|
|
424
|
+
*/
|
|
425
|
+
toKebab?: boolean;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Lazy command interface.
|
|
429
|
+
* Lazy command that's not loaded until it is executed.
|
|
430
|
+
*/
|
|
431
|
+
type LazyCommand<G extends GunshiParamsConstraint = DefaultGunshiParams> = {
|
|
432
|
+
/**
|
|
433
|
+
* Command load function
|
|
434
|
+
*/
|
|
435
|
+
(): Awaitable<Command<G> | CommandRunner<G>>;
|
|
436
|
+
/**
|
|
437
|
+
* Command name
|
|
438
|
+
*/
|
|
439
|
+
commandName?: string;
|
|
440
|
+
} & Omit<Command<G>, 'run' | 'name'>;
|
|
441
|
+
/**
|
|
442
|
+
* Define a command type.
|
|
443
|
+
*/
|
|
444
|
+
type Commandable<G extends GunshiParamsConstraint = DefaultGunshiParams> = Command<G> | LazyCommand<G>;
|
|
445
|
+
/**
|
|
446
|
+
* Command examples fetcher.
|
|
447
|
+
* @param ctx A {@link CommandContext | command context}
|
|
448
|
+
* @returns A fetched command examples.
|
|
449
|
+
*/
|
|
450
|
+
type CommandExamplesFetcher<G extends GunshiParamsConstraint = DefaultGunshiParams> = (ctx: Readonly<CommandContext<G>>) => Awaitable<string>;
|
|
451
|
+
/**
|
|
452
|
+
* Command runner.
|
|
453
|
+
* @param ctx A {@link CommandContext | command context}
|
|
454
|
+
* @returns void or string (for CLI output)
|
|
455
|
+
*/
|
|
456
|
+
type CommandRunner<G extends GunshiParamsConstraint = DefaultGunshiParams> = (ctx: Readonly<CommandContext<G>>) => Awaitable<void | string>; //#endregion
|
|
457
|
+
//#region ../../node_modules/.pnpm/args-tokens@0.20.1/node_modules/args-tokens/lib/utils.d.ts
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Command loader.
|
|
461
|
+
* A function that returns a command or command runner.
|
|
462
|
+
* This is used to lazily load commands.
|
|
463
|
+
* @returns A command or command runner
|
|
464
|
+
*/
|
|
465
|
+
//#region src/utils.d.ts
|
|
466
|
+
/**
|
|
467
|
+
* Entry point of utils.
|
|
468
|
+
*
|
|
469
|
+
* Note that this entry point is used by gunshi to import utility functions.
|
|
470
|
+
*
|
|
471
|
+
* @module
|
|
472
|
+
*/
|
|
473
|
+
/**
|
|
474
|
+
* @author kazuya kawaguchi (a.k.a. kazupon)
|
|
475
|
+
* @license MIT
|
|
476
|
+
*/
|
|
477
|
+
declare function kebabnize(str: string): string;
|
|
478
|
+
|
|
479
|
+
//#endregion
|
|
480
|
+
//#region ../gunshi/src/utils.d.ts
|
|
481
|
+
//#endregion
|
|
482
|
+
declare function isLazyCommand<G extends GunshiParamsConstraint = DefaultGunshiParams>(cmd: unknown): cmd is LazyCommand<G>;
|
|
483
|
+
declare function resolveLazyCommand<G extends GunshiParamsConstraint = DefaultGunshiParams>(cmd: Commandable<G>, name?: string | undefined, needRunResolving?: boolean): Promise<Command<G>>;
|
|
484
|
+
declare function create<T>(obj?: object | null): T;
|
|
485
|
+
declare function log(...args: unknown[]): void;
|
|
486
|
+
declare function deepFreeze<T extends Record<string, any>>(obj: T, ignores?: string[]): Readonly<T>;
|
|
487
|
+
|
|
488
|
+
//#endregion
|
|
489
|
+
//#region src/constants.d.ts
|
|
490
|
+
declare namespace constants_d_exports {
|
|
491
|
+
export { ARG_NEGATABLE_PREFIX, ARG_PREFIX, ARG_PREFIX_AND_KEY_SEPARATOR, BUILD_IN_PREFIX_AND_KEY_SEPARATOR, BUILT_IN_KEY_SEPARATOR, BUILT_IN_PREFIX, COMMAND_BUILTIN_RESOURCE_KEYS, COMMON_ARGS, PLUGIN_PREFIX };
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* @author kazuya kawaguchi (a.k.a. kazupon)
|
|
495
|
+
* @license MIT
|
|
496
|
+
*/
|
|
497
|
+
declare const BUILT_IN_PREFIX = "_";
|
|
498
|
+
declare const PLUGIN_PREFIX = "g";
|
|
499
|
+
declare const ARG_PREFIX = "arg";
|
|
500
|
+
declare const BUILT_IN_KEY_SEPARATOR = ":";
|
|
501
|
+
declare const BUILD_IN_PREFIX_AND_KEY_SEPARATOR: string;
|
|
502
|
+
declare const ARG_PREFIX_AND_KEY_SEPARATOR: string;
|
|
503
|
+
declare const ARG_NEGATABLE_PREFIX = "no-";
|
|
504
|
+
type CommonArgType = {
|
|
505
|
+
readonly help: {
|
|
506
|
+
readonly type: 'boolean';
|
|
507
|
+
readonly short: 'h';
|
|
508
|
+
readonly description: string;
|
|
509
|
+
};
|
|
510
|
+
readonly version: {
|
|
511
|
+
readonly type: 'boolean';
|
|
512
|
+
readonly short: 'v';
|
|
513
|
+
readonly description: string;
|
|
514
|
+
};
|
|
515
|
+
};
|
|
516
|
+
declare const COMMON_ARGS: CommonArgType;
|
|
517
|
+
declare const COMMAND_BUILTIN_RESOURCE_KEYS: readonly ["USAGE", "COMMAND", "SUBCOMMAND", "COMMANDS", "ARGUMENTS", "OPTIONS", "EXAMPLES", "FORMORE", "NEGATABLE", "DEFAULT", "CHOICES"];
|
|
518
|
+
|
|
519
|
+
//#endregion
|
|
520
|
+
//#region src/types.d.ts
|
|
521
|
+
type RemoveIndexSignature<T> = { [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K] };
|
|
522
|
+
/**
|
|
523
|
+
* Remove index signature from object or record type.
|
|
524
|
+
*/
|
|
525
|
+
type RemovedIndex<T> = RemoveIndexSignature<{ [K in keyof T]: T[K] }>;
|
|
526
|
+
type KeyOfArgs<A extends Args> = keyof A | { [K in keyof A]: A[K]['type'] extends 'boolean' ? A[K]['negatable'] extends true ? `no-${Extract<K, string>}` : never : never }[keyof A];
|
|
527
|
+
/**
|
|
528
|
+
* Generate a namespaced key.
|
|
529
|
+
*/
|
|
530
|
+
type GenerateNamespacedKey<Key extends string, Prefixed extends string = typeof BUILT_IN_PREFIX> = `${Prefixed}${typeof BUILT_IN_KEY_SEPARATOR}${Key}`;
|
|
531
|
+
/**
|
|
532
|
+
* Command i18n built-in arguments keys.
|
|
533
|
+
*/
|
|
534
|
+
type CommandBuiltinArgsKeys = keyof (typeof constants_d_exports)['COMMON_ARGS'];
|
|
535
|
+
/**
|
|
536
|
+
* Command i18n built-in resource keys.
|
|
537
|
+
*/
|
|
538
|
+
type CommandBuiltinResourceKeys = (typeof constants_d_exports)['COMMAND_BUILTIN_RESOURCE_KEYS'][number];
|
|
539
|
+
/**
|
|
540
|
+
* i18n built-in resource keys.
|
|
541
|
+
*/
|
|
542
|
+
type BuiltinResourceKeys = CommandBuiltinArgsKeys | CommandBuiltinResourceKeys;
|
|
543
|
+
/**
|
|
544
|
+
* Command i18n built-in keys.
|
|
545
|
+
* The command i18n built-in keys are used by the i18n plugin for translation.
|
|
546
|
+
*/
|
|
547
|
+
type CommandBuiltinKeys = GenerateNamespacedKey<BuiltinResourceKeys> | 'description' | 'examples';
|
|
548
|
+
/**
|
|
549
|
+
* Command i18n option keys.
|
|
550
|
+
* The command i18n option keys are used by the i18n plugin for translation.
|
|
551
|
+
*/
|
|
552
|
+
type CommandArgKeys<A extends Args> = GenerateNamespacedKey<KeyOfArgs<RemovedIndex<A>>, typeof ARG_PREFIX>;
|
|
553
|
+
|
|
554
|
+
//#endregion
|
|
555
|
+
//#region src/utils.d.ts
|
|
556
|
+
declare function resolveBuiltInKey<K extends string = CommandBuiltinArgsKeys | CommandBuiltinResourceKeys>(key: K): GenerateNamespacedKey<K>;
|
|
557
|
+
declare function resolveArgKey<A extends Args = DefaultGunshiParams['args'], K extends string = KeyOfArgs<RemovedIndex<A>>>(key: K): GenerateNamespacedKey<K, typeof ARG_PREFIX>;
|
|
558
|
+
declare function resolveExamples<G extends GunshiParamsConstraint = DefaultGunshiParams>(ctx: Readonly<CommandContext<G>>, examples?: string | CommandExamplesFetcher<G>): Promise<string>;
|
|
559
|
+
declare function namespacedId<K extends string>(id: K): GenerateNamespacedKey<K, typeof PLUGIN_PREFIX>;
|
|
560
|
+
|
|
561
|
+
//#endregion
|
|
562
|
+
export { ARG_NEGATABLE_PREFIX, ARG_PREFIX, ARG_PREFIX_AND_KEY_SEPARATOR, BUILD_IN_PREFIX_AND_KEY_SEPARATOR, BUILT_IN_KEY_SEPARATOR, BUILT_IN_PREFIX, BuiltinResourceKeys, COMMAND_BUILTIN_RESOURCE_KEYS, COMMON_ARGS, CommandArgKeys, CommandBuiltinArgsKeys, CommandBuiltinKeys, CommandBuiltinResourceKeys, en_US_default as DefaultResource, GenerateNamespacedKey, KeyOfArgs, PLUGIN_PREFIX, RemovedIndex, create, deepFreeze, isLazyCommand, kebabnize, log, namespacedId, resolveArgKey, resolveBuiltInKey, resolveExamples, resolveLazyCommand };
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
//#region ../../node_modules/.pnpm/args-tokens@0.20.1/node_modules/args-tokens/lib/utils-N7UlhLbz.js
|
|
2
|
+
/**
|
|
3
|
+
* Entry point of utils.
|
|
4
|
+
*
|
|
5
|
+
* Note that this entry point is used by gunshi to import utility functions.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* @author kazuya kawaguchi (a.k.a. kazupon)
|
|
11
|
+
* @license MIT
|
|
12
|
+
*/
|
|
13
|
+
function kebabnize(str) {
|
|
14
|
+
return str.replace(/[A-Z]/g, (match, offset) => (offset > 0 ? "-" : "") + match.toLowerCase());
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region ../gunshi/src/utils.ts
|
|
19
|
+
function isLazyCommand(cmd) {
|
|
20
|
+
return typeof cmd === "function" && "commandName" in cmd && !!cmd.commandName;
|
|
21
|
+
}
|
|
22
|
+
async function resolveLazyCommand(cmd, name, needRunResolving = false) {
|
|
23
|
+
let command;
|
|
24
|
+
if (isLazyCommand(cmd)) {
|
|
25
|
+
const baseCommand = {
|
|
26
|
+
name: cmd.commandName,
|
|
27
|
+
description: cmd.description,
|
|
28
|
+
args: cmd.args,
|
|
29
|
+
examples: cmd.examples
|
|
30
|
+
};
|
|
31
|
+
if ("resource" in cmd && cmd.resource) baseCommand.resource = cmd.resource;
|
|
32
|
+
command = Object.assign(create(), baseCommand);
|
|
33
|
+
if (needRunResolving) {
|
|
34
|
+
const loaded = await cmd();
|
|
35
|
+
if (typeof loaded === "function") command.run = loaded;
|
|
36
|
+
else if (typeof loaded === "object") {
|
|
37
|
+
if (loaded.run == null) throw new TypeError(`'run' is required in command: ${cmd.name || name}`);
|
|
38
|
+
command.run = loaded.run;
|
|
39
|
+
command.name = loaded.name;
|
|
40
|
+
command.description = loaded.description;
|
|
41
|
+
command.args = loaded.args;
|
|
42
|
+
command.examples = loaded.examples;
|
|
43
|
+
if ("resource" in loaded && loaded.resource) command.resource = loaded.resource;
|
|
44
|
+
} else throw new TypeError(`Cannot resolve command: ${cmd.name || name}`);
|
|
45
|
+
}
|
|
46
|
+
} else command = Object.assign(create(), cmd);
|
|
47
|
+
if (command.name == null && name) command.name = name;
|
|
48
|
+
return deepFreeze(command);
|
|
49
|
+
}
|
|
50
|
+
function create(obj = null) {
|
|
51
|
+
return Object.create(obj);
|
|
52
|
+
}
|
|
53
|
+
function log(...args) {
|
|
54
|
+
console.log(...args);
|
|
55
|
+
}
|
|
56
|
+
function deepFreeze(obj, ignores = []) {
|
|
57
|
+
if (obj === null || typeof obj !== "object") return obj;
|
|
58
|
+
for (const key of Object.keys(obj)) {
|
|
59
|
+
const value = obj[key];
|
|
60
|
+
if (ignores.includes(key)) continue;
|
|
61
|
+
if (typeof value === "object" && value !== null) deepFreeze(value, ignores);
|
|
62
|
+
}
|
|
63
|
+
return Object.freeze(obj);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/constants.ts
|
|
68
|
+
/**
|
|
69
|
+
* @author kazuya kawaguchi (a.k.a. kazupon)
|
|
70
|
+
* @license MIT
|
|
71
|
+
*/
|
|
72
|
+
const BUILT_IN_PREFIX = "_";
|
|
73
|
+
const PLUGIN_PREFIX = "g";
|
|
74
|
+
const ARG_PREFIX = "arg";
|
|
75
|
+
const BUILT_IN_KEY_SEPARATOR = ":";
|
|
76
|
+
const BUILD_IN_PREFIX_AND_KEY_SEPARATOR = `${BUILT_IN_PREFIX}${BUILT_IN_KEY_SEPARATOR}`;
|
|
77
|
+
const ARG_PREFIX_AND_KEY_SEPARATOR = `${ARG_PREFIX}${BUILT_IN_KEY_SEPARATOR}`;
|
|
78
|
+
const ARG_NEGATABLE_PREFIX = "no-";
|
|
79
|
+
const COMMON_ARGS = {
|
|
80
|
+
help: {
|
|
81
|
+
type: "boolean",
|
|
82
|
+
short: "h",
|
|
83
|
+
description: "Display this help message"
|
|
84
|
+
},
|
|
85
|
+
version: {
|
|
86
|
+
type: "boolean",
|
|
87
|
+
short: "v",
|
|
88
|
+
description: "Display this version"
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const COMMAND_BUILTIN_RESOURCE_KEYS = [
|
|
92
|
+
"USAGE",
|
|
93
|
+
"COMMAND",
|
|
94
|
+
"SUBCOMMAND",
|
|
95
|
+
"COMMANDS",
|
|
96
|
+
"ARGUMENTS",
|
|
97
|
+
"OPTIONS",
|
|
98
|
+
"EXAMPLES",
|
|
99
|
+
"FORMORE",
|
|
100
|
+
"NEGATABLE",
|
|
101
|
+
"DEFAULT",
|
|
102
|
+
"CHOICES"
|
|
103
|
+
];
|
|
104
|
+
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region ../resources/locales/en-US.json
|
|
107
|
+
var COMMAND = "COMMAND";
|
|
108
|
+
var COMMANDS = "COMMANDS";
|
|
109
|
+
var SUBCOMMAND = "SUBCOMMAND";
|
|
110
|
+
var USAGE = "USAGE";
|
|
111
|
+
var ARGUMENTS = "ARGUMENTS";
|
|
112
|
+
var OPTIONS = "OPTIONS";
|
|
113
|
+
var EXAMPLES = "EXAMPLES";
|
|
114
|
+
var FORMORE = "For more info, run any command with the `--help` flag";
|
|
115
|
+
var NEGATABLE = "Negatable of";
|
|
116
|
+
var DEFAULT = "default";
|
|
117
|
+
var CHOICES = "choices";
|
|
118
|
+
var help = "Display this help message";
|
|
119
|
+
var version = "Display this version";
|
|
120
|
+
var en_US_default = {
|
|
121
|
+
COMMAND,
|
|
122
|
+
COMMANDS,
|
|
123
|
+
SUBCOMMAND,
|
|
124
|
+
USAGE,
|
|
125
|
+
ARGUMENTS,
|
|
126
|
+
OPTIONS,
|
|
127
|
+
EXAMPLES,
|
|
128
|
+
FORMORE,
|
|
129
|
+
NEGATABLE,
|
|
130
|
+
DEFAULT,
|
|
131
|
+
CHOICES,
|
|
132
|
+
help,
|
|
133
|
+
version
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
//#endregion
|
|
137
|
+
//#region src/utils.ts
|
|
138
|
+
function resolveBuiltInKey(key) {
|
|
139
|
+
return `${BUILT_IN_PREFIX}${BUILT_IN_KEY_SEPARATOR}${key}`;
|
|
140
|
+
}
|
|
141
|
+
function resolveArgKey(key) {
|
|
142
|
+
return `${ARG_PREFIX}${BUILT_IN_KEY_SEPARATOR}${key}`;
|
|
143
|
+
}
|
|
144
|
+
async function resolveExamples(ctx, examples) {
|
|
145
|
+
return typeof examples === "string" ? examples : typeof examples === "function" ? await examples(ctx) : "";
|
|
146
|
+
}
|
|
147
|
+
function namespacedId(id) {
|
|
148
|
+
return `${PLUGIN_PREFIX}${BUILT_IN_KEY_SEPARATOR}${id}`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
//#endregion
|
|
152
|
+
export { ARG_NEGATABLE_PREFIX, ARG_PREFIX, ARG_PREFIX_AND_KEY_SEPARATOR, BUILD_IN_PREFIX_AND_KEY_SEPARATOR, BUILT_IN_KEY_SEPARATOR, BUILT_IN_PREFIX, COMMAND_BUILTIN_RESOURCE_KEYS, COMMON_ARGS, en_US_default as DefaultResource, PLUGIN_PREFIX, create, deepFreeze, isLazyCommand, kebabnize, log, namespacedId, resolveArgKey, resolveBuiltInKey, resolveExamples, resolveLazyCommand };
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gunshi/shared",
|
|
3
|
+
"description": "shared utils for gunshi",
|
|
4
|
+
"version": "0.26.3",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "kazuya kawaguchi",
|
|
7
|
+
"email": "kawakazu80@gmail.com"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"funding": "https://github.com/sponsors/kazupon",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/kazupon/gunshi/issues"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/kazupon/gunshi.git",
|
|
17
|
+
"directory": "packages/shared"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"gunshi",
|
|
21
|
+
"cli"
|
|
22
|
+
],
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">= 20"
|
|
28
|
+
},
|
|
29
|
+
"type": "module",
|
|
30
|
+
"files": [
|
|
31
|
+
"lib"
|
|
32
|
+
],
|
|
33
|
+
"module": "lib/index.js",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./lib/index.d.ts",
|
|
37
|
+
"import": "./lib/index.js",
|
|
38
|
+
"require": "./lib/index.js",
|
|
39
|
+
"default": "./lib/index.js"
|
|
40
|
+
},
|
|
41
|
+
"./package.json": "./package.json"
|
|
42
|
+
},
|
|
43
|
+
"types": "lib/index.d.ts",
|
|
44
|
+
"typesVersions": {
|
|
45
|
+
"*": {
|
|
46
|
+
"*": [
|
|
47
|
+
"./lib/*",
|
|
48
|
+
"./*"
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"deno": "^2.3.3",
|
|
54
|
+
"jsr": "^0.13.4",
|
|
55
|
+
"jsr-exports-lint": "^0.4.1",
|
|
56
|
+
"publint": "^0.3.12",
|
|
57
|
+
"tsdown": "^0.12.3",
|
|
58
|
+
"gunshi": "0.26.3",
|
|
59
|
+
"@gunshi/resources": "0.26.3"
|
|
60
|
+
},
|
|
61
|
+
"scripts": {
|
|
62
|
+
"build": "tsdown",
|
|
63
|
+
"lint:jsr": "jsr publish --dry-run --allow-dirty",
|
|
64
|
+
"typecheck:deno": "deno check --import-map=../../importmap.json ./src"
|
|
65
|
+
}
|
|
66
|
+
}
|