@clerc/core 0.25.0 → 0.26.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/index.d.ts CHANGED
@@ -1,6 +1,170 @@
1
- import { LiteralUnion, OmitIndexSignature } from 'type-fest';
2
- import * as _clerc_utils from '@clerc/utils';
3
- import { Dict, MaybeArray as MaybeArray$1, Equals, CamelCase } from '@clerc/utils';
1
+ /**
2
+ Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive).
3
+
4
+ @category Type
5
+ */
6
+ type Primitive =
7
+ | null
8
+ | undefined
9
+ | string
10
+ | number
11
+ | boolean
12
+ | symbol
13
+ | bigint;
14
+
15
+ declare global {
16
+ // eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- It has to be an `interface` so that it can be merged.
17
+ interface SymbolConstructor {
18
+ readonly observable: symbol;
19
+ }
20
+ }
21
+
22
+ /**
23
+ Omit any index signatures from the given object type, leaving only explicitly defined properties.
24
+
25
+ This is the counterpart of `PickIndexSignature`.
26
+
27
+ Use-cases:
28
+ - Remove overly permissive signatures from third-party types.
29
+
30
+ This type was taken from this [StackOverflow answer](https://stackoverflow.com/a/68261113/420747).
31
+
32
+ It relies on the fact that an empty object (`{}`) is assignable to an object with just an index signature, like `Record<string, unknown>`, but not to an object with explicitly defined keys, like `Record<'foo' | 'bar', unknown>`.
33
+
34
+ (The actual value type, `unknown`, is irrelevant and could be any type. Only the key type matters.)
35
+
36
+ ```
37
+ const indexed: Record<string, unknown> = {}; // Allowed
38
+
39
+ const keyed: Record<'foo', unknown> = {}; // Error
40
+ // => TS2739: Type '{}' is missing the following properties from type 'Record<"foo" | "bar", unknown>': foo, bar
41
+ ```
42
+
43
+ Instead of causing a type error like the above, you can also use a [conditional type](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html) to test whether a type is assignable to another:
44
+
45
+ ```
46
+ type Indexed = {} extends Record<string, unknown>
47
+ ? '✅ `{}` is assignable to `Record<string, unknown>`'
48
+ : '❌ `{}` is NOT assignable to `Record<string, unknown>`';
49
+ // => '✅ `{}` is assignable to `Record<string, unknown>`'
50
+
51
+ type Keyed = {} extends Record<'foo' | 'bar', unknown>
52
+ ? "✅ `{}` is assignable to `Record<'foo' | 'bar', unknown>`"
53
+ : "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`";
54
+ // => "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`"
55
+ ```
56
+
57
+ Using a [mapped type](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#further-exploration), you can then check for each `KeyType` of `ObjectType`...
58
+
59
+ ```
60
+ import type {OmitIndexSignature} from 'type-fest';
61
+
62
+ type OmitIndexSignature<ObjectType> = {
63
+ [KeyType in keyof ObjectType // Map each key of `ObjectType`...
64
+ ]: ObjectType[KeyType]; // ...to its original value, i.e. `OmitIndexSignature<Foo> == Foo`.
65
+ };
66
+ ```
67
+
68
+ ...whether an empty object (`{}`) would be assignable to an object with that `KeyType` (`Record<KeyType, unknown>`)...
69
+
70
+ ```
71
+ import type {OmitIndexSignature} from 'type-fest';
72
+
73
+ type OmitIndexSignature<ObjectType> = {
74
+ [KeyType in keyof ObjectType
75
+ // Is `{}` assignable to `Record<KeyType, unknown>`?
76
+ as {} extends Record<KeyType, unknown>
77
+ ? ... // ✅ `{}` is assignable to `Record<KeyType, unknown>`
78
+ : ... // ❌ `{}` is NOT assignable to `Record<KeyType, unknown>`
79
+ ]: ObjectType[KeyType];
80
+ };
81
+ ```
82
+
83
+ If `{}` is assignable, it means that `KeyType` is an index signature and we want to remove it. If it is not assignable, `KeyType` is a "real" key and we want to keep it.
84
+
85
+ ```
86
+ import type {OmitIndexSignature} from 'type-fest';
87
+
88
+ type OmitIndexSignature<ObjectType> = {
89
+ [KeyType in keyof ObjectType
90
+ as {} extends Record<KeyType, unknown>
91
+ ? never // => Remove this `KeyType`.
92
+ : KeyType // => Keep this `KeyType` as it is.
93
+ ]: ObjectType[KeyType];
94
+ };
95
+ ```
96
+
97
+ @example
98
+ ```
99
+ import type {OmitIndexSignature} from 'type-fest';
100
+
101
+ interface Example {
102
+ // These index signatures will be removed.
103
+ [x: string]: any
104
+ [x: number]: any
105
+ [x: symbol]: any
106
+ [x: `head-${string}`]: string
107
+ [x: `${string}-tail`]: string
108
+ [x: `head-${string}-tail`]: string
109
+ [x: `${bigint}`]: string
110
+ [x: `embedded-${number}`]: string
111
+
112
+ // These explicitly defined keys will remain.
113
+ foo: 'bar';
114
+ qux?: 'baz';
115
+ }
116
+
117
+ type ExampleWithoutIndexSignatures = OmitIndexSignature<Example>;
118
+ // => { foo: 'bar'; qux?: 'baz' | undefined; }
119
+ ```
120
+
121
+ @see PickIndexSignature
122
+ @category Object
123
+ */
124
+ type OmitIndexSignature<ObjectType> = {
125
+ [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown>
126
+ ? never
127
+ : KeyType]: ObjectType[KeyType];
128
+ };
129
+
130
+ /**
131
+ Allows creating a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union.
132
+
133
+ Currently, when a union type of a primitive type is combined with literal types, TypeScript loses all information about the combined literals. Thus, when such type is used in an IDE with autocompletion, no suggestions are made for the declared literals.
134
+
135
+ This type is a workaround for [Microsoft/TypeScript#29729](https://github.com/Microsoft/TypeScript/issues/29729). It will be removed as soon as it's not needed anymore.
136
+
137
+ @example
138
+ ```
139
+ import type {LiteralUnion} from 'type-fest';
140
+
141
+ // Before
142
+
143
+ type Pet = 'dog' | 'cat' | string;
144
+
145
+ const pet: Pet = '';
146
+ // Start typing in your TypeScript-enabled IDE.
147
+ // You **will not** get auto-completion for `dog` and `cat` literals.
148
+
149
+ // After
150
+
151
+ type Pet2 = LiteralUnion<'dog' | 'cat', string>;
152
+
153
+ const pet: Pet2 = '';
154
+ // You **will** get auto-completion for `dog` and `cat` literals.
155
+ ```
156
+
157
+ @category Type
158
+ */
159
+ type LiteralUnion<
160
+ LiteralType,
161
+ BaseType extends Primitive,
162
+ > = LiteralType | (BaseType & Record<never, never>);
163
+
164
+ type Equals<X, Y> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false;
165
+ type Dict<T> = Record<string, T>;
166
+ type MaybeArray$1<T> = T | T[];
167
+ type CamelCase<T extends string> = T extends `${infer A}-${infer B}${infer C}` ? `${A}${Capitalize<B>}${CamelCase<C>}` : T;
4
168
 
5
169
  declare const DOUBLE_DASH = "--";
6
170
  type TypeFunction<ReturnType = any> = (value: any) => ReturnType;
@@ -329,10 +493,10 @@ declare class InvalidCommandNameError extends Error {
329
493
  constructor(commandName: string);
330
494
  }
331
495
 
332
- declare function resolveFlattenCommands(commands: CommandRecord): Map<string[] | typeof Root, CommandAlias<string, CommandOptions<string[], _clerc_utils.MaybeArray<string | typeof Root>, Flags>>>;
496
+ declare function resolveFlattenCommands(commands: CommandRecord): Map<string[] | typeof Root, CommandAlias<string, CommandOptions<string[], MaybeArray$1<string | typeof Root>, Flags>>>;
333
497
  declare function resolveCommand(commands: CommandRecord, name: string | string[] | RootType): Command<string | RootType> | undefined;
334
- declare function resolveSubcommandsByParent(commands: CommandRecord, parent: string | string[], depth?: number): Command<string, CommandOptions<string[], _clerc_utils.MaybeArray<string | typeof Root>, Flags>>[];
335
- declare const resolveRootCommands: (commands: CommandRecord) => Command<string, CommandOptions<string[], _clerc_utils.MaybeArray<string | typeof Root>, Flags>>[];
498
+ declare function resolveSubcommandsByParent(commands: CommandRecord, parent: string | string[], depth?: number): Command<string, CommandOptions<string[], MaybeArray$1<string | typeof Root>, Flags>>[];
499
+ declare const resolveRootCommands: (commands: CommandRecord) => Command<string, CommandOptions<string[], MaybeArray$1<string | typeof Root>, Flags>>[];
336
500
  declare function resolveParametersBeforeFlag(argv: string[]): string[];
