@clerc/core 1.0.0-beta.3 → 1.0.0-beta.30
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/index.d.ts +156 -65
- package/dist/index.js +85 -40
- package/package.json +6 -9
package/dist/index.d.ts
CHANGED
|
@@ -1,22 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* Creates a Choices type function that validates the input against allowed values.
|
|
7
|
-
* The display name will be formatted as "value1 | value2 | ..." for help output.
|
|
8
|
-
*
|
|
9
|
-
* @param values - Array of allowed string values
|
|
10
|
-
* @returns A FlagTypeFunction that validates and returns the input value
|
|
11
|
-
* @throws {Error} If the value is not in the allowed values list
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```typescript
|
|
15
|
-
* const format = Choices(['json', 'yaml', 'xml']);
|
|
16
|
-
* // Help output will show: json | yaml | xml
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
declare function Choices<T extends string>(...values: T[]): FlagTypeFunction<T>;
|
|
1
|
+
//#endregion
|
|
2
|
+
//#region ../parser/src/errors.d.ts
|
|
3
|
+
declare class InvalidSchemaError extends Error {
|
|
4
|
+
constructor(message: string);
|
|
5
|
+
}
|
|
20
6
|
//#endregion
|
|
21
7
|
//#region ../utils/src/types/type-fest.d.ts
|
|
22
8
|
type LiteralUnion<LiteralType, BaseType> = LiteralType | (BaseType & Record<never, never>);
|
|
@@ -29,6 +15,7 @@ type MapsSetsOrArrays = ReadonlyMap<unknown, unknown> | WeakMap<WeakKey, unknown
|
|
|
29
15
|
type ConditionalDeepPrettify<T, E = never, I$1 = unknown> = T extends E ? T : T extends I$1 ? { [TypeKey in keyof T]: ConditionalDeepPrettify<T[TypeKey], E, I$1> } : T;
|
|
30
16
|
type DeepPrettify<T, E = never> = ConditionalDeepPrettify<T, E | NonRecursiveType | MapsSetsOrArrays, object>;
|
|
31
17
|
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
18
|
+
type RequireExactlyOneOrNone<T, Keys extends keyof T = keyof T> = ({ [K in Keys]-?: Required<Pick<T, K>> & Partial<Record<Exclude<Keys, K>, never>> }[Keys] & Omit<T, Keys>) | (Partial<Record<Keys, never>> & Omit<T, Keys>);
|
|
32
19
|
//#endregion
|
|
33
20
|
//#region ../utils/src/types/index.d.ts
|
|
34
21
|
type MaybeArray<T> = T | T[];
|
|
@@ -37,19 +24,24 @@ type UnionToIntersection<U$1> = (U$1 extends any ? (k: U$1) => void : never) ext
|
|
|
37
24
|
type CamelCase<S extends string> = S extends `${infer Head} ${infer Tail}` ? `${Head}${Capitalize<CamelCase<Tail>>}` : S extends `${infer Head}-${infer Tail}` ? `${Head}${Capitalize<CamelCase<Tail>>}` : S;
|
|
38
25
|
//#endregion
|
|
39
26
|
//#region ../parser/src/types.d.ts
|
|
40
|
-
|
|
27
|
+
interface FlagDefaultValueFunction<T> {
|
|
28
|
+
(): T;
|
|
29
|
+
display?: string;
|
|
30
|
+
}
|
|
31
|
+
type FlagDefaultValue<T = unknown> = T | FlagDefaultValueFunction<T>;
|
|
41
32
|
/**
|
|
42
33
|
* Defines how a string input is converted to the target type T.
|
|
43
34
|
*
|
|
44
35
|
* @template T The target type.
|
|
45
36
|
*/
|
|
46
|
-
|
|
37
|
+
interface TypeFunction<T = unknown> {
|
|
38
|
+
(value: string): T;
|
|
47
39
|
/**
|
|
48
40
|
* Optional display name for the type, useful in help output.
|
|
49
41
|
* If provided, this will be shown instead of the function name.
|
|
50
42
|
*/
|
|
51
|
-
|
|
52
|
-
}
|
|
43
|
+
display?: string;
|
|
44
|
+
}
|
|
53
45
|
/**
|
|
54
46
|
* A callback function to conditionally stop parsing.
|
|
55
47
|
* When it returns true, parsing stops and remaining arguments are preserved in `ignored`.
|
|
@@ -59,19 +51,23 @@ type FlagTypeFunction<T = unknown> = ((value: string) => T) & {
|
|
|
59
51
|
* @returns true to stop parsing, false to continue
|
|
60
52
|
*/
|
|
61
53
|
type IgnoreFunction = (type: typeof KNOWN_FLAG | typeof UNKNOWN_FLAG | typeof PARAMETER, arg: string) => boolean;
|
|
62
|
-
type
|
|
63
|
-
|
|
54
|
+
type TypeValue<T = unknown> = TypeFunction<T> | readonly [TypeFunction<T>];
|
|
55
|
+
type FlagRequiredOrDefault = RequireExactlyOneOrNone<{
|
|
56
|
+
/** The default value of the flag. */
|
|
57
|
+
default?: unknown;
|
|
58
|
+
/** Whether the flag is required. */
|
|
59
|
+
required?: boolean;
|
|
60
|
+
}, "default" | "required">;
|
|
61
|
+
type BaseFlagOptions<T extends TypeValue = TypeValue> = FlagRequiredOrDefault & {
|
|
64
62
|
/**
|
|
65
63
|
* The type constructor or a function to convert the string value.
|
|
66
64
|
* To support multiple occurrences of a flag (e.g., --file a --file b), wrap the type in an array: [String], [Number].
|
|
67
65
|
* e.g., String, Number, [String], (val) => val.split(',')
|
|
68
66
|
*/
|
|
69
67
|
type: T;
|
|
70
|
-
/**
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
default?: unknown;
|
|
74
|
-
}
|
|
68
|
+
/** Short flag alias (single character). */
|
|
69
|
+
short?: string;
|
|
70
|
+
};
|
|
75
71
|
type FlagOptions = (BaseFlagOptions<BooleanConstructor> & {
|
|
76
72
|
/**
|
|
77
73
|
* Whether to enable the `--no-<flag>` syntax to set the value to false.
|
|
@@ -84,8 +80,30 @@ type FlagOptions = (BaseFlagOptions<BooleanConstructor> & {
|
|
|
84
80
|
}) | (BaseFlagOptions & {
|
|
85
81
|
negatable?: never;
|
|
86
82
|
});
|
|
87
|
-
type FlagDefinitionValue = FlagOptions |
|
|
83
|
+
type FlagDefinitionValue = FlagOptions | TypeValue;
|
|
88
84
|
type FlagsDefinition = Record<string, FlagDefinitionValue>;
|
|
85
|
+
/**
|
|
86
|
+
* Configuration options for the parser.
|
|
87
|
+
*/
|
|
88
|
+
interface ParserOptions<T extends FlagsDefinition = {}> {
|
|
89
|
+
/**
|
|
90
|
+
* Detailed configuration for flags.
|
|
91
|
+
* Supports the full object syntax or a type constructor as a shorthand.
|
|
92
|
+
* The key is the flag name (e.g., "file" for "--file").
|
|
93
|
+
*/
|
|
94
|
+
flags?: T;
|
|
95
|
+
/**
|
|
96
|
+
* Delimiters to split flag names and values.
|
|
97
|
+
*
|
|
98
|
+
* @default ['=', ':']
|
|
99
|
+
*/
|
|
100
|
+
delimiters?: string[];
|
|
101
|
+
/**
|
|
102
|
+
* A callback function to conditionally stop parsing.
|
|
103
|
+
* When it returns true, parsing stops and remaining arguments are preserved in `ignored`.
|
|
104
|
+
*/
|
|
105
|
+
ignore?: IgnoreFunction;
|
|
106
|
+
}
|
|
89
107
|
type RawInputType = string | boolean;
|
|
90
108
|
interface ObjectInputType {
|
|
91
109
|
[key: string]: RawInputType | ObjectInputType;
|
|
@@ -110,6 +128,8 @@ interface ParsedResult<TFlags extends Record<string, any>> {
|
|
|
110
128
|
unknown: Record<string, RawInputType>;
|
|
111
129
|
/** Arguments that were not parsed due to ignore callback. */
|
|
112
130
|
ignored: string[];
|
|
131
|
+
/** List of required flags that were not provided. */
|
|
132
|
+
missingRequiredFlags: string[];
|
|
113
133
|
}
|
|
114
134
|
type InferFlagDefault<T extends FlagDefinitionValue, Fallback> = T extends {
|
|
115
135
|
default: FlagDefaultValue<infer DefaultType>;
|
|
@@ -119,13 +139,15 @@ type IsTypeAny<T extends FlagDefinitionValue> = IsAny<T> extends true ? true : T
|
|
|
119
139
|
} ? IsAny<Type> extends true ? true : false : false;
|
|
120
140
|
type _InferFlags<T extends FlagsDefinition> = { [K in keyof T]: IsTypeAny<T[K]> extends true ? any : T[K] extends readonly [BooleanConstructor] | {
|
|
121
141
|
type: readonly [BooleanConstructor];
|
|
122
|
-
} ? number : T[K] extends ObjectConstructor | {
|
|
142
|
+
} ? number | InferFlagDefault<T[K], never> : T[K] extends ObjectConstructor | {
|
|
123
143
|
type: ObjectConstructor;
|
|
124
|
-
} ? ObjectInputType : T[K] extends readonly [
|
|
125
|
-
type: readonly [
|
|
126
|
-
} ? U[] | InferFlagDefault<T[K], never> : T[K] extends
|
|
127
|
-
type:
|
|
128
|
-
} ? U | InferFlagDefault<T[K], [U] extends [boolean] ? never :
|
|
144
|
+
} ? ObjectInputType | InferFlagDefault<T[K], never> : T[K] extends readonly [TypeValue<infer U>] | {
|
|
145
|
+
type: readonly [TypeValue<infer U>];
|
|
146
|
+
} ? U[] | InferFlagDefault<T[K], never> : T[K] extends TypeValue<infer U> | {
|
|
147
|
+
type: TypeValue<infer U>;
|
|
148
|
+
} ? U | InferFlagDefault<T[K], [U] extends [boolean] ? never : T[K] extends {
|
|
149
|
+
required: true;
|
|
150
|
+
} ? never : undefined> : never };
|
|
129
151
|
/**
|
|
130
152
|
* An advanced utility type that infers the exact type of the `flags` object in the parsed result,
|
|
131
153
|
* based on the provided `flags` configuration object T.
|
|
@@ -141,40 +163,95 @@ declare const PARAMETER = "parameter";
|
|
|
141
163
|
//#endregion
|
|
142
164
|
//#region ../parser/src/parse.d.ts
|
|
143
165
|
declare const DOUBLE_DASH = "--";
|
|
166
|
+
type ParseFunction<T extends FlagsDefinition> = (args: string[]) => ParsedResult<InferFlags<T>>;
|
|
167
|
+
declare function createParser<T extends FlagsDefinition>(options?: ParserOptions<T>): {
|
|
168
|
+
parse: ParseFunction<T>;
|
|
169
|
+
};
|
|
170
|
+
declare const parse: <T extends FlagsDefinition>(args: string[], options?: ParserOptions<T>) => ParsedResult<InferFlags<T>>;
|
|
171
|
+
declare namespace index_d_exports {
|
|
172
|
+
export { BaseFlagOptions, DOUBLE_DASH, FlagDefaultValue, FlagDefaultValueFunction, FlagDefinitionValue, FlagOptions, FlagsDefinition, IgnoreFunction, InferFlags, InvalidSchemaError, KNOWN_FLAG, ObjectInputType, PARAMETER, ParsedResult, ParserOptions, RawInputType, TypeFunction, TypeValue, UNKNOWN_FLAG, createParser, parse };
|
|
173
|
+
}
|
|
174
|
+
//#endregion
|
|
175
|
+
//#region ../advanced-types/src/errors.d.ts
|
|
176
|
+
declare class FlagValidationError extends Error {}
|
|
177
|
+
declare namespace index_d_exports$1 {
|
|
178
|
+
export { Enum, FlagValidationError, Range, Regex };
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Creates a Enum type function that validates the input against allowed values.
|
|
182
|
+
* The display name will be formatted as "value1 | value2 | ..." for help output.
|
|
183
|
+
*
|
|
184
|
+
* @param values - Array of allowed string values
|
|
185
|
+
* @returns A TypeFunction that validates and returns the input value
|
|
186
|
+
* @throws {Error} If the value is not in the allowed values list
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```typescript
|
|
190
|
+
* const format = Enum(['json', 'yaml', 'xml']);
|
|
191
|
+
* // Help output will show: json | yaml | xml
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
declare function Enum<T extends string>(...values: T[]): TypeFunction<T>;
|
|
195
|
+
/**
|
|
196
|
+
* Creates a range type function that validates the input is a number within the specified range.
|
|
197
|
+
*
|
|
198
|
+
* @param min - The minimum acceptable value (inclusive)
|
|
199
|
+
* @param max - The maximum acceptable value (inclusive)
|
|
200
|
+
* @returns A TypeFunction that validates the input value
|
|
201
|
+
* @throws {Error} If the value is not a number or is outside the specified range
|
|
202
|
+
*/
|
|
203
|
+
declare function Range(min: number, max: number): TypeFunction<number>;
|
|
204
|
+
/**
|
|
205
|
+
* Creates a regex type function that validates the input against the provided pattern.
|
|
206
|
+
*
|
|
207
|
+
* @param pattern - The regular expression pattern to validate against
|
|
208
|
+
* @param description - Optional description for display purposes
|
|
209
|
+
* @returns A TypeFunction that validates the input value
|
|
210
|
+
* @throws {Error} If the value does not match the regex pattern
|
|
211
|
+
*/
|
|
212
|
+
declare function Regex(pattern: RegExp, description?: string): TypeFunction<string>;
|
|
144
213
|
//#endregion
|
|
145
214
|
//#region src/types/clerc.d.ts
|
|
146
215
|
type ErrorHandler = (error: unknown) => void;
|
|
147
216
|
//#endregion
|
|
148
217
|
//#region src/types/flag.d.ts
|
|
149
218
|
interface FlagCustomOptions {}
|
|
150
|
-
type ClercFlagOptions = FlagOptions &
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
type ClercFlagsDefinition = Record<string, ClercFlagOptionsWithDescription>;
|
|
219
|
+
type ClercFlagOptions = FlagOptions & {
|
|
220
|
+
description?: string;
|
|
221
|
+
} & FlagCustomOptions;
|
|
222
|
+
type ClercFlagDefinitionValue = ClercFlagOptions | TypeValue;
|
|
223
|
+
type ClercFlagsDefinition = Record<string, ClercFlagDefinitionValue>;
|
|
156
224
|
//#endregion
|
|
157
|
-
//#region src/types/
|
|
158
|
-
|
|
159
|
-
type
|
|
225
|
+
//#region src/types/parameter.d.ts
|
|
226
|
+
interface ParameterCustomOptions {}
|
|
227
|
+
type InferStringParameter<T extends string, Type$1 = string> = T extends `<${infer Name extends string}...>` | `[${infer Name extends string}...]` ? Record<CamelCase<Name>, Type$1[]> : T extends `<${infer Name extends string}>` ? Record<CamelCase<Name>, Type$1> : T extends `[${infer Name extends string}]` ? Record<CamelCase<Name>, Type$1 | undefined> : never;
|
|
228
|
+
type InferParameter<T extends ParameterDefinitionValue> = T extends string ? InferStringParameter<T> : T extends ParameterOptions ? T["type"] extends TypeFunction<infer U> ? InferStringParameter<T["key"], U> : InferStringParameter<T["key"]> : never;
|
|
229
|
+
type InferParameters<T extends readonly ParameterDefinitionValue[]> = T extends readonly (infer U extends ParameterDefinitionValue)[] ? Prettify<UnionToIntersection<InferParameter<U>>> : never;
|
|
230
|
+
type ParameterOptions = {
|
|
231
|
+
key: string;
|
|
232
|
+
description?: string;
|
|
233
|
+
type?: TypeFunction;
|
|
234
|
+
} & ParameterCustomOptions;
|
|
235
|
+
type ParameterDefinitionValue = string | ParameterOptions;
|
|
160
236
|
//#endregion
|
|
161
237
|
//#region src/types/context.d.ts
|
|
162
238
|
type AddStringIndex<T> = T & Record<string, any>;
|
|
163
|
-
type
|
|
239
|
+
type KnownKeys<T> = string extends keyof T ? never : keyof T;
|
|
240
|
+
type InferFlagsWithGlobal<C extends Command, GF extends ClercFlagsDefinition> = AddStringIndex<InferFlags<NonNullable<C["flags"]> & Omit<GF, KnownKeys<NonNullable<C["flags"]>>>>>;
|
|
241
|
+
interface ContextStore {}
|
|
164
242
|
interface BaseContext<C extends Command = Command, GF extends ClercFlagsDefinition = {}> {
|
|
165
|
-
resolved: boolean;
|
|
166
243
|
command?: C;
|
|
167
244
|
calledAs?: string;
|
|
168
245
|
parameters: InferParameters<NonNullable<C["parameters"]>>;
|
|
169
246
|
flags: InferFlagsWithGlobal<C, GF>;
|
|
170
247
|
ignored: string[];
|
|
171
248
|
rawParsed: ParsedResult<InferFlagsWithGlobal<C, GF>>;
|
|
172
|
-
|
|
249
|
+
store: Partial<ContextStore>;
|
|
173
250
|
}
|
|
174
251
|
//#endregion
|
|
175
252
|
//#region src/types/command.d.ts
|
|
176
253
|
interface CommandCustomOptions {}
|
|
177
|
-
interface CommandOptions<Parameters extends
|
|
254
|
+
interface CommandOptions<Parameters extends readonly ParameterDefinitionValue[] = readonly ParameterDefinitionValue[], Flags extends ClercFlagsDefinition = ClercFlagsDefinition> extends CommandCustomOptions {
|
|
178
255
|
alias?: MaybeArray<string>;
|
|
179
256
|
parameters?: Parameters;
|
|
180
257
|
flags?: Flags;
|
|
@@ -183,11 +260,11 @@ interface CommandOptions<Parameters extends string[] = string[], Flags extends C
|
|
|
183
260
|
*/
|
|
184
261
|
ignore?: IgnoreFunction;
|
|
185
262
|
}
|
|
186
|
-
interface Command<Name$1 extends string = string, Parameters extends
|
|
263
|
+
interface Command<Name$1 extends string = string, Parameters extends readonly ParameterDefinitionValue[] = readonly ParameterDefinitionValue[], Flags extends ClercFlagsDefinition = ClercFlagsDefinition> extends CommandOptions<Parameters, Flags> {
|
|
187
264
|
name: Name$1;
|
|
188
|
-
description
|
|
265
|
+
description?: string;
|
|
189
266
|
}
|
|
190
|
-
type CommandWithHandler<Name$1 extends string = string, Parameters extends
|
|
267
|
+
type CommandWithHandler<Name$1 extends string = string, Parameters extends readonly ParameterDefinitionValue[] = readonly ParameterDefinitionValue[], Flags extends ClercFlagsDefinition = ClercFlagsDefinition> = Command<Name$1, Parameters, Flags> & {
|
|
191
268
|
handler?: CommandHandler<Command<Name$1, Parameters, Flags>>;
|
|
192
269
|
};
|
|
193
270
|
type CommandsRecord = Record<string, Command>;
|
|
@@ -237,23 +314,26 @@ declare class Clerc<Commands extends CommandsRecord = {}, GlobalFlags extends Cl
|
|
|
237
314
|
get _version(): string;
|
|
238
315
|
get _commands(): CommandsMap;
|
|
239
316
|
get _globalFlags(): GlobalFlags;
|
|
317
|
+
get store(): Partial<ContextStore>;
|
|
240
318
|
static create(options?: CreateOptions): Clerc;
|
|
241
319
|
name(name: string): this;
|
|
242
320
|
scriptName(scriptName: string): this;
|
|
243
321
|
description(description: string): this;
|
|
244
322
|
version(version: string): this;
|
|
245
323
|
use(plugin: Plugin): this;
|
|
246
|
-
errorHandler(handler: ErrorHandler
|
|
247
|
-
command<Name$1 extends string, Parameters extends
|
|
248
|
-
command<Name$1 extends string, Parameters extends
|
|
249
|
-
|
|
324
|
+
errorHandler(handler: ErrorHandler): this;
|
|
325
|
+
command<Name$1 extends string, const Parameters extends readonly ParameterDefinitionValue[], Flags extends ClercFlagsDefinition>(command: CommandWithHandler<Name$1, Parameters, Flags>): Clerc<Commands & Record<string, CommandWithHandler<Name$1, Parameters, Flags>>, GlobalFlags>;
|
|
326
|
+
command<Name$1 extends string, const Parameters extends readonly ParameterDefinitionValue[], Flags extends ClercFlagsDefinition>(name: Name$1 extends keyof Commands ? ["COMMAND ALREADY EXISTS"] : Name$1, options?: CommandOptions<Parameters, Flags>): Clerc<Commands & Record<Name$1, Command<Name$1, Parameters, Flags>>, GlobalFlags>;
|
|
327
|
+
command<Name$1 extends string, const Parameters extends readonly ParameterDefinitionValue[], Flags extends ClercFlagsDefinition>(name: Name$1 extends keyof Commands ? ["COMMAND ALREADY EXISTS"] : Name$1, description: string, options?: CommandOptions<Parameters, Flags>): Clerc<Commands & Record<Name$1, Command<Name$1, Parameters, Flags>>, GlobalFlags>;
|
|
328
|
+
globalFlag<Name$1 extends string, Flag extends ClercFlagDefinitionValue>(name: Name$1, description: string, options: Flag): Clerc<Commands, GlobalFlags & Record<Name$1, Flag>>;
|
|
329
|
+
globalFlag<Name$1 extends string, Flag extends ClercFlagDefinitionValue>(name: Name$1, options: Flag): Clerc<Commands, GlobalFlags & Record<Name$1, Flag>>;
|
|
250
330
|
interceptor(interceptor: Interceptor<Command, GlobalFlags>): this;
|
|
251
331
|
on<Name$1 extends LiteralUnion<keyof Commands, string>>(name: Name$1, handler: CommandHandler<Commands[Name$1], GlobalFlags>): this;
|
|
252
332
|
run(): Promise<void>;
|
|
253
333
|
parse<Run extends boolean = true>(argvOrOptions?: string[] | ParseOptions<Run>): Run extends true ? Promise<void> : this;
|
|
254
334
|
}
|
|
255
335
|
//#endregion
|
|
256
|
-
//#region src/
|
|
336
|
+
//#region src/command.d.ts
|
|
257
337
|
declare function resolveCommand(commandsMap: CommandsMap, parameters: string[]): [Command, string] | [undefined, undefined];
|
|
258
338
|
//#endregion
|
|
259
339
|
//#region src/errors.d.ts
|
|
@@ -264,23 +344,34 @@ declare class NoSuchCommandError extends Error {
|
|
|
264
344
|
declare class NoCommandSpecifiedError extends Error {
|
|
265
345
|
constructor(text?: string);
|
|
266
346
|
}
|
|
267
|
-
declare class InvalidCommandError extends Error {
|
|
268
|
-
constructor(message: string);
|
|
269
|
-
}
|
|
347
|
+
declare class InvalidCommandError extends Error {}
|
|
270
348
|
declare class MissingRequiredMetadataError extends Error {
|
|
271
349
|
constructor(metadataName: string);
|
|
272
350
|
}
|
|
273
|
-
declare class InvalidParametersError extends Error {
|
|
274
|
-
|
|
351
|
+
declare class InvalidParametersError extends Error {}
|
|
352
|
+
declare class MissingRequiredFlagError extends Error {
|
|
353
|
+
constructor(flags: string[]);
|
|
275
354
|
}
|
|
276
355
|
//#endregion
|
|
277
356
|
//#region src/helpers.d.ts
|
|
278
|
-
declare const defineCommand: <Name$1 extends string, Parameters extends
|
|
357
|
+
declare const defineCommand: <Name$1 extends string, const Parameters extends readonly ParameterDefinitionValue[], Flags extends ClercFlagsDefinition>(command: Command<Name$1, Parameters, Flags>, handler?: NoInfer<CommandHandler<Command<Name$1, Parameters, Flags>>>) => CommandWithHandler<Name$1, Parameters, Flags>;
|
|
279
358
|
//#endregion
|
|
280
359
|
//#region src/ignore.d.ts
|
|
281
360
|
declare function createStopAtFirstParameter(): IgnoreFunction;
|
|
282
361
|
//#endregion
|
|
362
|
+
//#region src/parameter.d.ts
|
|
363
|
+
interface ParameterInfo {
|
|
364
|
+
name: string;
|
|
365
|
+
isRequired: boolean;
|
|
366
|
+
isVariadic: boolean;
|
|
367
|
+
}
|
|
368
|
+
declare function extractParameterInfo(key: string): ParameterInfo;
|
|
369
|
+
//#endregion
|
|
283
370
|
//#region src/plugin.d.ts
|
|
284
371
|
declare const definePlugin: (plugin: Plugin) => Plugin;
|
|
285
372
|
//#endregion
|
|
286
|
-
|
|
373
|
+
//#region src/utils.d.ts
|
|
374
|
+
declare const normalizeFlagValue: (flag: ClercFlagDefinitionValue) => ClercFlagOptions;
|
|
375
|
+
declare const normalizeParameterValue: (parameter: ParameterDefinitionValue) => ParameterOptions;
|
|
376
|
+
//#endregion
|
|
377
|
+
export { BaseContext, Clerc, ClercFlagDefinitionValue, ClercFlagOptions, ClercFlagsDefinition, Command, CommandCustomOptions, CommandHandler, CommandHandlerContext, CommandOptions, CommandWithHandler, CommandsMap, CommandsRecord, ContextStore, type CreateOptions, DOUBLE_DASH, ErrorHandler, FlagCustomOptions, InferParameters, Interceptor, InterceptorContext, InterceptorHandler, InterceptorNext, InterceptorObject, InvalidCommandError, InvalidParametersError, InvalidSchemaError, KNOWN_FLAG, MakeEmitterEvents, MissingRequiredFlagError, MissingRequiredMetadataError, NoCommandSpecifiedError, NoSuchCommandError, PARAMETER, ParameterCustomOptions, ParameterDefinitionValue, ParameterOptions, type ParseOptions, type index_d_exports as Parser, Plugin, index_d_exports$1 as Types, UNKNOWN_FLAG, createStopAtFirstParameter, defineCommand, definePlugin, extractParameterInfo, normalizeFlagValue, normalizeParameterValue, resolveCommand };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import * as Types from "@clerc/advanced-types";
|
|
2
|
+
import { DOUBLE_DASH, DOUBLE_DASH as DOUBLE_DASH$1, InvalidSchemaError, KNOWN_FLAG, PARAMETER, PARAMETER as PARAMETER$1, UNKNOWN_FLAG, parse } from "@clerc/parser";
|
|
3
3
|
import { LiteEmit } from "lite-emit";
|
|
4
4
|
|
|
5
|
-
//#region src/
|
|
5
|
+
//#region ../utils/src/index.ts
|
|
6
|
+
const looseIsArray = (arr) => Array.isArray(arr);
|
|
7
|
+
const toArray = (a) => Array.isArray(a) ? a : [a];
|
|
8
|
+
/**
|
|
9
|
+
* Converts a dash- or space-separated string to camelCase.
|
|
10
|
+
* Not using regexp for better performance, because this function is used in parser.
|
|
11
|
+
*/
|
|
12
|
+
function camelCase(str) {
|
|
13
|
+
const firstIdx = Math.min(str.includes("-") ? str.indexOf("-") : Infinity, str.includes(" ") ? str.indexOf(" ") : Infinity);
|
|
14
|
+
if (firstIdx === Infinity) return str;
|
|
15
|
+
let result = str.slice(0, firstIdx);
|
|
16
|
+
for (let i = firstIdx; i < str.length; i++) if ((str[i] === "-" || str[i] === " ") && i + 1 < str.length) {
|
|
17
|
+
const nextChar = str.charCodeAt(i + 1);
|
|
18
|
+
if (nextChar >= 97 && nextChar <= 122) {
|
|
19
|
+
result += String.fromCharCode(nextChar - 32);
|
|
20
|
+
i++;
|
|
21
|
+
} else {
|
|
22
|
+
result += str[i + 1];
|
|
23
|
+
i++;
|
|
24
|
+
}
|
|
25
|
+
} else if (str[i] !== "-" && str[i] !== " ") result += str[i];
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/command.ts
|
|
6
31
|
function resolveCommand(commandsMap, parameters) {
|
|
7
32
|
for (let i = parameters.length; i >= 0; i--) {
|
|
8
33
|
const name = parameters.slice(0, i).join(" ");
|
|
@@ -24,19 +49,17 @@ var NoCommandSpecifiedError = class extends Error {
|
|
|
24
49
|
super(text);
|
|
25
50
|
}
|
|
26
51
|
};
|
|
27
|
-
var InvalidCommandError = class extends Error {
|
|
28
|
-
constructor(message) {
|
|
29
|
-
super(message);
|
|
30
|
-
}
|
|
31
|
-
};
|
|
52
|
+
var InvalidCommandError = class extends Error {};
|
|
32
53
|
var MissingRequiredMetadataError = class extends Error {
|
|
33
54
|
constructor(metadataName) {
|
|
34
55
|
super(`CLI ${metadataName} is required.`);
|
|
35
56
|
}
|
|
36
57
|
};
|
|
37
|
-
var InvalidParametersError = class extends Error {
|
|
38
|
-
|
|
39
|
-
|
|
58
|
+
var InvalidParametersError = class extends Error {};
|
|
59
|
+
var MissingRequiredFlagError = class extends Error {
|
|
60
|
+
constructor(flags) {
|
|
61
|
+
const s = flags.length > 1 ? "s" : "";
|
|
62
|
+
super(`Missing required flag${s}: ${flags.join(", ")}`);
|
|
40
63
|
}
|
|
41
64
|
};
|
|
42
65
|
|
|
@@ -73,7 +96,18 @@ function compose(inspectors) {
|
|
|
73
96
|
}
|
|
74
97
|
|
|
75
98
|
//#endregion
|
|
76
|
-
//#region
|
|
99
|
+
//#region ../../node_modules/.pnpm/is-platform@1.0.0/node_modules/is-platform/dist/index.mjs
|
|
100
|
+
const IS_DENO = typeof Deno !== "undefined";
|
|
101
|
+
const IS_NODE = typeof process !== "undefined" && !IS_DENO;
|
|
102
|
+
const IS_ELECTRON = process.versions.electron && !process.defaultApp;
|
|
103
|
+
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/utils.ts
|
|
106
|
+
const normalizeFlagValue = (flag) => typeof flag === "function" || looseIsArray(flag) ? { type: flag } : flag;
|
|
107
|
+
const normalizeParameterValue = (parameter) => typeof parameter === "string" ? { key: parameter } : parameter;
|
|
108
|
+
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/parameter.ts
|
|
77
111
|
function getParametersToResolve(argv) {
|
|
78
112
|
const parameters = [];
|
|
79
113
|
for (const arg of argv) {
|
|
@@ -84,15 +118,21 @@ function getParametersToResolve(argv) {
|
|
|
84
118
|
}
|
|
85
119
|
const PARAMETER_REGEX = /^(<|\[)([\w ]+)(\.\.\.)?(\]|>)$/;
|
|
86
120
|
const isParameterDefinitionBracketsValid = (definition) => definition.startsWith("<") && definition.endsWith(">") || definition.startsWith("[") && definition.endsWith("]");
|
|
121
|
+
function extractParameterInfo(key) {
|
|
122
|
+
const match = key.match(PARAMETER_REGEX);
|
|
123
|
+
if (!match || !isParameterDefinitionBracketsValid(key)) throw new InvalidParametersError(`Invalid parameter definition: ${key}`);
|
|
124
|
+
return {
|
|
125
|
+
name: camelCase(match[2]),
|
|
126
|
+
isRequired: key.startsWith("<"),
|
|
127
|
+
isVariadic: !!match[3]
|
|
128
|
+
};
|
|
129
|
+
}
|
|
87
130
|
function _parseParameters(definitions, parameters) {
|
|
88
131
|
const result = {};
|
|
89
132
|
let hasOptional = false;
|
|
90
|
-
for (const [i,
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
const name = camelCase(match[2]);
|
|
94
|
-
const isVariadic = !!match[3];
|
|
95
|
-
const isRequired = definition.startsWith("<");
|
|
133
|
+
for (const [i, def] of definitions.entries()) {
|
|
134
|
+
const normalized = normalizeParameterValue(def);
|
|
135
|
+
const { name, isRequired, isVariadic } = extractParameterInfo(normalized.key);
|
|
96
136
|
if (name in result) throw new InvalidParametersError(`Duplicate parameter name: ${name}`);
|
|
97
137
|
if (isVariadic && i !== definitions.length - 1) throw new InvalidParametersError("Variadic parameter must be the last parameter in the definition.");
|
|
98
138
|
if (isRequired) {
|
|
@@ -100,7 +140,10 @@ function _parseParameters(definitions, parameters) {
|
|
|
100
140
|
} else hasOptional = true;
|
|
101
141
|
const value = isVariadic ? parameters.slice(i) : parameters[i];
|
|
102
142
|
if (isRequired && (isVariadic ? value.length === 0 : value === void 0)) throw new InvalidParametersError(`Missing required ${isVariadic ? "variadic " : ""}parameter: ${name}`);
|
|
103
|
-
result[name] = value;
|
|
143
|
+
if (normalized.type) if (isVariadic) result[name] = value.map((v) => normalized.type(v));
|
|
144
|
+
else if (value === void 0) result[name] = value;
|
|
145
|
+
else result[name] = normalized.type(value);
|
|
146
|
+
else result[name] = value;
|
|
104
147
|
}
|
|
105
148
|
return result;
|
|
106
149
|
}
|
|
@@ -117,12 +160,6 @@ function parseParameters(definitions, parameters, doubleDashParameters) {
|
|
|
117
160
|
}
|
|
118
161
|
}
|
|
119
162
|
|
|
120
|
-
//#endregion
|
|
121
|
-
//#region ../../node_modules/.pnpm/is-platform@1.0.0/node_modules/is-platform/dist/index.mjs
|
|
122
|
-
const IS_DENO = typeof Deno !== "undefined";
|
|
123
|
-
const IS_NODE = typeof process !== "undefined" && !IS_DENO;
|
|
124
|
-
const IS_ELECTRON = process.versions.electron && !process.defaultApp;
|
|
125
|
-
|
|
126
163
|
//#endregion
|
|
127
164
|
//#region src/platform.ts
|
|
128
165
|
const platformArgv = IS_NODE ? process.argv.slice(IS_ELECTRON ? 1 : 2) : IS_DENO ? Deno.args : [];
|
|
@@ -132,8 +169,9 @@ const platformArgv = IS_NODE ? process.argv.slice(IS_ELECTRON ? 1 : 2) : IS_DENO
|
|
|
132
169
|
var Clerc = class Clerc {
|
|
133
170
|
#argv = [];
|
|
134
171
|
#commands = /* @__PURE__ */ new Map();
|
|
135
|
-
#emitter = new LiteEmit(
|
|
172
|
+
#emitter = new LiteEmit();
|
|
136
173
|
#globalFlags = {};
|
|
174
|
+
#store = {};
|
|
137
175
|
#interceptors = [];
|
|
138
176
|
#errorHandlers = [];
|
|
139
177
|
#name = "";
|
|
@@ -164,6 +202,9 @@ var Clerc = class Clerc {
|
|
|
164
202
|
get _globalFlags() {
|
|
165
203
|
return this.#globalFlags;
|
|
166
204
|
}
|
|
205
|
+
get store() {
|
|
206
|
+
return this.#store;
|
|
207
|
+
}
|
|
167
208
|
static create(options) {
|
|
168
209
|
return new Clerc(options);
|
|
169
210
|
}
|
|
@@ -211,13 +252,14 @@ var Clerc = class Clerc {
|
|
|
211
252
|
if (this.#commands.has(name)) throw new InvalidCommandError(`Command with name "${name}" already exists.`);
|
|
212
253
|
for (const alias of aliases) if (this.#commands.has(alias)) throw new InvalidCommandError(`Command with name "${alias}" already exists.`);
|
|
213
254
|
}
|
|
214
|
-
command(nameOrCommandObject,
|
|
255
|
+
command(nameOrCommandObject, descriptionOrOptions, options) {
|
|
256
|
+
const isDescription = typeof descriptionOrOptions === "string";
|
|
215
257
|
const command = typeof nameOrCommandObject === "string" ? {
|
|
216
258
|
name: nameOrCommandObject,
|
|
217
|
-
description,
|
|
218
|
-
...options
|
|
259
|
+
description: isDescription ? descriptionOrOptions : void 0,
|
|
260
|
+
...isDescription ? options : descriptionOrOptions
|
|
219
261
|
} : nameOrCommandObject;
|
|
220
|
-
const aliases = toArray(
|
|
262
|
+
const aliases = toArray(command?.alias ?? []);
|
|
221
263
|
this.#callWithErrorHandler(() => this.#validateCommandNameAndAlias(command.name, aliases));
|
|
222
264
|
this.#commands.set(command.name, command);
|
|
223
265
|
for (const alias of aliases) this.#commands.set(alias, {
|
|
@@ -227,10 +269,11 @@ var Clerc = class Clerc {
|
|
|
227
269
|
if (command.handler) this.on(command.name, command.handler);
|
|
228
270
|
return this;
|
|
229
271
|
}
|
|
230
|
-
globalFlag(name,
|
|
272
|
+
globalFlag(name, descriptionOrOptions, options) {
|
|
273
|
+
const isDescription = typeof descriptionOrOptions === "string";
|
|
231
274
|
this.#globalFlags[name] = {
|
|
232
|
-
description,
|
|
233
|
-
...options
|
|
275
|
+
description: isDescription ? descriptionOrOptions : void 0,
|
|
276
|
+
...isDescription ? options : descriptionOrOptions
|
|
234
277
|
};
|
|
235
278
|
return this;
|
|
236
279
|
}
|
|
@@ -244,7 +287,6 @@ var Clerc = class Clerc {
|
|
|
244
287
|
}
|
|
245
288
|
#validate() {
|
|
246
289
|
if (!this.#scriptName) throw new MissingRequiredMetadataError("script name");
|
|
247
|
-
if (!this.#description) throw new MissingRequiredMetadataError("description");
|
|
248
290
|
if (!this.#version) throw new MissingRequiredMetadataError("version");
|
|
249
291
|
}
|
|
250
292
|
#parseArgv(argv, command) {
|
|
@@ -270,20 +312,20 @@ var Clerc = class Clerc {
|
|
|
270
312
|
parametersError = e;
|
|
271
313
|
}
|
|
272
314
|
const context = {
|
|
273
|
-
resolved: !!command,
|
|
274
315
|
command,
|
|
275
316
|
calledAs,
|
|
276
317
|
parameters,
|
|
277
318
|
flags: parsed.flags,
|
|
278
319
|
ignored: parsed.ignored,
|
|
279
320
|
rawParsed: parsed,
|
|
280
|
-
|
|
321
|
+
store: { ...this.#store }
|
|
281
322
|
};
|
|
282
323
|
const emitInterceptor = {
|
|
283
324
|
enforce: "post",
|
|
284
|
-
handler: (ctx) => {
|
|
325
|
+
handler: async (ctx) => {
|
|
326
|
+
if (parsed.missingRequiredFlags.length > 0) throw new MissingRequiredFlagError(parsed.missingRequiredFlags);
|
|
285
327
|
if (parametersError) throw parametersError;
|
|
286
|
-
if (command) this.#emitter.emit(command.name, ctx);
|
|
328
|
+
if (command) await this.#emitter.emit(command.name, ctx);
|
|
287
329
|
else throw parametersToResolve.length > 0 ? new NoSuchCommandError(parametersToResolve.join(" ")) : new NoCommandSpecifiedError();
|
|
288
330
|
}
|
|
289
331
|
};
|
|
@@ -302,7 +344,10 @@ var Clerc = class Clerc {
|
|
|
302
344
|
|
|
303
345
|
//#endregion
|
|
304
346
|
//#region src/helpers.ts
|
|
305
|
-
const defineCommand = (command) =>
|
|
347
|
+
const defineCommand = (command, handler) => ({
|
|
348
|
+
...command,
|
|
349
|
+
handler
|
|
350
|
+
});
|
|
306
351
|
|
|
307
352
|
//#endregion
|
|
308
353
|
//#region src/ignore.ts
|
|
@@ -322,4 +367,4 @@ function createStopAtFirstParameter() {
|
|
|
322
367
|
const definePlugin = (plugin) => plugin;
|
|
323
368
|
|
|
324
369
|
//#endregion
|
|
325
|
-
export {
|
|
370
|
+
export { Clerc, DOUBLE_DASH, InvalidCommandError, InvalidParametersError, InvalidSchemaError, KNOWN_FLAG, MissingRequiredFlagError, MissingRequiredMetadataError, NoCommandSpecifiedError, NoSuchCommandError, PARAMETER, Types, UNKNOWN_FLAG, createStopAtFirstParameter, defineCommand, definePlugin, extractParameterInfo, normalizeFlagValue, normalizeParameterValue, resolveCommand };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clerc/core",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.30",
|
|
4
4
|
"author": "Ray <i@mk1.io> (https://github.com/so1ve)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Clerc core",
|
|
@@ -44,15 +44,12 @@
|
|
|
44
44
|
"access": "public"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"lite-emit": "^
|
|
48
|
-
"@clerc/parser": "
|
|
49
|
-
"@clerc/
|
|
47
|
+
"lite-emit": "^4.0.0",
|
|
48
|
+
"@clerc/parser": "1.0.0-beta.30",
|
|
49
|
+
"@clerc/advanced-types": "1.0.0-beta.30"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"is-platform": "^1.0.0"
|
|
53
|
-
|
|
54
|
-
"scripts": {
|
|
55
|
-
"build": "tsdown",
|
|
56
|
-
"watch": "tsdown --watch"
|
|
52
|
+
"is-platform": "^1.0.0",
|
|
53
|
+
"@clerc/utils": "1.0.0-beta.30"
|
|
57
54
|
}
|
|
58
55
|
}
|