clerc 0.4.0 → 0.6.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.cjs ADDED
@@ -0,0 +1,267 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var liteEmit = require('lite-emit');
6
+ var typeFlag = require('type-flag');
7
+ var utils = require('@clerc/utils');
8
+ var isPlatform = require('is-platform');
9
+
10
+ class SingleCommandError extends Error {
11
+ constructor() {
12
+ super("Single command mode enabled.");
13
+ }
14
+ }
15
+ class CommandExistsError extends Error {
16
+ }
17
+ class CommonCommandExistsError extends Error {
18
+ constructor() {
19
+ super("Common command exists.");
20
+ }
21
+ }
22
+ class NoSuchCommandError extends Error {
23
+ constructor(name) {
24
+ super(`No such command: ${name}`);
25
+ }
26
+ }
27
+ class ParentCommandExistsError extends Error {
28
+ constructor(name) {
29
+ super(`Command "${name}" cannot exist with its parent`);
30
+ }
31
+ }
32
+ class SubcommandExistsError extends Error {
33
+ constructor(name) {
34
+ super(`Command "${name}" cannot exist with its subcommand`);
35
+ }
36
+ }
37
+
38
+ const resolveFlagAlias = (_command) => Object.entries((_command == null ? void 0 : _command.flags) || {}).reduce((acc, [name, command]) => {
39
+ if (command.alias) {
40
+ const item = utils.mustArray(command.alias).map(utils.kebabCase);
41
+ acc[utils.kebabCase(name)] = item;
42
+ }
43
+ return acc;
44
+ }, {});
45
+ const resolveFlagDefault = (_command) => Object.entries((_command == null ? void 0 : _command.flags) || {}).reduce((acc, [name, command]) => {
46
+ const item = command.default;
47
+ if (item) {
48
+ acc[name] = item;
49
+ }
50
+ return acc;
51
+ }, {});
52
+ function resolveCommand(commands, name) {
53
+ if (name === SingleCommand) {
54
+ return commands[SingleCommand];
55
+ }
56
+ const nameArr = Array.isArray(name) ? name : name.split(" ");
57
+ const nameString = nameArr.join(" ");
58
+ const possibleCommands = Object.values(commands).filter(
59
+ (c) => utils.arrayStartsWith(nameArr, c.name.split(" ")) || utils.mustArray(c.alias || []).map(String).includes(nameString)
60
+ );
61
+ if (possibleCommands.length > 1) {
62
+ throw new Error(`Multiple commands found with name "${nameString}"`);
63
+ }
64
+ return possibleCommands[0];
65
+ }
66
+ function resolveSubcommandsByParent(commands, parent, depth = Infinity) {
67
+ const parentArr = parent === "" ? [] : Array.isArray(parent) ? parent : parent.split(" ");
68
+ return Object.values(commands).filter((c) => {
69
+ const commandNameArr = c.name.split(" ");
70
+ return utils.arrayStartsWith(commandNameArr, parentArr) && commandNameArr.length - parentArr.length <= depth;
71
+ });
72
+ }
73
+ const resolveRootCommands = (commands) => resolveSubcommandsByParent(commands, "", 1);
74
+ function resolveParametersBeforeFlag(argv) {
75
+ const parameters = [];
76
+ for (const arg of argv) {
77
+ if (arg.startsWith("-")) {
78
+ break;
79
+ }
80
+ parameters.push(arg);
81
+ }
82
+ return parameters;
83
+ }
84
+ const resolveArgv = () => isPlatform.isNode() ? process.argv.slice(2) : isPlatform.isDeno() ? Deno.args : [];
85
+ function compose(inspectors) {
86
+ return (getCtx) => {
87
+ return dispatch(0);
88
+ function dispatch(i) {
89
+ const inspector = inspectors[i];
90
+ return inspector(getCtx(), dispatch.bind(null, i + 1));
91
+ }
92
+ };
93
+ }
94
+
95
+ var __accessCheck = (obj, member, msg) => {
96
+ if (!member.has(obj))
97
+ throw TypeError("Cannot " + msg);
98
+ };
99
+ var __privateGet = (obj, member, getter) => {
100
+ __accessCheck(obj, member, "read from private field");
101
+ return getter ? getter.call(obj) : member.get(obj);
102
+ };
103
+ var __privateAdd = (obj, member, value) => {
104
+ if (member.has(obj))
105
+ throw TypeError("Cannot add the same private member more than once");
106
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
107
+ };
108
+ var __privateSet = (obj, member, value, setter) => {
109
+ __accessCheck(obj, member, "write to private field");
110
+ setter ? setter.call(obj, value) : member.set(obj, value);
111
+ return value;
112
+ };
113
+ var _name, _description, _version, _inspectors, _commands, _commandEmitter, _isSingleCommand, isSingleCommand_get, _hasCommands, hasCommands_get;
114
+ const SingleCommand = Symbol("SingleCommand");
115
+ const _Clerc = class {
116
+ constructor() {
117
+ __privateAdd(this, _isSingleCommand);
118
+ __privateAdd(this, _hasCommands);
119
+ __privateAdd(this, _name, "");
120
+ __privateAdd(this, _description, "");
121
+ __privateAdd(this, _version, "");
122
+ __privateAdd(this, _inspectors, []);
123
+ __privateAdd(this, _commands, {});
124
+ __privateAdd(this, _commandEmitter, new liteEmit.LiteEmit());
125
+ }
126
+ get _name() {
127
+ return __privateGet(this, _name);
128
+ }
129
+ get _description() {
130
+ return __privateGet(this, _description);
131
+ }
132
+ get _version() {
133
+ return __privateGet(this, _version);
134
+ }
135
+ get _inspectors() {
136
+ return __privateGet(this, _inspectors);
137
+ }
138
+ get _commands() {
139
+ return __privateGet(this, _commands);
140
+ }
141
+ static create() {
142
+ return new _Clerc();
143
+ }
144
+ name(name) {
145
+ __privateSet(this, _name, name);
146
+ return this;
147
+ }
148
+ description(description) {
149
+ __privateSet(this, _description, description);
150
+ return this;
151
+ }
152
+ version(version) {
153
+ __privateSet(this, _version, version);
154
+ return this;
155
+ }
156
+ command(name, description, options = {}) {
157
+ if (__privateGet(this, _commands)[name]) {
158
+ if (name === SingleCommand) {
159
+ throw new CommandExistsError("Single command already exists");
160
+ }
161
+ throw new CommandExistsError(`Command "${name === SingleCommand ? "[SingleCommand]" : name}" already exists`);
162
+ }
163
+ if (__privateGet(this, _isSingleCommand, isSingleCommand_get)) {
164
+ throw new SingleCommandError();
165
+ }
166
+ if (name === SingleCommand && __privateGet(this, _hasCommands, hasCommands_get)) {
167
+ throw new CommonCommandExistsError();
168
+ }
169
+ if (name !== SingleCommand) {
170
+ const splitedName = name.split(" ");
171
+ const existedCommandNames = Object.keys(__privateGet(this, _commands)).filter((name2) => typeof name2 === "string").map((name2) => name2.split(" "));
172
+ if (existedCommandNames.some((name2) => utils.arrayStartsWith(splitedName, name2))) {
173
+ throw new ParentCommandExistsError(splitedName.join(" "));
174
+ }
175
+ if (existedCommandNames.some((name2) => utils.arrayStartsWith(name2, splitedName))) {
176
+ throw new SubcommandExistsError(splitedName.join(" "));
177
+ }
178
+ }
179
+ __privateGet(this, _commands)[name] = { name, description, ...options };
180
+ return this;
181
+ }
182
+ on(name, handler) {
183
+ __privateGet(this, _commandEmitter).on(name, handler);
184
+ return this;
185
+ }
186
+ use(plugin) {
187
+ return plugin.setup(this);
188
+ }
189
+ inspector(inspector) {
190
+ __privateGet(this, _inspectors).push(inspector);
191
+ return this;
192
+ }
193
+ parse(argv = resolveArgv()) {
194
+ const name = resolveParametersBeforeFlag(argv);
195
+ const stringName = name.join(" ");
196
+ const getCommand = () => __privateGet(this, _isSingleCommand, isSingleCommand_get) ? __privateGet(this, _commands)[SingleCommand] : resolveCommand(__privateGet(this, _commands), name);
197
+ const getContext = () => {
198
+ const command = getCommand();
199
+ const isCommandResolved = !!command;
200
+ const parsedWithType = typeFlag.typeFlag((command == null ? void 0 : command.flags) || {}, [...argv]);
201
+ const { _: args, flags } = parsedWithType;
202
+ const parameters = __privateGet(this, _isSingleCommand, isSingleCommand_get) || !isCommandResolved ? args : args.slice(command.name.split(" ").length);
203
+ const context = {
204
+ name: command == null ? void 0 : command.name,
205
+ resolved: isCommandResolved,
206
+ isSingleCommand: __privateGet(this, _isSingleCommand, isSingleCommand_get),
207
+ raw: parsedWithType,
208
+ parameters,
209
+ flags,
210
+ unknownFlags: parsedWithType.unknownFlags,
211
+ cli: this
212
+ };
213
+ return context;
214
+ };
215
+ const emitHandler = () => {
216
+ const command = getCommand();
217
+ const handlerContext = getContext();
218
+ if (!command) {
219
+ throw new NoSuchCommandError(stringName);
220
+ }
221
+ __privateGet(this, _commandEmitter).emit(command.name, handlerContext);
222
+ };
223
+ const inspectors = [...__privateGet(this, _inspectors), emitHandler];
224
+ const inspector = compose(inspectors);
225
+ inspector(getContext);
226
+ return this;
227
+ }
228
+ };
229
+ let Clerc = _Clerc;
230
+ _name = new WeakMap();
231
+ _description = new WeakMap();
232
+ _version = new WeakMap();
233
+ _inspectors = new WeakMap();
234
+ _commands = new WeakMap();
235
+ _commandEmitter = new WeakMap();
236
+ _isSingleCommand = new WeakSet();
237
+ isSingleCommand_get = function() {
238
+ return __privateGet(this, _commands)[SingleCommand] !== void 0;
239
+ };
240
+ _hasCommands = new WeakSet();
241
+ hasCommands_get = function() {
242
+ return Object.keys(__privateGet(this, _commands)).length > 0;
243
+ };
244
+
245
+ const definePlugin = (p) => p;
246
+ const defineHandler = (_cli, _key, handler) => handler;
247
+ const defineInspector = (_cli, inspector) => inspector;
248
+
249
+ exports.Clerc = Clerc;
250
+ exports.CommandExistsError = CommandExistsError;
251
+ exports.CommonCommandExistsError = CommonCommandExistsError;
252
+ exports.NoSuchCommandError = NoSuchCommandError;
253
+ exports.ParentCommandExistsError = ParentCommandExistsError;
254
+ exports.SingleCommand = SingleCommand;
255
+ exports.SingleCommandError = SingleCommandError;
256
+ exports.SubcommandExistsError = SubcommandExistsError;
257
+ exports.compose = compose;
258
+ exports.defineHandler = defineHandler;
259
+ exports.defineInspector = defineInspector;
260
+ exports.definePlugin = definePlugin;
261
+ exports.resolveArgv = resolveArgv;
262
+ exports.resolveCommand = resolveCommand;
263
+ exports.resolveFlagAlias = resolveFlagAlias;
264
+ exports.resolveFlagDefault = resolveFlagDefault;
265
+ exports.resolveParametersBeforeFlag = resolveParametersBeforeFlag;
266
+ exports.resolveRootCommands = resolveRootCommands;
267
+ exports.resolveSubcommandsByParent = resolveSubcommandsByParent;
@@ -0,0 +1,284 @@
1
+ import * as _clerc_utils from '@clerc/utils';
2
+ import { MaybeArray, Dict, LiteralUnion } from '@clerc/utils';
3
+
4
+ declare const DOUBLE_DASH = "--";
5
+ type TypeFunction<ReturnType = any> = (value: any) => ReturnType;
6
+ type TypeFunctionArray<ReturnType> = readonly [TypeFunction<ReturnType>];
7
+ type FlagType<ReturnType = any> = TypeFunction<ReturnType> | TypeFunctionArray<ReturnType>;
8
+ type FlagSchemaBase<TF> = {
9
+ /**
10
+ Type of the flag as a function that parses the argv string and returns the parsed value.
11
+
12
+ @example
13
+ ```
14
+ type: String
15
+ ```
16
+
17
+ @example Wrap in an array to accept multiple values.
18
+ ```
19
+ type: [Boolean]
20
+ ```
21
+
22
+ @example Custom function type that uses moment.js to parse string as date.
23
+ ```
24
+ type: function CustomDate(value: string) {
25
+ return moment(value).toDate();
26
+ }
27
+ ```
28
+ */
29
+ type: TF;
30
+ /**
31
+ A single-character alias for the flag.
32
+
33
+ @example
34
+ ```
35
+ alias: 's'
36
+ ```
37
+ */
38
+ alias?: string;
39
+ } & Record<PropertyKey, unknown>;
40
+ type FlagSchemaDefault<TF, DefaultType = any> = FlagSchemaBase<TF> & {
41
+ /**
42
+ Default value of the flag. Also accepts a function that returns the default value.
43
+ [Default: undefined]
44
+
45
+ @example
46
+ ```
47
+ default: 'hello'
48
+ ```
49
+
50
+ @example
51
+ ```
52
+ default: () => [1, 2, 3]
53
+ ```
54
+ */
55
+ default: DefaultType | (() => DefaultType);
56
+ };
57
+ type FlagSchema<TF = FlagType> = (FlagSchemaBase<TF> | FlagSchemaDefault<TF>);
58
+ type FlagTypeOrSchema<ExtraOptions = Record<string, unknown>> = FlagType | (FlagSchema & ExtraOptions);
59
+ type Flags<ExtraOptions = Record<string, unknown>> = Record<string, FlagTypeOrSchema<ExtraOptions>>;
60
+ type InferFlagType<Flag extends FlagTypeOrSchema> = (Flag extends (TypeFunctionArray<infer T> | FlagSchema<TypeFunctionArray<infer T>>) ? (Flag extends FlagSchemaDefault<TypeFunctionArray<T>, infer D> ? T[] | D : T[]) : (Flag extends TypeFunction<infer T> | FlagSchema<TypeFunction<infer T>> ? (Flag extends FlagSchemaDefault<TypeFunction<T>, infer D> ? T | D : T | undefined) : never));
61
+ interface ParsedFlags<Schemas = Record<string, unknown>> {
62
+ flags: Schemas;
63
+ unknownFlags: Record<string, (string | boolean)[]>;
64
+ _: string[] & {
65
+ [DOUBLE_DASH]: string[];
66
+ };
67
+ }
68
+ type TypeFlag<Schemas extends Flags> = ParsedFlags<{
69
+ [flag in keyof Schemas]: InferFlagType<Schemas[flag]>;
70
+ }>;
71
+
72
+ type FlagOptions = FlagSchema & {
73
+ description: string;
74
+ required?: boolean;
75
+ };
76
+ type Flag = FlagOptions & {
77
+ name: string;
78
+ };
79
+ interface CommandOptions<A extends MaybeArray<string> = MaybeArray<string>, F extends Dict<FlagOptions> = Dict<FlagOptions>> {
80
+ alias?: A;
81
+ flags?: F;
82
+ examples?: [string, string][];
83
+ notes?: string[];
84
+ }
85
+ type Command<N extends string | SingleCommandType = string, D extends string = string, Options extends CommandOptions = CommandOptions> = Options & {
86
+ name: N;
87
+ description: D;
88
+ };
89
+ type CommandRecord = Dict<Command> & {
90
+ [SingleCommand]?: Command;
91
+ };
92
+ type MakeEventMap<T extends CommandRecord> = {
93
+ [K in keyof T]: [InspectorContext];
94
+ };
95
+ type PossibleInputKind = string | number | boolean | Dict<any>;
96
+ type NonNullableFlag<T extends Dict<FlagOptions> | undefined> = T extends undefined ? {} : NonNullable<T>;
97
+ interface HandlerContext<C extends CommandRecord = CommandRecord, N extends keyof C = keyof C> {
98
+ name?: N;
99
+ resolved: boolean;
100
+ isSingleCommand: boolean;
101
+ raw: ParsedFlags;
102
+ parameters: PossibleInputKind[];
103
+ unknownFlags: ParsedFlags["unknownFlags"];
104
+ flags: TypeFlag<NonNullableFlag<C[N]["flags"]>>["flags"];
105
+ cli: Clerc<C>;
106
+ }
107
+ type Handler<C extends CommandRecord = CommandRecord, K extends keyof C = keyof C> = (ctx: HandlerContext<C, K>) => void;
108
+ type FallbackType<T, U> = {} extends T ? U : T;
109
+ type InspectorContext<C extends CommandRecord = CommandRecord> = HandlerContext<C> & {
110
+ flags: FallbackType<TypeFlag<NonNullableFlag<C[keyof C]["flags"]>>["flags"], Dict<any>>;
111
+ };
112
+ type Inspector<C extends CommandRecord = CommandRecord> = (ctx: InspectorContext<C>, next: () => void) => void;
113
+ interface Plugin<T extends Clerc = Clerc, U extends Clerc = Clerc> {
114
+ setup: (cli: T) => U;
115
+ }
116
+
117
+ declare const SingleCommand: unique symbol;
118
+ type SingleCommandType = typeof SingleCommand;
119
+ declare class Clerc<C extends CommandRecord = {}> {
120
+ #private;
121
+ private constructor();
122
+ get _name(): string;
123
+ get _description(): string;
124
+ get _version(): string;
125
+ get _inspectors(): Inspector<CommandRecord>[];
126
+ get _commands(): C;
127
+ /**
128
+ * Create a new cli
129
+ * @returns
130
+ * @example
131
+ * ```ts
132
+ * const cli = Clerc.create()
133
+ * ```
134
+ */
135
+ static create(): Clerc<{}>;
136
+ /**
137
+ * Set the name of the cli
138
+ * @param name
139
+ * @returns
140
+ * @example
141
+ * ```ts
142
+ * Clerc.create()
143
+ * .name("test")
144
+ * ```
145
+ */
146
+ name(name: string): this;
147
+ /**
148
+ * Set the description of the cli
149
+ * @param description
150
+ * @returns
151
+ * @example
152
+ * ```ts
153
+ * Clerc.create()
154
+ * .description("test cli")
155
+ */
156
+ description(description: string): this;
157
+ /**
158
+ * Set the version of the cli
159
+ * @param version
160
+ * @returns
161
+ * @example
162
+ * ```ts
163
+ * Clerc.create()
164
+ * .version("1.0.0")
165
+ */
166
+ version(version: string): this;
167
+ /**
168
+ * Register a command
169
+ * @param name
170
+ * @param description
171
+ * @param options
172
+ * @returns
173
+ * @example
174
+ * ```ts
175
+ * Clerc.create()
176
+ * .command("test", "test command", {
177
+ * alias: "t",
178
+ * flags: {
179
+ * foo: {
180
+ * alias: "f",
181
+ * description: "foo flag",
182
+ * }
183
+ * }
184
+ * })
185
+ * ```
186
+ * @example
187
+ * ```ts
188
+ * Clerc.create()
189
+ * .command("", "single command", {
190
+ * flags: {
191
+ * foo: {
192
+ * alias: "f",
193
+ * description: "foo flag",
194
+ * }
195
+ * }
196
+ * })
197
+ * ```
198
+ */
199
+ command<N extends string | SingleCommandType, D extends string, O extends CommandOptions>(name: N, description: D, options?: O): this & Clerc<C & Record<N, Command<N, D, O>>>;
200
+ /**
201
+ * Register a handler
202
+ * @param name
203
+ * @param handler
204
+ * @returns
205
+ * @example
206
+ * ```ts
207
+ * Clerc.create()
208
+ * .command("test", "test command")
209
+ * .on("test", (ctx) => {
210
+ * console.log(ctx);
211
+ * })
212
+ * ```
213
+ */
214
+ on<K extends keyof CM, CM extends this["_commands"] = this["_commands"]>(name: LiteralUnion<K, string>, handler: Handler<CM, K>): this;
215
+ /**
216
+ * Use a plugin
217
+ * @param plugin
218
+ * @returns
219
+ * @example
220
+ * ```ts
221
+ * Clerc.create()
222
+ * .use(plugin)
223
+ * ```
224
+ */
225
+ use<T extends Clerc, U extends Clerc>(plugin: Plugin<T, U>): U;
226
+ /**
227
+ * Register a inspector
228
+ * @param inspector
229
+ * @returns
230
+ * @example
231
+ * ```ts
232
+ * Clerc.create()
233
+ * .inspector((ctx, next) => {
234
+ * console.log(ctx);
235
+ * next();
236
+ * })
237
+ * ```
238
+ */
239
+ inspector(inspector: Inspector): this;
240
+ /**
241
+ * Parse the command line arguments
242
+ * @param args
243
+ * @returns
244
+ * @example
245
+ * ```ts
246
+ * Clerc.create()
247
+ * .parse(process.argv.slice(2)) // Optional
248
+ * ```
249
+ */
250
+ parse(argv?: string[]): this;
251
+ }
252
+
253
+ declare const definePlugin: <T extends Clerc<{}>, U extends Clerc<{}>>(p: Plugin<T, U>) => Plugin<T, U>;
254
+ declare const defineHandler: <C extends Clerc<{}>, K extends keyof C["_commands"]>(_cli: C, _key: K, handler: Handler<C["_commands"], K>) => Handler<C["_commands"], K>;
255
+ declare const defineInspector: <C extends Clerc<{}>>(_cli: C, inspector: Inspector<C["_commands"]>) => Inspector<C["_commands"]>;
256
+
257
+ declare class SingleCommandError extends Error {
258
+ constructor();
259
+ }
260
+ declare class CommandExistsError extends Error {
261
+ }
262
+ declare class CommonCommandExistsError extends Error {
263
+ constructor();
264
+ }
265
+ declare class NoSuchCommandError extends Error {
266
+ constructor(name: string);
267
+ }
268
+ declare class ParentCommandExistsError extends Error {
269
+ constructor(name: string);
270
+ }
271
+ declare class SubcommandExistsError extends Error {
272
+ constructor(name: string);
273
+ }
274
+
275
+ declare const resolveFlagAlias: (_command: Command) => Dict<string[]>;
276
+ declare const resolveFlagDefault: (_command: Command) => Dict<any>;
277
+ declare function resolveCommand(commands: CommandRecord, name: string | string[] | SingleCommandType): Command | undefined;
278
+ declare function resolveSubcommandsByParent(commands: CommandRecord, parent: string | string[], depth?: number): Command<string, string, CommandOptions<_clerc_utils.MaybeArray<string>, Dict<FlagOptions>>>[];
279
+ declare const resolveRootCommands: (commands: CommandRecord) => Command<string, string, CommandOptions<_clerc_utils.MaybeArray<string>, Dict<FlagOptions>>>[];
280
+ declare function resolveParametersBeforeFlag(argv: string[]): string[];
281
+ declare const resolveArgv: () => string[];
282
+ declare function compose(inspectors: Inspector[]): (getCtx: () => InspectorContext) => void;
283
+
284
+ export { Clerc, Command, CommandExistsError, CommandOptions, CommandRecord, CommonCommandExistsError, FallbackType, Flag, FlagOptions, Handler, HandlerContext, Inspector, InspectorContext, MakeEventMap, NoSuchCommandError, ParentCommandExistsError, Plugin, PossibleInputKind, SingleCommand, SingleCommandError, SingleCommandType, SubcommandExistsError, compose, defineHandler, defineInspector, definePlugin, resolveArgv, resolveCommand, resolveFlagAlias, resolveFlagDefault, resolveParametersBeforeFlag, resolveRootCommands, resolveSubcommandsByParent };
package/dist/index.mjs ADDED
@@ -0,0 +1,245 @@
1
+ import { LiteEmit } from 'lite-emit';
2
+ import { typeFlag } from 'type-flag';
3
+ import { mustArray, kebabCase, arrayStartsWith } from '@clerc/utils';
4
+ import { isNode, isDeno } from 'is-platform';
5
+
6
+ class SingleCommandError extends Error {
7
+ constructor() {
8
+ super("Single command mode enabled.");
9
+ }
10
+ }
11
+ class CommandExistsError extends Error {
12
+ }
13
+ class CommonCommandExistsError extends Error {
14
+ constructor() {
15
+ super("Common command exists.");
16
+ }
17
+ }
18
+ class NoSuchCommandError extends Error {
19
+ constructor(name) {
20
+ super(`No such command: ${name}`);
21
+ }
22
+ }
23
+ class ParentCommandExistsError extends Error {
24
+ constructor(name) {
25
+ super(`Command "${name}" cannot exist with its parent`);
26
+ }
27
+ }
28
+ class SubcommandExistsError extends Error {
29
+ constructor(name) {
30
+ super(`Command "${name}" cannot exist with its subcommand`);
31
+ }
32
+ }
33
+
34
+ const resolveFlagAlias = (_command) => Object.entries((_command == null ? void 0 : _command.flags) || {}).reduce((acc, [name, command]) => {
35
+ if (command.alias) {
36
+ const item = mustArray(command.alias).map(kebabCase);
37
+ acc[kebabCase(name)] = item;
38
+ }
39
+ return acc;
40
+ }, {});
41
+ const resolveFlagDefault = (_command) => Object.entries((_command == null ? void 0 : _command.flags) || {}).reduce((acc, [name, command]) => {
42
+ const item = command.default;
43
+ if (item) {
44
+ acc[name] = item;
45
+ }
46
+ return acc;
47
+ }, {});
48
+ function resolveCommand(commands, name) {
49
+ if (name === SingleCommand) {
50
+ return commands[SingleCommand];
51
+ }
52
+ const nameArr = Array.isArray(name) ? name : name.split(" ");
53
+ const nameString = nameArr.join(" ");
54
+ const possibleCommands = Object.values(commands).filter(
55
+ (c) => arrayStartsWith(nameArr, c.name.split(" ")) || mustArray(c.alias || []).map(String).includes(nameString)
56
+ );
57
+ if (possibleCommands.length > 1) {
58
+ throw new Error(`Multiple commands found with name "${nameString}"`);
59
+ }
60
+ return possibleCommands[0];
61
+ }
62
+ function resolveSubcommandsByParent(commands, parent, depth = Infinity) {
63
+ const parentArr = parent === "" ? [] : Array.isArray(parent) ? parent : parent.split(" ");
64
+ return Object.values(commands).filter((c) => {
65
+ const commandNameArr = c.name.split(" ");
66
+ return arrayStartsWith(commandNameArr, parentArr) && commandNameArr.length - parentArr.length <= depth;
67
+ });
68
+ }
69
+ const resolveRootCommands = (commands) => resolveSubcommandsByParent(commands, "", 1);
70
+ function resolveParametersBeforeFlag(argv) {
71
+ const parameters = [];
72
+ for (const arg of argv) {
73
+ if (arg.startsWith("-")) {
74
+ break;
75
+ }
76
+ parameters.push(arg);
77
+ }
78
+ return parameters;
79
+ }
80
+ const resolveArgv = () => isNode() ? process.argv.slice(2) : isDeno() ? Deno.args : [];
81
+ function compose(inspectors) {
82
+ return (getCtx) => {
83
+ return dispatch(0);
84
+ function dispatch(i) {
85
+ const inspector = inspectors[i];
86
+ return inspector(getCtx(), dispatch.bind(null, i + 1));
87
+ }
88
+ };
89
+ }
90
+
91
+ var __accessCheck = (obj, member, msg) => {
92
+ if (!member.has(obj))
93
+ throw TypeError("Cannot " + msg);
94
+ };
95
+ var __privateGet = (obj, member, getter) => {
96
+ __accessCheck(obj, member, "read from private field");
97
+ return getter ? getter.call(obj) : member.get(obj);
98
+ };
99
+ var __privateAdd = (obj, member, value) => {
100
+ if (member.has(obj))
101
+ throw TypeError("Cannot add the same private member more than once");
102
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
103
+ };
104
+ var __privateSet = (obj, member, value, setter) => {
105
+ __accessCheck(obj, member, "write to private field");
106
+ setter ? setter.call(obj, value) : member.set(obj, value);
107
+ return value;
108
+ };
109
+ var _name, _description, _version, _inspectors, _commands, _commandEmitter, _isSingleCommand, isSingleCommand_get, _hasCommands, hasCommands_get;
110
+ const SingleCommand = Symbol("SingleCommand");
111
+ const _Clerc = class {
112
+ constructor() {
113
+ __privateAdd(this, _isSingleCommand);
114
+ __privateAdd(this, _hasCommands);
115
+ __privateAdd(this, _name, "");
116
+ __privateAdd(this, _description, "");
117
+ __privateAdd(this, _version, "");
118
+ __privateAdd(this, _inspectors, []);
119
+ __privateAdd(this, _commands, {});
120
+ __privateAdd(this, _commandEmitter, new LiteEmit());
121
+ }
122
+ get _name() {
123
+ return __privateGet(this, _name);
124
+ }
125
+ get _description() {
126
+ return __privateGet(this, _description);
127
+ }
128
+ get _version() {
129
+ return __privateGet(this, _version);
130
+ }
131
+ get _inspectors() {
132
+ return __privateGet(this, _inspectors);
133
+ }
134
+ get _commands() {
135
+ return __privateGet(this, _commands);
136
+ }
137
+ static create() {
138
+ return new _Clerc();
139
+ }
140
+ name(name) {
141
+ __privateSet(this, _name, name);
142
+ return this;
143
+ }
144
+ description(description) {
145
+ __privateSet(this, _description, description);
146
+ return this;
147
+ }
148
+ version(version) {
149
+ __privateSet(this, _version, version);
150
+ return this;
151
+ }
152
+ command(name, description, options = {}) {
153
+ if (__privateGet(this, _commands)[name]) {
154
+ if (name === SingleCommand) {
155
+ throw new CommandExistsError("Single command already exists");
156
+ }
157
+ throw new CommandExistsError(`Command "${name === SingleCommand ? "[SingleCommand]" : name}" already exists`);
158
+ }
159
+ if (__privateGet(this, _isSingleCommand, isSingleCommand_get)) {
160
+ throw new SingleCommandError();
161
+ }
162
+ if (name === SingleCommand && __privateGet(this, _hasCommands, hasCommands_get)) {
163
+ throw new CommonCommandExistsError();
164
+ }
165
+ if (name !== SingleCommand) {
166
+ const splitedName = name.split(" ");
167
+ const existedCommandNames = Object.keys(__privateGet(this, _commands)).filter((name2) => typeof name2 === "string").map((name2) => name2.split(" "));
168
+ if (existedCommandNames.some((name2) => arrayStartsWith(splitedName, name2))) {
169
+ throw new ParentCommandExistsError(splitedName.join(" "));
170
+ }
171
+ if (existedCommandNames.some((name2) => arrayStartsWith(name2, splitedName))) {
172
+ throw new SubcommandExistsError(splitedName.join(" "));
173
+ }
174
+ }
175
+ __privateGet(this, _commands)[name] = { name, description, ...options };
176
+ return this;
177
+ }
178
+ on(name, handler) {
179
+ __privateGet(this, _commandEmitter).on(name, handler);
180
+ return this;
181
+ }
182
+ use(plugin) {
183
+ return plugin.setup(this);
184
+ }
185
+ inspector(inspector) {
186
+ __privateGet(this, _inspectors).push(inspector);
187
+ return this;
188
+ }
189
+ parse(argv = resolveArgv()) {
190
+ const name = resolveParametersBeforeFlag(argv);
191
+ const stringName = name.join(" ");
192
+ const getCommand = () => __privateGet(this, _isSingleCommand, isSingleCommand_get) ? __privateGet(this, _commands)[SingleCommand] : resolveCommand(__privateGet(this, _commands), name);
193
+ const getContext = () => {
194
+ const command = getCommand();
195
+ const isCommandResolved = !!command;
196
+ const parsedWithType = typeFlag((command == null ? void 0 : command.flags) || {}, [...argv]);
197
+ const { _: args, flags } = parsedWithType;
198
+ const parameters = __privateGet(this, _isSingleCommand, isSingleCommand_get) || !isCommandResolved ? args : args.slice(command.name.split(" ").length);
199
+ const context = {
200
+ name: command == null ? void 0 : command.name,
201
+ resolved: isCommandResolved,
202
+ isSingleCommand: __privateGet(this, _isSingleCommand, isSingleCommand_get),
203
+ raw: parsedWithType,
204
+ parameters,
205
+ flags,
206
+ unknownFlags: parsedWithType.unknownFlags,
207
+ cli: this
208
+ };
209
+ return context;
210
+ };
211
+ const emitHandler = () => {
212
+ const command = getCommand();
213
+ const handlerContext = getContext();
214
+ if (!command) {
215
+ throw new NoSuchCommandError(stringName);
216
+ }
217
+ __privateGet(this, _commandEmitter).emit(command.name, handlerContext);
218
+ };
219
+ const inspectors = [...__privateGet(this, _inspectors), emitHandler];
220
+ const inspector = compose(inspectors);
221
+ inspector(getContext);
222
+ return this;
223
+ }
224
+ };
225
+ let Clerc = _Clerc;
226
+ _name = new WeakMap();
227
+ _description = new WeakMap();
228
+ _version = new WeakMap();
229
+ _inspectors = new WeakMap();
230
+ _commands = new WeakMap();
231
+ _commandEmitter = new WeakMap();
232
+ _isSingleCommand = new WeakSet();
233
+ isSingleCommand_get = function() {
234
+ return __privateGet(this, _commands)[SingleCommand] !== void 0;
235
+ };
236
+ _hasCommands = new WeakSet();
237
+ hasCommands_get = function() {
238
+ return Object.keys(__privateGet(this, _commands)).length > 0;
239
+ };
240
+
241
+ const definePlugin = (p) => p;
242
+ const defineHandler = (_cli, _key, handler) => handler;
243
+ const defineInspector = (_cli, inspector) => inspector;
244
+
245
+ export { Clerc, CommandExistsError, CommonCommandExistsError, NoSuchCommandError, ParentCommandExistsError, SingleCommand, SingleCommandError, SubcommandExistsError, compose, defineHandler, defineInspector, definePlugin, resolveArgv, resolveCommand, resolveFlagAlias, resolveFlagDefault, resolveParametersBeforeFlag, resolveRootCommands, resolveSubcommandsByParent };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clerc",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "author": "Ray <nn_201312@163.com> (https://github.com/so1ve)",
5
5
  "description": "Clerc is a simple and easy-to-use cli framework.",
6
6
  "keywords": [
@@ -39,10 +39,9 @@
39
39
  "access": "public"
40
40
  },
41
41
  "dependencies": {
42
- "@clerc/utils": "0.4.0",
42
+ "@clerc/utils": "0.6.0",
43
43
  "is-platform": "^0.2.0",
44
44
  "lite-emit": "^1.4.0",
45
- "mri": "^1.2.0",
46
45
  "type-flag": "^3.0.0"
47
46
  },
48
47
  "scripts": {