337
501
  declare const resolveArgv: () => string[];
338
502
  declare function compose(inspectors: Inspector[]): (getCtx: () => InspectorContext) => void;
package/dist/index.js CHANGED
@@ -1,410 +1 @@
1
- import { LiteEmit } from 'lite-emit';
2
- import { typeFlag } from 'type-flag';
3
- import { toArray, arrayStartsWith, camelCase } from '@clerc/utils';
4
- import { isNode, isDeno } from 'is-platform';
5
-
6
- class CommandExistsError extends Error {
7
- constructor(commandName) {
8
- super(`Command "${commandName}" exists.`);
9
- this.commandName = commandName;
10
- }
11
- }
12
- class NoSuchCommandError extends Error {
13
- constructor(commandName) {
14
- super(`No such command: ${commandName}`);
15
- this.commandName = commandName;
16
- }
17
- }
18
- class NoCommandGivenError extends Error {
19
- constructor() {
20
- super("No command given.");
21
- }
22
- }
23
- class CommandNameConflictError extends Error {
24
- constructor(n1, n2) {
25
- super(`Command name ${n1} conflicts with ${n2}. Maybe caused by alias.`);
26
- this.n1 = n1;
27
- this.n2 = n2;
28
- }
29
- }
30
- class NameNotSetError extends Error {
31
- constructor() {
32
- super("Name not set.");
33
- }
34
- }
35
- class DescriptionNotSetError extends Error {
36
- constructor() {
37
- super("Description not set.");
38
- }
39
- }
40
- class VersionNotSetError extends Error {
41
- constructor() {
42
- super("Version not set.");
43
- }
44
- }
45
- class InvalidCommandNameError extends Error {
46
- constructor(commandName) {
47
- super(`Bad name format: ${commandName}`);
48
- this.commandName = commandName;
49
- }
50
- }
51
-
52
- function setCommand(commandsMap, commands, command) {
53
- if (command.alias) {
54
- const aliases = toArray(command.alias);
55
- for (const alias of aliases) {
56
- if (alias in commands) {
57
- throw new CommandNameConflictError(commands[alias].name, command.name);
58
- }
59
- commandsMap.set(typeof alias === "symbol" ? alias : alias.split(" "), { ...command, __isAlias: true });
60
- }
61
- }
62
- }
63
- function resolveFlattenCommands(commands) {
64
- const commandsMap = /* @__PURE__ */ new Map();
65
- if (commands[Root]) {
66
- commandsMap.set(Root, commands[Root]);
67
- setCommand(commandsMap, commands, commands[Root]);
68
- }
69
- for (const command of Object.values(commands)) {
70
- setCommand(commandsMap, commands, command);
71
- commandsMap.set(command.name.split(" "), command);
72
- }
73
- return commandsMap;
74
- }
75
- function resolveCommand(commands, name) {
76
- if (name === Root) {
77
- return commands[Root];
78
- }
79
- const nameArr = toArray(name);
80
- const commandsMap = resolveFlattenCommands(commands);
81
- let current;
82
- let currentName;
83
- commandsMap.forEach((v, k) => {
84
- if (k === Root) {
85
- current = commandsMap.get(Root);
86
- currentName = Root;
87
- return;
88
- }
89
- if (arrayStartsWith(nameArr, k) && (!currentName || currentName === Root || k.length > currentName.length)) {
90
- current = v;
91
- currentName = k;
92
- }
93
- });
94
- return current;
95
- }
96
- function resolveSubcommandsByParent(commands, parent, depth = Infinity) {
97
- const parentArr = parent === "" ? [] : Array.isArray(parent) ? parent : parent.split(" ");
98
- return Object.values(commands).filter((c) => {
99
- const commandNameArr = c.name.split(" ");
100
- return arrayStartsWith(commandNameArr, parentArr) && commandNameArr.length - parentArr.length <= depth;
101
- });
102
- }
103
- const resolveRootCommands = (commands) => resolveSubcommandsByParent(commands, "", 1);
104
- function resolveParametersBeforeFlag(argv) {
105
- const parameters = [];
106
- for (const arg of argv) {
107
- if (arg.startsWith("-")) {
108
- break;
109
- }
110
- parameters.push(arg);
111
- }
112
- return parameters;
113
- }
114
- const resolveArgv = () => isNode() ? process.argv.slice(2) : isDeno() ? Deno.args : [];
115
- function compose(inspectors) {
116
- const inspectorMap = {
117
- pre: [],
118
- normal: [],
119
- post: []
120
- };
121
- for (const inspector of inspectors) {
122
- const objectInspector = typeof inspector === "object" ? inspector : { fn: inspector };
123
- const { enforce, fn } = objectInspector;
124
- if (enforce === "post" || enforce === "pre") {
125
- inspectorMap[enforce].push(fn);
126
- } else {
127
- inspectorMap.normal.push(fn);
128
- }
129
- }
130
- const mergedInspectorFns = [
131
- ...inspectorMap.pre,
132
- ...inspectorMap.normal,
133
- ...inspectorMap.post
134
- ];
135
- return (getCtx) => {
136
- return dispatch(0);
137
- function dispatch(i) {
138
- const inspector = mergedInspectorFns[i];
139
- return inspector(getCtx(), dispatch.bind(null, i + 1));
140
- }
141
- };
142
- }
143
- const isInvalidName = (name) => typeof name === "string" && (name.startsWith(" ") || name.endsWith(" "));
144
- const withBrackets = (s, isOptional) => isOptional ? `[${s}]` : `<${s}>`;
145
- const ROOT = "<Root>";
146
- const formatCommandName = (name) => Array.isArray(name) ? name.join(" ") : typeof name === "string" ? name : ROOT;
147
-
148
- const { stringify } = JSON;
149
- function parseParameters(parameters) {
150
- const parsedParameters = [];
151
- let hasOptional;
152
- let hasSpread;
153
- for (const parameter of parameters) {
154
- if (hasSpread) {
155
- throw new Error(`Invalid parameter: Spread parameter ${stringify(hasSpread)} must be last`);
156
- }
157
- const firstCharacter = parameter[0];
158
- const lastCharacter = parameter[parameter.length - 1];
159
- let required;
160
- if (firstCharacter === "<" && lastCharacter === ">") {
161
- required = true;
162
- if (hasOptional) {
163
- throw new Error(`Invalid parameter: Required parameter ${stringify(parameter)} cannot come after optional parameter ${stringify(hasOptional)}`);
164
- }
165
- }
166
- if (firstCharacter === "[" && lastCharacter === "]") {
167
- required = false;
168
- hasOptional = parameter;
169
- }
170
- if (required === void 0) {
171
- throw new Error(`Invalid parameter: ${stringify(parameter)}. Must be wrapped in <> (required parameter) or [] (optional parameter)`);
172
- }
173
- let name = parameter.slice(1, -1);
174
- const spread = name.slice(-3) === "...";
175
- if (spread) {
176
- hasSpread = parameter;
177
- name = name.slice(0, -3);
178
- }
179
- parsedParameters.push({
180
- name,
181
- required,
182
- spread
183
- });
184
- }
185
- return parsedParameters;
186
- }
187
- function mapParametersToArguments(mapping, parameters, cliArguments) {
188
- for (let i = 0; i < parameters.length; i += 1) {
189
- const { name, required, spread } = parameters[i];
190
- const camelCaseName = camelCase(name);
191
- if (camelCaseName in mapping) {
192
- return new Error(`Invalid parameter: ${stringify(name)} is used more than once.`);
193
- }
194
- const value = spread ? cliArguments.slice(i) : cliArguments[i];
195
- if (spread) {
196
- i = parameters.length;
197
- }
198
- if (required && (!value || spread && value.length === 0)) {
199
- return new Error(`Error: Missing required parameter ${stringify(name)}`);
200
- }
201
- mapping[camelCaseName] = value;
202
- }
203
- }
204
-
205
- var __accessCheck = (obj, member, msg) => {
206
- if (!member.has(obj))
207
- throw TypeError("Cannot " + msg);
208
- };
209
- var __privateGet = (obj, member, getter) => {
210
- __accessCheck(obj, member, "read from private field");
211
- return getter ? getter.call(obj) : member.get(obj);
212
- };
213
- var __privateAdd = (obj, member, value) => {
214
- if (member.has(obj))
215
- throw TypeError("Cannot add the same private member more than once");
216
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
217
- };
218
- var __privateSet = (obj, member, value, setter) => {
219
- __accessCheck(obj, member, "write to private field");
220
- setter ? setter.call(obj, value) : member.set(obj, value);
221
- return value;
222
- };
223
- var _name, _description, _version, _inspectors, _commands, _commandEmitter, _usedNames, _hasRootOrAlias, hasRootOrAlias_get, _hasRoot, hasRoot_get;
224
- const Root = Symbol("Root");
225
- const _Clerc = class {
226
- constructor(name, description, version) {
227
- __privateAdd(this, _hasRootOrAlias);
228
- __privateAdd(this, _hasRoot);
229
- __privateAdd(this, _name, "");
230
- __privateAdd(this, _description, "");
231
- __privateAdd(this, _version, "");
232
- __privateAdd(this, _inspectors, []);
233
- __privateAdd(this, _commands, {});
234
- __privateAdd(this, _commandEmitter, new LiteEmit());
235
- __privateAdd(this, _usedNames, /* @__PURE__ */ new Set());
236
- __privateSet(this, _name, name || __privateGet(this, _name));
237
- __privateSet(this, _description, description || __privateGet(this, _description));
238
- __privateSet(this, _version, version || __privateGet(this, _version));
239
- }
240
- get _name() {
241
- return __privateGet(this, _name);
242
- }
243
- get _description() {
244
- return __privateGet(this, _description);
245
- }
246
- get _version() {
247
- return __privateGet(this, _version);
248
- }
249
- get _inspectors() {
250
- return __privateGet(this, _inspectors);
251
- }
252
- get _commands() {
253
- return __privateGet(this, _commands);
254
- }
255
- static create(name, description, version) {
256
- return new _Clerc(name, description, version);
257
- }
258
- name(name) {
259
- __privateSet(this, _name, name);
260
- return this;
261
- }
262
- description(description) {
263
- __privateSet(this, _description, description);
264
- return this;
265
- }
266
- version(version) {
267
- __privateSet(this, _version, version);
268
- return this;
269
- }
270
- command(nameOrCommand, description, options = {}) {
271
- const checkIsCommandObject = (nameOrCommand2) => !(typeof nameOrCommand2 === "string" || nameOrCommand2 === Root);
272
- const isCommandObject = checkIsCommandObject(nameOrCommand);
273
- const name = !isCommandObject ? nameOrCommand : nameOrCommand.name;
274
- if (isInvalidName(name)) {
275
- throw new InvalidCommandNameError(name);
276
- }
277
- const { handler = void 0, ...commandToSave } = isCommandObject ? nameOrCommand : { name, description, ...options };
278
- const nameList = [commandToSave.name];
279
- commandToSave.alias && nameList.push(...toArray(commandToSave.alias));
280
- for (const name2 of nameList) {
281
- if (__privateGet(this, _usedNames).has(name2)) {
282
- throw new CommandExistsError(formatCommandName(name2));
283
- }
284
- }
285
- __privateGet(this, _commands)[name] = commandToSave;
286
- __privateGet(this, _usedNames).add(commandToSave.name);
287
- (toArray(commandToSave.alias) || []).forEach((a) => __privateGet(this, _usedNames).add(a));
288
- isCommandObject && handler && this.on(nameOrCommand.name, handler);
289
- return this;
290
- }
291
- on(name, handler) {
292
- __privateGet(this, _commandEmitter).on(name, handler);
293
- return this;
294
- }
295
- use(plugin) {
296
- return plugin.setup(this);
297
- }
298
- inspector(inspector) {
299
- __privateGet(this, _inspectors).push(inspector);
300
- return this;
301
- }
302
- parse(argv = resolveArgv()) {
303
- if (!__privateGet(this, _name)) {
304
- throw new NameNotSetError();
305
- }
306
- if (!__privateGet(this, _description)) {
307
- throw new DescriptionNotSetError();
308
- }
309
- if (!__privateGet(this, _version)) {
310
- throw new VersionNotSetError();
311
- }
312
- const name = resolveParametersBeforeFlag(argv);
313
- const stringName = name.join(" ");
314
- const getCommand = () => resolveCommand(__privateGet(this, _commands), name);
315
- const mapErrors = [];
316
- const getContext = () => {
317
- mapErrors.length = 0;
318
- const command = getCommand();
319
- const isCommandResolved = !!command;
320
- const parsed = typeFlag((command == null ? void 0 : command.flags) || {}, [...argv]);
321
- const { _: args, flags, unknownFlags } = parsed;
322
- let parameters = !isCommandResolved || command.name === Root ? args : args.slice(command.name.split(" ").length);
323
- let commandParameters = (command == null ? void 0 : command.parameters) || [];
324
- const hasEof = commandParameters.indexOf("--");
325
- const eofParameters = commandParameters.slice(hasEof + 1) || [];
326
- const mapping = /* @__PURE__ */ Object.create(null);
327
- if (hasEof > -1 && eofParameters.length > 0) {
328
- commandParameters = commandParameters.slice(0, hasEof);
329
- const eofArguments = args["--"];
330
- parameters = parameters.slice(0, -eofArguments.length || void 0);
331
- mapErrors.push(mapParametersToArguments(
332
- mapping,
333
- parseParameters(commandParameters),
334
- parameters
335
- ));
336
- mapErrors.push(mapParametersToArguments(
337
- mapping,
338
- parseParameters(eofParameters),
339
- eofArguments
340
- ));
341
- } else {
342
- mapErrors.push(mapParametersToArguments(
343
- mapping,
344
- parseParameters(commandParameters),
345
- parameters
346
- ));
347
- }
348
- const mergedFlags = { ...flags, ...unknownFlags };
349
- const context = {
350
- name: command == null ? void 0 : command.name,
351
- called: name.length === 0 && (command == null ? void 0 : command.name) ? Root : stringName,
352
- resolved: isCommandResolved,
353
- hasRootOrAlias: __privateGet(this, _hasRootOrAlias, hasRootOrAlias_get),
354
- hasRoot: __privateGet(this, _hasRoot, hasRoot_get),
355
- raw: { ...parsed, parameters, mergedFlags },
356
- parameters: mapping,
357
- flags,
358
- unknownFlags,
359
- cli: this
360
- };
361
- return context;
362
- };
363
- const emitHandler = {
364
- enforce: "post",
365
- fn: () => {
366
- const command = getCommand();
367
- const handlerContext = getContext();
368
- const errors = mapErrors.filter(Boolean);
369
- if (errors.length > 0) {
370
- throw errors[0];
371
- }
372
- if (!command) {
373
- if (stringName) {
374
- throw new NoSuchCommandError(stringName);
375
- } else {
376
- throw new NoCommandGivenError();
377
- }
378
- }
379
- __privateGet(this, _commandEmitter).emit(command.name, handlerContext);
380
- }
381
- };
382
- const inspectors = [...__privateGet(this, _inspectors), emitHandler];
383
- const callInspector = compose(inspectors);
384
- callInspector(getContext);
385
- return this;
386
- }
387
- };
388
- let Clerc = _Clerc;
389
- _name = new WeakMap();
390
- _description = new WeakMap();
391
- _version = new WeakMap();
392
- _inspectors = new WeakMap();
393
- _commands = new WeakMap();
394
- _commandEmitter = new WeakMap();
395
- _usedNames = new WeakMap();
396
- _hasRootOrAlias = new WeakSet();
397
- hasRootOrAlias_get = function() {
398
- return __privateGet(this, _usedNames).has(Root);
399
- };
400
- _hasRoot = new WeakSet();
401
- hasRoot_get = function() {
402
- return Object.prototype.hasOwnProperty.call(this._commands, Root);
403
- };
404
-
405
- const definePlugin = (p) => p;
406
- const defineHandler = (_cli, _key, handler) => handler;
407
- const defineInspector = (_cli, inspector) => inspector;
408
- const defineCommand = (command, handler) => ({ ...command, handler });
409
-
410
- export { Clerc, CommandExistsError, CommandNameConflictError, DescriptionNotSetError, InvalidCommandNameError, NameNotSetError, NoCommandGivenError, NoSuchCommandError, Root, VersionNotSetError, compose, defineCommand, defineHandler, defineInspector, definePlugin, formatCommandName, isInvalidName, resolveArgv, resolveCommand, resolveFlattenCommands, resolveParametersBeforeFlag, resolveRootCommands, resolveSubcommandsByParent, withBrackets };
1
+ class fe{constructor(){this.listenerMap={},this.wildcardListeners=new Set}on(t,s){return t==="*"?(this.wildcardListeners.add(s),this):(this.listenerMap[t]||(this.listenerMap[t]=new Set),this.listenerMap[t].add(s),this)}emit(t,...s){return this.listenerMap[t]&&(this.wildcardListeners.forEach(r=>r(t,...s)),this.listenerMap[t].forEach(r=>r(...s))),this}off(t,s){var r,n;return t==="**"?(this.listenerMap={},this.wildcardListeners.clear(),this):t==="*"?(s?this.wildcardListeners.delete(s):this.wildcardListeners.clear(),this):(s?(r=this.listenerMap[t])==null||r.delete(s):(n=this.listenerMap[t])==null||n.clear(),this)}}const ue="known-flag",pe="unknown-flag",de="argument",{stringify:A}=JSON,me=/\B([A-Z])/g,ge=e=>e.replace(me,"-$1").toLowerCase(),{hasOwnProperty:we}=Object.prototype,k=(e,t)=>we.call(e,t),ve=e=>Array.isArray(e),T=e=>typeof e=="function"?[e,!1]:ve(e)?[e[0],!0]:T(e.type),ye=(e,t)=>e===Boolean?t!=="false":t,Ee=(e,t)=>typeof t=="boolean"?t:e===Number&&t===""?Number.NaN:e(t),_e=/[\s.:=]/,Ce=e=>{const t=`Flag name ${A(e)}`;if(e.length===0)throw new Error(`${t} cannot be empty`);if(e.length===1)throw new Error(`${t} must be longer than a character`);const s=e.match(_e);if(s)throw new Error(`${t} cannot contain ${A(s==null?void 0:s[0])}`)},Ne=e=>{const t={},s=(r,n)=>{if(k(t,r))throw new Error(`Duplicate flags named ${A(r)}`);t[r]=n};for(const r in e){if(!k(e,r))continue;Ce(r);const n=e[r],o=[[],...T(n),n];s(r,o);const a=ge(r);if(r!==a&&s(a,o),"alias"in n&&typeof n.alias=="string"){const{alias:i}=n,c=`Flag alias ${A(i)} for flag ${A(r)}`;if(i.length===0)throw new Error(`${c} cannot be empty`);if(i.length>1)throw new Error(`${c} must be a single character`);s(i,o)}}return t},$e=(e,t)=>{const s={};for(const r in e){if(!k(e,r))continue;const[n,,o,a]=t[r];if(n.length===0&&"default"in a){let{default:i}=a;typeof i=="function"&&(i=i()),s[r]=i}else s[r]=o?n:n.pop()}return s},O="--",Me=/[.:=]/,Ae=/^-{1,2}\w/,ke=e=>{if(!Ae.test(e))return;const t=!e.startsWith(O);let s=e.slice(t?1:2),r;const n=s.match(Me);if(n){const{index:o}=n;r=s.slice(o+1),s=s.slice(0,o)}return[s,r,t]},be=(e,{onFlag:t,onArgument:s})=>{let r;const n=(o,a)=>{if(typeof r!="function")return!0;r(o,a),r=void 0};for(let o=0;o<e.length;o+=1){const a=e[o];if(a===O){n();const c=e.slice(o+1);s==null||s(c,[o],!0);break}const i=ke(a);if(i){if(n(),!t)continue;const[c,l,f]=i;if(f)for(let p=0;p<c.length;p+=1){n();const d=p===c.length-1;r=t(c[p],d?l:void 0,[o,p+1,d])}else r=t(c,l,[o])}else n(a,[o])&&(s==null||s([a],[o]))}n()},Se=(e,t)=>{for(const[s,r,n]of t.reverse()){if(r){const o=e[s];let a=o.slice(0,r);if(n||(a+=o.slice(r+1)),a!=="-"){e[s]=a;continue}}e.splice(s,1)}},xe=(e,t=process.argv.slice(2),{ignore:s}={})=>{const r=[],n=Ne(e),o={},a=[];return a[O]=[],be(t,{onFlag(i,c,l){const f=k(n,i);if(!(s!=null&&s(f?ue:pe,i,c))){if(f){const[p,d]=n[i],$=ye(d,c),M=(w,m)=>{r.push(l),m&&r.push(m),p.push(Ee(d,w||""))};return $===void 0?M:M($)}k(o,i)||(o[i]=[]),o[i].push(c===void 0?!0:c),r.push(l)}},onArgument(i,c,l){s!=null&&s(de,t[c[0]])||(a.push(...i),l?(a[O]=i,t.splice(c[0])):r.push(c))}}),Se(t,r),{flags:$e(e,n),unknownFlags:o,_:a}},W=e=>Array.isArray(e)?e:[e],Oe=e=>e.replace(/-([a-z])/g,(t,s)=>s.toUpperCase()),Ie=(e,t)=>t.length!==e.length?!1:e.every((s,r)=>s===t[r]),q=(e,t)=>t.length>e.length?!1:Ie(e.slice(0,t.length),t);class G extends Error{constructor(t){super(`Command "${t}" exists.`),this.commandName=t}}class V extends Error{constructor(t){super(`No such command: ${t}`),this.commandName=t}}class H extends Error{constructor(){super("No command given.")}}class J extends Error{constructor(t,s){super(`Command name ${t} conflicts with ${s}. Maybe caused by alias.`),this.n1=t,this.n2=s}}class U extends Error{constructor(){super("Name not set.")}}class z extends Error{constructor(){super("Description not set.")}}class K extends Error{constructor(){super("Version not set.")}}class Z extends Error{constructor(t){super(`Bad name format: ${t}`),this.commandName=t}}function Re(){return typeof process!="undefined"}function We(){return typeof Deno!="undefined"}function Q(e,t,s){if(s.alias){const r=W(s.alias);for(const n of r){if(n in t)throw new J(t[n].name,s.name);e.set(typeof n=="symbol"?n:n.split(" "),{...s,__isAlias:!0})}}}function X(e){const t=new Map;e[u]&&(t.set(u,e[u]),Q(t,e,e[u]));for(const s of Object.values(e))Q(t,e,s),t.set(s.name.split(" "),s);return t}function Y(e,t){if(t===u)return e[u];const s=W(t),r=X(e);let n,o;return r.forEach((a,i)=>{if(i===u){n=r.get(u),o=u;return}q(s,i)&&(!o||o===u||i.length>o.length)&&(n=a,o=i)}),n}function ee(e,t,s=1/0){const r=t===""?[]:Array.isArray(t)?t:t.split(" ");return Object.values(e).filter(n=>{const o=n.name.split(" ");return q(o,r)&&o.length-r.length<=s})}const Fe=e=>ee(e,"",1);function te(e){const t=[];for(const s of e){if(s.startsWith("-"))break;t.push(s)}return t}const se=()=>Re()?process.argv.slice(2):We()?Deno.args:[];function re(e){const t={pre:[],normal:[],post:[]};for(const r of e){const n=typeof r=="object"?r:{fn:r},{enforce:o,fn:a}=n;o==="post"||o==="pre"?t[o].push(a):t.normal.push(a)}const s=[...t.pre,...t.normal,...t.post];return r=>{return n(0);function n(o){const a=s[o];return a(r(),n.bind(null,o+1))}}}const ne=e=>typeof e=="string"&&(e.startsWith(" ")||e.endsWith(" ")),Le=(e,t)=>t?`[${e}]`:`<${e}>`,Pe="<Root>",oe=e=>Array.isArray(e)?e.join(" "):typeof e=="string"?e:Pe,{stringify:_}=JSON;function F(e){const t=[];let s,r;for(const n of e){if(r)throw new Error(`Invalid parameter: Spread parameter ${_(r)} must be last`);const o=n[0],a=n[n.length-1];let i;if(o==="<"&&a===">"&&(i=!0,s))throw new Error(`Invalid parameter: Required parameter ${_(n)} cannot come after optional parameter ${_(s)}`);if(o==="["&&a==="]"&&(i=!1,s=n),i===void 0)throw new Error(`Invalid parameter: ${_(n)}. Must be wrapped in <> (required parameter) or [] (optional parameter)`);let c=n.slice(1,-1);const l=c.slice(-3)==="...";l&&(r=n,c=c.slice(0,-3)),t.push({name:c,required:i,spread:l})}return t}function L(e,t,s){for(let r=0;r<t.length;r+=1){const{name:n,required:o,spread:a}=t[r],i=Oe(n);if(i in e)return new Error(`Invalid parameter: ${_(n)} is used more than once.`);const c=a?s.slice(r):s[r];if(a&&(r=t.length),o&&(!c||a&&c.length===0))return new Error(`Error: Missing required parameter ${_(n)}`);e[i]=c}}var ie=(e,t,s)=>{if(!t.has(e))throw TypeError("Cannot "+s)},h=(e,t,s)=>(ie(e,t,"read from private field"),s?s.call(e):t.get(e)),g=(e,t,s)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,s)},C=(e,t,s,r)=>(ie(e,t,"write to private field"),r?r.call(e,s):t.set(e,s),s),v,y,E,b,S,I,N,P,ae,B,ce;const u=Symbol("Root"),le=class{constructor(e,t,s){g(this,P),g(this,B),g(this,v,""),g(this,y,""),g(this,E,""),g(this,b,[]),g(this,S,{}),g(this,I,new fe),g(this,N,new Set),C(this,v,e||h(this,v)),C(this,y,t||h(this,y)),C(this,E,s||h(this,E))}get _name(){return h(this,v)}get _description(){return h(this,y)}get _version(){return h(this,E)}get _inspectors(){return h(this,b)}get _commands(){return h(this,S)}static create(e,t,s){return new le(e,t,s)}name(e){return C(this,v,e),this}description(e){return C(this,y,e),this}version(e){return C(this,E,e),this}command(e,t,s={}){const n=(f=>!(typeof f=="string"||f===u))(e),o=n?e.name:e;if(ne(o))throw new Z(o);const{handler:a=void 0,...i}=n?e:{name:o,description:t,...s},c=[i.name],l=i.alias?W(i.alias):[];i.alias&&c.push(...l);for(const f of c)if(h(this,N).has(f))throw new G(oe(f));return h(this,S)[o]=i,h(this,N).add(i.name),l.forEach(f=>h(this,N).add(f)),n&&a&&this.on(e.name,a),this}on(e,t){return h(this,I).on(e,t),this}use(e){return e.setup(this)}inspector(e){return h(this,b).push(e),this}parse(e=se()){if(!h(this,v))throw new U;if(!h(this,y))throw new z;if(!h(this,E))throw new K;const t=te(e),s=t.join(" "),r=()=>Y(h(this,S),t),n=[],o=()=>{n.length=0;const l=r(),f=!!l,p=xe((l==null?void 0:l.flags)||{},[...e]),{_:d,flags:$,unknownFlags:M}=p;let w=!f||l.name===u?d:d.slice(l.name.split(" ").length),m=(l==null?void 0:l.parameters)||[];const R=m.indexOf("--"),D=m.slice(R+1)||[],x=Object.create(null);if(R>-1&&D.length>0){m=m.slice(0,R);const j=d["--"];w=w.slice(0,-j.length||void 0),n.push(L(x,F(m),w)),n.push(L(x,F(D),j))}else n.push(L(x,F(m),w));const he={...$,...M};return{name:l==null?void 0:l.name,called:t.length===0&&(l==null?void 0:l.name)?u:s,resolved:f,hasRootOrAlias:h(this,P,ae),hasRoot:h(this,B,ce),raw:{...p,parameters:w,mergedFlags:he},parameters:x,flags:$,unknownFlags:M,cli:this}},a={enforce:"post",fn:()=>{const l=r(),f=o(),p=n.filter(Boolean);if(p.length>0)throw p[0];if(!l)throw s?new V(s):new H;h(this,I).emit(l.name,f)}},i=[...h(this,b),a];return re(i)(o),this}};let Be=le;v=new WeakMap,y=new WeakMap,E=new WeakMap,b=new WeakMap,S=new WeakMap,I=new WeakMap,N=new WeakMap,P=new WeakSet,ae=function(){return h(this,N).has(u)},B=new WeakSet,ce=function(){return Object.prototype.hasOwnProperty.call(this._commands,u)};const De=e=>e,je=(e,t,s)=>s,Te=(e,t)=>t,qe=(e,t)=>({...e,handler:t});export{Be as Clerc,G as CommandExistsError,J as CommandNameConflictError,z as DescriptionNotSetError,Z as InvalidCommandNameError,U as NameNotSetError,H as NoCommandGivenError,V as NoSuchCommandError,u as Root,K as VersionNotSetError,re as compose,qe as defineCommand,je as defineHandler,Te as defineInspector,De as definePlugin,oe as formatCommandName,ne as isInvalidName,se as resolveArgv,Y as resolveCommand,X as resolveFlattenCommands,te as resolveParametersBeforeFlag,Fe as resolveRootCommands,ee as resolveSubcommandsByParent,Le as withBrackets};
package/dist/index.mjs CHANGED
@@ -1,410 +1 @@
1
- import { LiteEmit } from 'lite-emit';
2
- import { typeFlag } from 'type-flag';
3
- import { toArray, arrayStartsWith, camelCase } from '@clerc/utils';
4
- import { isNode, isDeno } from 'is-platform';
5
-
6
- class CommandExistsError extends Error {
7
- constructor(commandName) {
8
- super(`Command "${commandName}" exists.`);
9
- this.commandName = commandName;
10
- }
11
- }
12
- class NoSuchCommandError extends Error {
13
- constructor(commandName) {
14
- super(`No such command: ${commandName}`);
15
- this.commandName = commandName;
16
- }
17
- }
18
- class NoCommandGivenError extends Error {
19
- constructor() {
20
- super("No command given.");
21
- }
22
- }
23
- class CommandNameConflictError extends Error {
24
- constructor(n1, n2) {
25
- super(`Command name ${n1} conflicts with ${n2}. Maybe caused by alias.`);
26
- this.n1 = n1;
27
- this.n2 = n2;
28
- }
29
- }
30
- class NameNotSetError extends Error {
31
- constructor() {
32
- super("Name not set.");
33
- }
34
- }
35
- class DescriptionNotSetError extends Error {
36
- constructor() {
37
- super("Description not set.");
38
- }
39
- }
40
- class VersionNotSetError extends Error {
41
- constructor() {
42
- super("Version not set.");
43
- }
44
- }
45
- class InvalidCommandNameError extends Error {
46
- constructor(commandName) {
47
- super(`Bad name format: ${commandName}`);
48
- this.commandName = commandName;
49
- }
50
- }
51
-
52
- function setCommand(commandsMap, commands, command) {
53
- if (command.alias) {
54
- const aliases = toArray(command.alias);
55
- for (const alias of aliases) {
56
- if (alias in commands) {
57
- throw new CommandNameConflictError(commands[alias].name, command.name);
58
- }
59
- commandsMap.set(typeof alias === "symbol" ? alias : alias.split(" "), { ...command, __isAlias: true });
60
- }
61
- }
62
- }
63
- function resolveFlattenCommands(commands) {
64
- const commandsMap = /* @__PURE__ */ new Map();
65
- if (commands[Root]) {
66
- commandsMap.set(Root, commands[Root]);
67
- setCommand(commandsMap, commands, commands[Root]);
68
- }
69
- for (const command of Object.values(commands)) {
70
- setCommand(commandsMap, commands, command);
71
- commandsMap.set(command.name.split(" "), command);
72
- }
73
- return commandsMap;
74
- }
75
- function resolveCommand(commands, name) {
76
- if (name === Root) {
77
- return commands[Root];
78
- }
79
- const nameArr = toArray(name);
80
- const commandsMap = resolveFlattenCommands(commands);
81
- let current;
82
- let currentName;
83
- commandsMap.forEach((v, k) => {
84
- if (k === Root) {
85
- current = commandsMap.get(Root);
86
- currentName = Root;
87
- return;
88
- }
89
- if (arrayStartsWith(nameArr, k) && (!currentName || currentName === Root || k.length > currentName.length)) {
90
- current = v;
91
- currentName = k;
92
- }
93
- });
94
- return current;
95
- }
96
- function resolveSubcommandsByParent(commands, parent, depth = Infinity) {
97
- const parentArr = parent === "" ? [] : Array.isArray(parent) ? parent : parent.split(" ");
98
- return Object.values(commands).filter((c) => {
99
- const commandNameArr = c.name.split(" ");
100
- return arrayStartsWith(commandNameArr, parentArr) && commandNameArr.length - parentArr.length <= depth;
101
- });
102
- }
103
- const resolveRootCommands = (commands) => resolveSubcommandsByParent(commands, "", 1);
104
- function resolveParametersBeforeFlag(argv) {
105
- const parameters = [];
106
- for (const arg of argv) {
107
- if (arg.startsWith("-")) {
108
- break;
109
- }
110
- parameters.push(arg);
111
- }
112
- return parameters;
113
- }
114
- const resolveArgv = () => isNode() ? process.argv.slice(2) : isDeno() ? Deno.args : [];
115
- function compose(inspectors) {
116
- const inspectorMap = {
117
- pre: [],
118
- normal: [],
119
- post: []
120
- };
121
- for (const inspector of inspectors) {
122
- const objectInspector = typeof inspector === "object" ? inspector : { fn: inspector };
123
- const { enforce, fn } = objectInspector;
124
- if (enforce === "post" || enforce === "pre") {
125
- inspectorMap[enforce].push(fn);
126
- } else {
127
- inspectorMap.normal.push(fn);
128
- }
129
- }
130
- const mergedInspectorFns = [
131
- ...inspectorMap.pre,
132
- ...inspectorMap.normal,
133
- ...inspectorMap.post
134
- ];
135
- return (getCtx) => {
136
- return dispatch(0);
137
- function dispatch(i) {
138
- const inspector = mergedInspectorFns[i];
139
- return inspector(getCtx(), dispatch.bind(null, i + 1));
140
- }
141
- };
142
- }
143
- const isInvalidName = (name) => typeof name === "string" && (name.startsWith(" ") || name.endsWith(" "));
144
- const withBrackets = (s, isOptional) => isOptional ? `[${s}]` : `<${s}>`;
145
- const ROOT = "<Root>";
146
- const formatCommandName = (name) => Array.isArray(name) ? name.join(" ") : typeof name === "string" ? name : ROOT;
147
-
148
- const { stringify } = JSON;
149
- function parseParameters(parameters) {
150
- const parsedParameters = [];
151
- let hasOptional;
152
- let hasSpread;
153
- for (const parameter of parameters) {
154
- if (hasSpread) {
155
- throw new Error(`Invalid parameter: Spread parameter ${stringify(hasSpread)} must be last`);
156
- }
157
- const firstCharacter = parameter[0];
158
- const lastCharacter = parameter[parameter.length - 1];
159
- let required;
160
- if (firstCharacter === "<" && lastCharacter === ">") {
161
- required = true;
162
- if (hasOptional) {
163
- throw new Error(`Invalid parameter: Required parameter ${stringify(parameter)} cannot come after optional parameter ${stringify(hasOptional)}`);
164
- }
165
- }
166
- if (firstCharacter === "[" && lastCharacter === "]") {
167
- required = false;
168
- hasOptional = parameter;
169
- }
170
- if (required === void 0) {
171
- throw new Error(`Invalid parameter: ${stringify(parameter)}. Must be wrapped in <> (required parameter) or [] (optional parameter)`);
172
- }
173
- let name = parameter.slice(1, -1);
174
- const spread = name.slice(-3) === "...";
175
- if (spread) {
176
- hasSpread = parameter;
177
- name = name.slice(0, -3);
178
- }
179
- parsedParameters.push({
180
- name,
181
- required,
182
- spread
183
- });
184
- }
185
- return parsedParameters;
186
- }
187
- function mapParametersToArguments(mapping, parameters, cliArguments) {
188
- for (let i = 0; i < parameters.length; i += 1) {
189
- const { name, required, spread } = parameters[i];
190
- const camelCaseName = camelCase(name);
191
- if (camelCaseName in mapping) {
192
- return new Error(`Invalid parameter: ${stringify(name)} is used more than once.`);
193
- }
194
- const value = spread ? cliArguments.slice(i) : cliArguments[i];
195
- if (spread) {
196
- i = parameters.length;
197
- }
198
- if (required && (!value || spread && value.length === 0)) {
199
- return new Error(`Error: Missing required parameter ${stringify(name)}`);
200
- }
201
- mapping[camelCaseName] = value;
202
- }
203
- }
204
-
205
- var __accessCheck = (obj, member, msg) => {
206
- if (!member.has(obj))
207
- throw TypeError("Cannot " + msg);
208
- };
209
- var __privateGet = (obj, member, getter) => {
210
- __accessCheck(obj, member, "read from private field");
211
- return getter ? getter.call(obj) : member.get(obj);
212
- };
213
- var __privateAdd = (obj, member, value) => {
214
- if (member.has(obj))
215
- throw TypeError("Cannot add the same private member more than once");
216
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
217
- };
218
- var __privateSet = (obj, member, value, setter) => {
219
- __accessCheck(obj, member, "write to private field");
220
- setter ? setter.call(obj, value) : member.set(obj, value);
221
- return value;
222
- };
223
- var _name, _description, _version, _inspectors, _commands, _commandEmitter, _usedNames, _hasRootOrAlias, hasRootOrAlias_get, _hasRoot, hasRoot_get;
224
- const Root = Symbol("Root");
225
- const _Clerc = class {
226
- constructor(name, description, version) {
227
- __privateAdd(this, _hasRootOrAlias);
228
- __privateAdd(this, _hasRoot);
229
- __privateAdd(this, _name, "");
230
- __privateAdd(this, _description, "");
231
- __privateAdd(this, _version, "");
232
- __privateAdd(this, _inspectors, []);
233
- __privateAdd(this, _commands, {});
234
- __privateAdd(this, _commandEmitter, new LiteEmit());
235
- __privateAdd(this, _usedNames, /* @__PURE__ */ new Set());
236
- __privateSet(this, _name, name || __privateGet(this, _name));
237
- __privateSet(this, _description, description || __privateGet(this, _description));
238
- __privateSet(this, _version, version || __privateGet(this, _version));
239
- }
240
- get _name() {
241
- return __privateGet(this, _name);
242
- }
243
- get _description() {
244
- return __privateGet(this, _description);
245
- }
246
- get _version() {
247
- return __privateGet(this, _version);
248
- }
249
- get _inspectors() {
250
- return __privateGet(this, _inspectors);
251
- }
252
- get _commands() {
253
- return __privateGet(this, _commands);
254
- }
255
- static create(name, description, version) {
256
- return new _Clerc(name, description, version);
257
- }
258
- name(name) {
259
- __privateSet(this, _name, name);
260
- return this;
261
- }
262
- description(description) {
263
- __privateSet(this, _description, description);
264
- return this;
265
- }
266
- version(version) {
267
- __privateSet(this, _version, version);
268
- return this;
269
- }
270
- command(nameOrCommand, description, options = {}) {
271
- const checkIsCommandObject = (nameOrCommand2) => !(typeof nameOrCommand2 === "string" || nameOrCommand2 === Root);
272
- const isCommandObject = checkIsCommandObject(nameOrCommand);
273
- const name = !isCommandObject ? nameOrCommand : nameOrCommand.name;
274
- if (isInvalidName(name)) {
275
- throw new InvalidCommandNameError(name);
276
- }
277
- const { handler = void 0, ...commandToSave } = isCommandObject ? nameOrCommand : { name, description, ...options };
278
- const nameList = [commandToSave.name];
279
- commandToSave.alias && nameList.push(...toArray(commandToSave.alias));
280
- for (const name2 of nameList) {
281
- if (__privateGet(this, _usedNames).has(name2)) {
282
- throw new CommandExistsError(formatCommandName(name2));
283
- }
284
- }
285
- __privateGet(this, _commands)[name] = commandToSave;
286
- __privateGet(this, _usedNames).add(commandToSave.name);
287
- (toArray(commandToSave.alias) || []).forEach((a) => __privateGet(this, _usedNames).add(a));
288
- isCommandObject && handler && this.on(nameOrCommand.name, handler);
289
- return this;
290
- }
291
- on(name, handler) {
292
- __privateGet(this, _commandEmitter).on(name, handler);
293
- return this;
294
- }
295
- use(plugin) {
296
- return plugin.setup(this);
297
- }
298
- inspector(inspector) {
299
- __privateGet(this, _inspectors).push(inspector);
300
- return this;
301
- }
302
- parse(argv = resolveArgv()) {
303
- if (!__privateGet(this, _name)) {
304
- throw new NameNotSetError();
305
- }
306
- if (!__privateGet(this, _description)) {
307
- throw new DescriptionNotSetError();
308
- }
309
- if (!__privateGet(this, _version)) {
310
- throw new VersionNotSetError();
311
- }
312
- const name = resolveParametersBeforeFlag(argv);
313
- const stringName = name.join(" ");
314
- const getCommand = () => resolveCommand(__privateGet(this, _commands), name);
315
- const mapErrors = [];
316
- const getContext = () => {
317
- mapErrors.length = 0;
318
- const command = getCommand();
319
- const isCommandResolved = !!command;
320
- const parsed = typeFlag((command == null ? void 0 : command.flags) || {}, [...argv]);
321
- const { _: args, flags, unknownFlags } = parsed;
322
- let parameters = !isCommandResolved || command.name === Root ? args : args.slice(command.name.split(" ").length);
323
- let commandParameters = (command == null ? void 0 : command.parameters) || [];
324
- const hasEof = commandParameters.indexOf("--");
325
- const eofParameters = commandParameters.slice(hasEof + 1) || [];
326
- const mapping = /* @__PURE__ */ Object.create(null);
327
- if (hasEof > -1 && eofParameters.length > 0) {
328
- commandParameters = commandParameters.slice(0, hasEof);
329
- const eofArguments = args["--"];
330
- parameters = parameters.slice(0, -eofArguments.length || void 0);
331
- mapErrors.push(mapParametersToArguments(
332
- mapping,
333
- parseParameters(commandParameters),
334
- parameters
335
- ));
336
- mapErrors.push(mapParametersToArguments(
337
- mapping,
338
- parseParameters(eofParameters),
339
- eofArguments
340
- ));
341
- } else {
342
- mapErrors.push(mapParametersToArguments(
343
- mapping,
344
- parseParameters(commandParameters),
345
- parameters
346
- ));
347
- }
348
- const mergedFlags = { ...flags, ...unknownFlags };
349
- const context = {
350
- name: command == null ? void 0 : command.name,
351
- called: name.length === 0 && (command == null ? void 0 : command.name) ? Root : stringName,
352
- resolved: isCommandResolved,
353
- hasRootOrAlias: __privateGet(this, _hasRootOrAlias, hasRootOrAlias_get),
354
- hasRoot: __privateGet(this, _hasRoot, hasRoot_get),
355
- raw: { ...parsed, parameters, mergedFlags },
356
- parameters: mapping,
357
- flags,
358
- unknownFlags,
359
- cli: this
360
- };
361
- return context;
362
- };
363
- const emitHandler = {
364
- enforce: "post",
365
- fn: () => {
366
- const command = getCommand();
367
- const handlerContext = getContext();
368
- const errors = mapErrors.filter(Boolean);
369
- if (errors.length > 0) {
370
- throw errors[0];
371
- }
372
- if (!command) {
373
- if (stringName) {
374
- throw new NoSuchCommandError(stringName);
375
- } else {
376
- throw new NoCommandGivenError();
377
- }
378
- }
379
- __privateGet(this, _commandEmitter).emit(command.name, handlerContext);
380
- }
381
- };
382
- const inspectors = [...__privateGet(this, _inspectors), emitHandler];
383
- const callInspector = compose(inspectors);
384
- callInspector(getContext);
385
- return this;
386
- }
387
- };
388
- let Clerc = _Clerc;
389
- _name = new WeakMap();
390
- _description = new WeakMap();
391
- _version = new WeakMap();
392
- _inspectors = new WeakMap();
393
- _commands = new WeakMap();
394
- _commandEmitter = new WeakMap();
395
- _usedNames = new WeakMap();
396
- _hasRootOrAlias = new WeakSet();
397
- hasRootOrAlias_get = function() {
398
- return __privateGet(this, _usedNames).has(Root);
399
- };
400
- _hasRoot = new WeakSet();
401
- hasRoot_get = function() {
402
- return Object.prototype.hasOwnProperty.call(this._commands, Root);
403
- };
404
-
405
- const definePlugin = (p) => p;
406
- const defineHandler = (_cli, _key, handler) => handler;
407
- const defineInspector = (_cli, inspector) => inspector;
408
- const defineCommand = (command, handler) => ({ ...command, handler });
409
-
410
- export { Clerc, CommandExistsError, CommandNameConflictError, DescriptionNotSetError, InvalidCommandNameError, NameNotSetError, NoCommandGivenError, NoSuchCommandError, Root, VersionNotSetError, compose, defineCommand, defineHandler, defineInspector, definePlugin, formatCommandName, isInvalidName, resolveArgv, resolveCommand, resolveFlattenCommands, resolveParametersBeforeFlag, resolveRootCommands, resolveSubcommandsByParent, withBrackets };
1
+ class fe{constructor(){this.listenerMap={},this.wildcardListeners=new Set}on(t,s){return t==="*"?(this.wildcardListeners.add(s),this):(this.listenerMap[t]||(this.listenerMap[t]=new Set),this.listenerMap[t].add(s),this)}emit(t,...s){return this.listenerMap[t]&&(this.wildcardListeners.forEach(r=>r(t,...s)),this.listenerMap[t].forEach(r=>r(...s))),this}off(t,s){var r,n;return t==="**"?(this.listenerMap={},this.wildcardListeners.clear(),this):t==="*"?(s?this.wildcardListeners.delete(s):this.wildcardListeners.clear(),this):(s?(r=this.listenerMap[t])==null||r.delete(s):(n=this.listenerMap[t])==null||n.clear(),this)}}const ue="known-flag",pe="unknown-flag",de="argument",{stringify:A}=JSON,me=/\B([A-Z])/g,ge=e=>e.replace(me,"-$1").toLowerCase(),{hasOwnProperty:we}=Object.prototype,k=(e,t)=>we.call(e,t),ve=e=>Array.isArray(e),T=e=>typeof e=="function"?[e,!1]:ve(e)?[e[0],!0]:T(e.type),ye=(e,t)=>e===Boolean?t!=="false":t,Ee=(e,t)=>typeof t=="boolean"?t:e===Number&&t===""?Number.NaN:e(t),_e=/[\s.:=]/,Ce=e=>{const t=`Flag name ${A(e)}`;if(e.length===0)throw new Error(`${t} cannot be empty`);if(e.length===1)throw new Error(`${t} must be longer than a character`);const s=e.match(_e);if(s)throw new Error(`${t} cannot contain ${A(s==null?void 0:s[0])}`)},Ne=e=>{const t={},s=(r,n)=>{if(k(t,r))throw new Error(`Duplicate flags named ${A(r)}`);t[r]=n};for(const r in e){if(!k(e,r))continue;Ce(r);const n=e[r],o=[[],...T(n),n];s(r,o);const a=ge(r);if(r!==a&&s(a,o),"alias"in n&&typeof n.alias=="string"){const{alias:i}=n,c=`Flag alias ${A(i)} for flag ${A(r)}`;if(i.length===0)throw new Error(`${c} cannot be empty`);if(i.length>1)throw new Error(`${c} must be a single character`);s(i,o)}}return t},$e=(e,t)=>{const s={};for(const r in e){if(!k(e,r))continue;const[n,,o,a]=t[r];if(n.length===0&&"default"in a){let{default:i}=a;typeof i=="function"&&(i=i()),s[r]=i}else s[r]=o?n:n.pop()}return s},O="--",Me=/[.:=]/,Ae=/^-{1,2}\w/,ke=e=>{if(!Ae.test(e))return;const t=!e.startsWith(O);let s=e.slice(t?1:2),r;const n=s.match(Me);if(n){const{index:o}=n;r=s.slice(o+1),s=s.slice(0,o)}return[s,r,t]},be=(e,{onFlag:t,onArgument:s})=>{let r;const n=(o,a)=>{if(typeof r!="function")return!0;r(o,a),r=void 0};for(let o=0;o<e.length;o+=1){const a=e[o];if(a===O){n();const c=e.slice(o+1);s==null||s(c,[o],!0);break}const i=ke(a);if(i){if(n(),!t)continue;const[c,l,f]=i;if(f)for(let p=0;p<c.length;p+=1){n();const d=p===c.length-1;r=t(c[p],d?l:void 0,[o,p+1,d])}else r=t(c,l,[o])}else n(a,[o])&&(s==null||s([a],[o]))}n()},Se=(e,t)=>{for(const[s,r,n]of t.reverse()){if(r){const o=e[s];let a=o.slice(0,r);if(n||(a+=o.slice(r+1)),a!=="-"){e[s]=a;continue}}e.splice(s,1)}},xe=(e,t=process.argv.slice(2),{ignore:s}={})=>{const r=[],n=Ne(e),o={},a=[];return a[O]=[],be(t,{onFlag(i,c,l){const f=k(n,i);if(!(s!=null&&s(f?ue:pe,i,c))){if(f){const[p,d]=n[i],$=ye(d,c),M=(w,m)=>{r.push(l),m&&r.push(m),p.push(Ee(d,w||""))};return $===void 0?M:M($)}k(o,i)||(o[i]=[]),o[i].push(c===void 0?!0:c),r.push(l)}},onArgument(i,c,l){s!=null&&s(de,t[c[0]])||(a.push(...i),l?(a[O]=i,t.splice(c[0])):r.push(c))}}),Se(t,r),{flags:$e(e,n),unknownFlags:o,_:a}},W=e=>Array.isArray(e)?e:[e],Oe=e=>e.replace(/-([a-z])/g,(t,s)=>s.toUpperCase()),Ie=(e,t)=>t.length!==e.length?!1:e.every((s,r)=>s===t[r]),q=(e,t)=>t.length>e.length?!1:Ie(e.slice(0,t.length),t);class G extends Error{constructor(t){super(`Command "${t}" exists.`),this.commandName=t}}class V extends Error{constructor(t){super(`No such command: ${t}`),this.commandName=t}}class H extends Error{constructor(){super("No command given.")}}class J extends Error{constructor(t,s){super(`Command name ${t} conflicts with ${s}. Maybe caused by alias.`),this.n1=t,this.n2=s}}class U extends Error{constructor(){super("Name not set.")}}class z extends Error{constructor(){super("Description not set.")}}class K extends Error{constructor(){super("Version not set.")}}class Z extends Error{constructor(t){super(`Bad name format: ${t}`),this.commandName=t}}function Re(){return typeof process!="undefined"}function We(){return typeof Deno!="undefined"}function Q(e,t,s){if(s.alias){const r=W(s.alias);for(const n of r){if(n in t)throw new J(t[n].name,s.name);e.set(typeof n=="symbol"?n:n.split(" "),{...s,__isAlias:!0})}}}function X(e){const t=new Map;e[u]&&(t.set(u,e[u]),Q(t,e,e[u]));for(const s of Object.values(e))Q(t,e,s),t.set(s.name.split(" "),s);return t}function Y(e,t){if(t===u)return e[u];const s=W(t),r=X(e);let n,o;return r.forEach((a,i)=>{if(i===u){n=r.get(u),o=u;return}q(s,i)&&(!o||o===u||i.length>o.length)&&(n=a,o=i)}),n}function ee(e,t,s=1/0){const r=t===""?[]:Array.isArray(t)?t:t.split(" ");return Object.values(e).filter(n=>{const o=n.name.split(" ");return q(o,r)&&o.length-r.length<=s})}const Fe=e=>ee(e,"",1);function te(e){const t=[];for(const s of e){if(s.startsWith("-"))break;t.push(s)}return t}const se=()=>Re()?process.argv.slice(2):We()?Deno.args:[];function re(e){const t={pre:[],normal:[],post:[]};for(const r of e){const n=typeof r=="object"?r:{fn:r},{enforce:o,fn:a}=n;o==="post"||o==="pre"?t[o].push(a):t.normal.push(a)}const s=[...t.pre,...t.normal,...t.post];return r=>{return n(0);function n(o){const a=s[o];return a(r(),n.bind(null,o+1))}}}const ne=e=>typeof e=="string"&&(e.startsWith(" ")||e.endsWith(" ")),Le=(e,t)=>t?`[${e}]`:`<${e}>`,Pe="<Root>",oe=e=>Array.isArray(e)?e.join(" "):typeof e=="string"?e:Pe,{stringify:_}=JSON;function F(e){const t=[];let s,r;for(const n of e){if(r)throw new Error(`Invalid parameter: Spread parameter ${_(r)} must be last`);const o=n[0],a=n[n.length-1];let i;if(o==="<"&&a===">"&&(i=!0,s))throw new Error(`Invalid parameter: Required parameter ${_(n)} cannot come after optional parameter ${_(s)}`);if(o==="["&&a==="]"&&(i=!1,s=n),i===void 0)throw new Error(`Invalid parameter: ${_(n)}. Must be wrapped in <> (required parameter) or [] (optional parameter)`);let c=n.slice(1,-1);const l=c.slice(-3)==="...";l&&(r=n,c=c.slice(0,-3)),t.push({name:c,required:i,spread:l})}return t}function L(e,t,s){for(let r=0;r<t.length;r+=1){const{name:n,required:o,spread:a}=t[r],i=Oe(n);if(i in e)return new Error(`Invalid parameter: ${_(n)} is used more than once.`);const c=a?s.slice(r):s[r];if(a&&(r=t.length),o&&(!c||a&&c.length===0))return new Error(`Error: Missing required parameter ${_(n)}`);e[i]=c}}var ie=(e,t,s)=>{if(!t.has(e))throw TypeError("Cannot "+s)},h=(e,t,s)=>(ie(e,t,"read from private field"),s?s.call(e):t.get(e)),g=(e,t,s)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,s)},C=(e,t,s,r)=>(ie(e,t,"write to private field"),r?r.call(e,s):t.set(e,s),s),v,y,E,b,S,I,N,P,ae,B,ce;const u=Symbol("Root"),le=class{constructor(e,t,s){g(this,P),g(this,B),g(this,v,""),g(this,y,""),g(this,E,""),g(this,b,[]),g(this,S,{}),g(this,I,new fe),g(this,N,new Set),C(this,v,e||h(this,v)),C(this,y,t||h(this,y)),C(this,E,s||h(this,E))}get _name(){return h(this,v)}get _description(){return h(this,y)}get _version(){return h(this,E)}get _inspectors(){return h(this,b)}get _commands(){return h(this,S)}static create(e,t,s){return new le(e,t,s)}name(e){return C(this,v,e),this}description(e){return C(this,y,e),this}version(e){return C(this,E,e),this}command(e,t,s={}){const n=(f=>!(typeof f=="string"||f===u))(e),o=n?e.name:e;if(ne(o))throw new Z(o);const{handler:a=void 0,...i}=n?e:{name:o,description:t,...s},c=[i.name],l=i.alias?W(i.alias):[];i.alias&&c.push(...l);for(const f of c)if(h(this,N).has(f))throw new G(oe(f));return h(this,S)[o]=i,h(this,N).add(i.name),l.forEach(f=>h(this,N).add(f)),n&&a&&this.on(e.name,a),this}on(e,t){return h(this,I).on(e,t),this}use(e){return e.setup(this)}inspector(e){return h(this,b).push(e),this}parse(e=se()){if(!h(this,v))throw new U;if(!h(this,y))throw new z;if(!h(this,E))throw new K;const t=te(e),s=t.join(" "),r=()=>Y(h(this,S),t),n=[],o=()=>{n.length=0;const l=r(),f=!!l,p=xe((l==null?void 0:l.flags)||{},[...e]),{_:d,flags:$,unknownFlags:M}=p;let w=!f||l.name===u?d:d.slice(l.name.split(" ").length),m=(l==null?void 0:l.parameters)||[];const R=m.indexOf("--"),D=m.slice(R+1)||[],x=Object.create(null);if(R>-1&&D.length>0){m=m.slice(0,R);const j=d["--"];w=w.slice(0,-j.length||void 0),n.push(L(x,F(m),w)),n.push(L(x,F(D),j))}else n.push(L(x,F(m),w));const he={...$,...M};return{name:l==null?void 0:l.name,called:t.length===0&&(l==null?void 0:l.name)?u:s,resolved:f,hasRootOrAlias:h(this,P,ae),hasRoot:h(this,B,ce),raw:{...p,parameters:w,mergedFlags:he},parameters:x,flags:$,unknownFlags:M,cli:this}},a={enforce:"post",fn:()=>{const l=r(),f=o(),p=n.filter(Boolean);if(p.length>0)throw p[0];if(!l)throw s?new V(s):new H;h(this,I).emit(l.name,f)}},i=[...h(this,b),a];return re(i)(o),this}};let Be=le;v=new WeakMap,y=new WeakMap,E=new WeakMap,b=new WeakMap,S=new WeakMap,I=new WeakMap,N=new WeakMap,P=new WeakSet,ae=function(){return h(this,N).has(u)},B=new WeakSet,ce=function(){return Object.prototype.hasOwnProperty.call(this._commands,u)};const De=e=>e,je=(e,t,s)=>s,Te=(e,t)=>t,qe=(e,t)=>({...e,handler:t});export{Be as Clerc,G as CommandExistsError,J as CommandNameConflictError,z as DescriptionNotSetError,Z as InvalidCommandNameError,U as NameNotSetError,H as NoCommandGivenError,V as NoSuchCommandError,u as Root,K as VersionNotSetError,re as compose,qe as defineCommand,je as defineHandler,Te as defineInspector,De as definePlugin,oe as formatCommandName,ne as isInvalidName,se as resolveArgv,Y as resolveCommand,X as resolveFlattenCommands,te as resolveParametersBeforeFlag,Fe as resolveRootCommands,ee as resolveSubcommandsByParent,Le as withBrackets};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clerc/core",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "author": "Ray <nn_201312@163.com> (https://github.com/so1ve)",
5
5
  "description": "Clerc core",
6
6
  "keywords": [
@@ -46,15 +46,15 @@
46
46
  "publishConfig": {
47
47
  "access": "public"
48
48
  },
49
- "dependencies": {
49
+ "devDependencies": {
50
50
  "is-platform": "^0.2.0",
51
51
  "lite-emit": "^1.4.0",
52
- "type-fest": "^3.5.1",
52
+ "type-fest": "^3.5.3",
53
53
  "type-flag": "^3.0.0",
54
- "@clerc/utils": "0.25.0"
54
+ "@clerc/utils": "0.26.0"
55
55
  },
56
56
  "scripts": {
57
- "build": "puild",
57
+ "build": "puild --minify",
58
58
  "watch": "puild --watch"
59
59
  }
60
60
  }