@clerc/core 0.44.0 → 1.0.0-beta.1

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +242 -488
  2. package/dist/index.js +308 -813
  3. package/package.json +12 -15
package/dist/index.js CHANGED
@@ -1,828 +1,323 @@
1
- import { format } from 'node:util';
2
- import { camelCase, arrayStartsWith, toArray } from '@clerc/utils';
3
- import { defu } from 'defu';
4
- import { LiteEmit } from 'lite-emit';
5
- import { typeFlag } from 'type-flag';
6
- import { IS_NODE, IS_ELECTRON, IS_DENO } from 'is-platform';
1
+ import { DOUBLE_DASH, PARAMETER, parse } from "@clerc/parser";
2
+ import { toArray } from "@clerc/utils";
3
+ import { LiteEmit } from "lite-emit";
7
4
 
8
- const s = JSON.stringify;
9
- class CommandExistsError extends Error {
10
- constructor(commandName, t) {
11
- super(t("core.commandExists", s(commandName)));
12
- this.commandName = commandName;
13
- }
14
- }
15
- class NoSuchCommandError extends Error {
16
- constructor(commandName, t) {
17
- super(t("core.noSuchCommand", s(commandName)));
18
- this.commandName = commandName;
19
- }
20
- }
21
- class NoCommandGivenError extends Error {
22
- constructor(t) {
23
- super(t("core.noCommandGiven"));
24
- }
25
- }
26
- class CommandNameConflictError extends Error {
27
- constructor(n1, n2, t) {
28
- super(t("core.commandNameConflict", s(n1), s(n2)));
29
- this.n1 = n1;
30
- this.n2 = n2;
31
- }
32
- }
33
- class ScriptNameNotSetError extends Error {
34
- constructor(t) {
35
- super(t("core.scriptNameNotSet"));
36
- }
37
- }
38
- class DescriptionNotSetError extends Error {
39
- constructor(t) {
40
- super(t("core.descriptionNotSet"));
41
- }
42
- }
43
- class VersionNotSetError extends Error {
44
- constructor(t) {
45
- super(t("core.versionNotSet"));
46
- }
47
- }
48
- class InvalidCommandNameError extends Error {
49
- constructor(commandName, t) {
50
- super(t("core.badNameFormat", s(commandName)));
51
- this.commandName = commandName;
52
- }
53
- }
54
- class LocaleNotCalledFirstError extends Error {
55
- constructor(t) {
56
- super(t("core.localeMustBeCalledFirst"));
57
- }
5
+ //#region src/commands.ts
6
+ function resolveCommand(commandsMap, parameters) {
7
+ for (let i = parameters.length; i >= 0; i--) {
8
+ const name = parameters.slice(0, i).join(" ");
9
+ if (commandsMap.has(name)) return [commandsMap.get(name), name];
10
+ }
11
+ return [void 0, void 0];
58
12
  }
59
13
 
60
- const locales = {
61
- "en": {
62
- "core.commandExists": 'Command "%s" exists.',
63
- "core.noSuchCommand": "No such command: %s.",
64
- "core.noCommandGiven": "No command given.",
65
- "core.commandNameConflict": "Command name %s conflicts with %s. Maybe caused by alias.",
66
- "core.scriptNameNotSet": "Name not set.",
67
- "core.descriptionNotSet": "Description not set.",
68
- "core.versionNotSet": "Version not set.",
69
- "core.badNameFormat": "Bad name format: %s.",
70
- "core.localeMustBeCalledFirst": "locale() or fallbackLocale() must be called at first.",
71
- "core.cliParseMustBeCalled": "cli.parse() must be called.",
72
- "core.spreadParameterMustBeLast": "Invalid Parameter: Spread parameter %s must be last.",
73
- "core.requiredParameterCannotComeAfterOptionalParameter": "Invalid Parameter: Required parameter %s cannot come after optional parameter %s.",
74
- "core.parameterMustBeWrappedInBrackets": "Invalid Parameter: Parameter %s must be wrapped in <> (required parameter) or [] (optional parameter).",
75
- "core.parameterIsUsedMoreThanOnce": "Invalid Parameter: Parameter %s is used more than once.",
76
- "core.missingRequiredParameter": "Missing required parameter %s."
77
- },
78
- "zh-CN": {
79
- "core.commandExists": '\u547D\u4EE4 "%s" \u5DF2\u5B58\u5728\u3002',
80
- "core.noSuchCommand": "\u627E\u4E0D\u5230\u547D\u4EE4: %s\u3002",
81
- "core.noCommandGiven": "\u6CA1\u6709\u8F93\u5165\u547D\u4EE4\u3002",
82
- "core.commandNameConflict": "\u547D\u4EE4\u540D\u79F0 %s \u548C %s \u51B2\u7A81\u3002 \u53EF\u80FD\u662F\u7531\u4E8E\u522B\u540D\u5BFC\u81F4\u7684\u3002",
83
- "core.scriptNameNotSet": "\u672A\u8BBE\u7F6E CLI Script \u540D\u79F0\u3002",
84
- "core.descriptionNotSet": "\u672A\u8BBE\u7F6E CLI \u63CF\u8FF0\u3002",
85
- "core.versionNotSet": "\u672A\u8BBE\u7F6E CLI \u7248\u672C\u3002",
86
- "core.badNameFormat": "\u9519\u8BEF\u7684\u547D\u4EE4\u540D\u5B57\u683C\u5F0F: %s\u3002",
87
- "core.localeMustBeCalledFirst": "locale() \u6216 fallbackLocale() \u5FC5\u987B\u5728\u6700\u5F00\u59CB\u8C03\u7528\u3002",
88
- "core.cliParseMustBeCalled": "cli.parse() \u5FC5\u987B\u88AB\u8C03\u7528\u3002",
89
- "core.spreadParameterMustBeLast": "\u4E0D\u5408\u6CD5\u7684\u53C2\u6570: \u5C55\u5F00\u53C2\u6570 %s \u5FC5\u987B\u5728\u6700\u540E\u3002",
90
- "core.requiredParameterCannotComeAfterOptionalParameter": "\u4E0D\u5408\u6CD5\u7684\u53C2\u6570: \u5FC5\u586B\u53C2\u6570 %s \u4E0D\u80FD\u5728\u53EF\u9009\u53C2\u6570 %s \u4E4B\u540E\u3002",
91
- "core.parameterMustBeWrappedInBrackets": "\u4E0D\u5408\u6CD5\u7684\u53C2\u6570: \u53C2\u6570 %s \u5FC5\u987B\u88AB <> (\u5FC5\u586B\u53C2\u6570) \u6216 [] (\u53EF\u9009\u53C2\u6570) \u5305\u88F9\u3002",
92
- "core.parameterIsUsedMoreThanOnce": "\u4E0D\u5408\u6CD5\u7684\u53C2\u6570: \u53C2\u6570 %s \u88AB\u4F7F\u7528\u4E86\u591A\u6B21\u3002",
93
- "core.missingRequiredParameter": "\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570 %s\u3002"
94
- }
14
+ //#endregion
15
+ //#region src/errors.ts
16
+ var NoSuchCommandError = class extends Error {
17
+ constructor(commandName) {
18
+ super(`No such command: "${commandName}".`);
19
+ this.commandName = commandName;
20
+ }
21
+ };
22
+ var NoCommandGivenError = class extends Error {
23
+ constructor() {
24
+ super("No command specified.");
25
+ }
26
+ };
27
+ var InvalidCommandError = class extends Error {
28
+ constructor(message) {
29
+ super(message);
30
+ }
31
+ };
32
+ var MissingRequiredMetadataError = class extends Error {
33
+ constructor(metadataName) {
34
+ super(`CLI ${metadataName} is required.`);
35
+ }
36
+ };
37
+ var InvalidParametersError = class extends Error {
38
+ constructor(message) {
39
+ super(message);
40
+ }
95
41
  };
96
42
 
97
- const { stringify } = JSON;
98
- function parseParameters(parameters, t) {
99
- const parsedParameters = [];
100
- let hasOptional;
101
- let hasSpread;
102
- for (const parameter of parameters) {
103
- if (hasSpread) {
104
- throw new Error(
105
- t("core.spreadParameterMustBeLast", stringify(hasSpread))
106
- );
107
- }
108
- const firstCharacter = parameter[0];
109
- const lastCharacter = parameter[parameter.length - 1];
110
- let required;
111
- if (firstCharacter === "<" && lastCharacter === ">") {
112
- required = true;
113
- if (hasOptional) {
114
- throw new Error(
115
- t(
116
- "core.requiredParameterMustBeBeforeOptional",
117
- stringify(parameter),
118
- stringify(hasOptional)
119
- )
120
- );
121
- }
122
- }
123
- if (firstCharacter === "[" && lastCharacter === "]") {
124
- required = false;
125
- hasOptional = parameter;
126
- }
127
- if (required === void 0) {
128
- throw new Error(
129
- t("core.parameterMustBeWrappedInBrackets", stringify(parameter))
130
- );
131
- }
132
- let name = parameter.slice(1, -1);
133
- const spread = name.slice(-3) === "...";
134
- if (spread) {
135
- hasSpread = parameter;
136
- name = name.slice(0, -3);
137
- }
138
- parsedParameters.push({
139
- name,
140
- required,
141
- spread
142
- });
143
- }
144
- return parsedParameters;
43
+ //#endregion
44
+ //#region src/interceptor.ts
45
+ function normalizeInspector(inspector) {
46
+ if (typeof inspector === "function") return {
47
+ enforce: "normal",
48
+ handler: inspector
49
+ };
50
+ return {
51
+ enforce: inspector.enforce ?? "normal",
52
+ handler: inspector.handler
53
+ };
145
54
  }
146
- function mapParametersToArguments(mapping, parameters, cliArguments, t) {
147
- for (let i = 0; i < parameters.length; i += 1) {
148
- const { name, required, spread } = parameters[i];
149
- const camelCaseName = camelCase(name);
150
- if (camelCaseName in mapping) {
151
- throw new Error(t("core.parameterIsUsedMoreThanOnce", stringify(name)));
152
- }
153
- const value = spread ? cliArguments.slice(i) : cliArguments[i];
154
- if (spread) {
155
- i = parameters.length;
156
- }
157
- if (required && (!value || spread && value.length === 0)) {
158
- throw new Error(t("core.missingRequiredParameter", stringify(name)));
159
- }
160
- mapping[camelCaseName] = value;
161
- }
55
+ function compose(inspectors) {
56
+ const normalized = inspectors.map(normalizeInspector);
57
+ const pre = normalized.filter((i) => i.enforce === "pre");
58
+ const normal = normalized.filter((i) => i.enforce === "normal");
59
+ const post = normalized.filter((i) => i.enforce === "post");
60
+ const orderedInspectors = [
61
+ ...pre,
62
+ ...normal,
63
+ ...post
64
+ ];
65
+ return async (context) => {
66
+ let index = 0;
67
+ async function dispatch() {
68
+ if (index >= orderedInspectors.length) return;
69
+ await orderedInspectors[index++].handler(context, dispatch);
70
+ }
71
+ await dispatch();
72
+ };
162
73
  }
163
74
 
164
- function setCommand(commandsMap, commands, command, t) {
165
- if (command.alias) {
166
- const aliases = toArray(command.alias);
167
- for (const alias of aliases) {
168
- if (alias in commands) {
169
- throw new CommandNameConflictError(
170
- commands[alias].name,
171
- command.name,
172
- t
173
- );
174
- }
175
- commandsMap.set(typeof alias === "symbol" ? alias : alias.split(" "), {
176
- ...command,
177
- __isAlias: true
178
- });
179
- }
180
- }
181
- }
182
- function resolveFlattenCommands(commands, t) {
183
- const commandsMap = /* @__PURE__ */ new Map();
184
- if (commands[Root]) {
185
- commandsMap.set(Root, commands[Root]);
186
- setCommand(commandsMap, commands, commands[Root], t);
187
- }
188
- for (const command of Object.values(commands)) {
189
- setCommand(commandsMap, commands, command, t);
190
- commandsMap.set(command.name.split(" "), command);
191
- }
192
- return commandsMap;
75
+ //#endregion
76
+ //#region src/parameters.ts
77
+ function getParametersToResolve(argv) {
78
+ const parameters = [];
79
+ for (const arg of argv) {
80
+ if (arg.startsWith("-")) break;
81
+ parameters.push(arg);
82
+ }
83
+ return parameters;
193
84
  }
194
- function resolveCommand(commands, argv, t) {
195
- var _a;
196
- const commandsMap = resolveFlattenCommands(commands, t);
197
- for (const [name, command] of commandsMap.entries()) {
198
- const parsed = typeFlag((_a = command == null ? void 0 : command.flags) != null ? _a : /* @__PURE__ */ Object.create(null), [...argv]);
199
- const { _: args } = parsed;
200
- if (name === Root) {
201
- continue;
202
- }
203
- if (arrayStartsWith(args, name)) {
204
- return [command, name];
205
- }
206
- }
207
- if (commandsMap.has(Root)) {
208
- return [commandsMap.get(Root), Root];
209
- }
210
- return [void 0, void 0];
85
+ const PARAMETER_REGEX = /^(<|\[)(\w+)(\.\.\.)?(\]|>)$/;
86
+ const isParameterDefinitionBracketsValid = (definition) => definition.startsWith("<") && definition.endsWith(">") || definition.startsWith("[") && definition.endsWith("]");
87
+ function _parseParameters(definitions, parameters) {
88
+ const result = {};
89
+ let hasOptional = false;
90
+ for (const [i, definition] of definitions.entries()) {
91
+ const match = definition.match(PARAMETER_REGEX);
92
+ if (!match || !isParameterDefinitionBracketsValid(definition)) throw new InvalidParametersError(`Invalid parameter definition: ${definition}`);
93
+ const name = match[2];
94
+ const isVariadic = !!match[3];
95
+ const isRequired = definition.startsWith("<");
96
+ if (name in result) throw new InvalidParametersError(`Duplicate parameter name: ${name}`);
97
+ if (isVariadic && i !== definitions.length - 1) throw new InvalidParametersError("Variadic parameter must be the last parameter in the definition.");
98
+ if (isRequired) {
99
+ if (hasOptional) throw new InvalidParametersError(`Required parameter "${name}" cannot appear after an optional parameter.`);
100
+ } else hasOptional = true;
101
+ const value = isVariadic ? parameters.slice(i) : parameters[i];
102
+ if (isRequired && (isVariadic ? value.length === 0 : value === void 0)) throw new InvalidParametersError(`Missing required ${isVariadic ? "variadic " : ""}parameter: ${name}`);
103
+ result[name] = value;
104
+ }
105
+ return result;
211
106
  }
212
- const resolveArgv = () => IS_NODE ? process.argv.slice(IS_ELECTRON ? 1 : 2) : IS_DENO ? (
213
- // @ts-expect-error Ignore
214
- Deno.args
215
- ) : [];
216
- function compose(interceptors) {
217
- const interceptorMap = {
218
- pre: [],
219
- normal: [],
220
- post: []
221
- };
222
- for (const interceptor of interceptors) {
223
- const objectInterceptor = typeof interceptor === "object" ? interceptor : { fn: interceptor };
224
- const { enforce, fn } = objectInterceptor;
225
- if (enforce === "post" || enforce === "pre") {
226
- interceptorMap[enforce].push(fn);
227
- } else {
228
- interceptorMap.normal.push(fn);
229
- }
230
- }
231
- const mergedInterceptorFns = [
232
- ...interceptorMap.pre,
233
- ...interceptorMap.normal,
234
- ...interceptorMap.post
235
- ];
236
- return (ctx) => {
237
- return dispatch(0);
238
- function dispatch(i) {
239
- const interceptor = mergedInterceptorFns[i];
240
- return interceptor(ctx, dispatch.bind(null, i + 1));
241
- }
242
- };
107
+ function parseParameters(definitions, parameters, doubleDashParameters) {
108
+ const doubleDashIndex = definitions.indexOf(DOUBLE_DASH);
109
+ if (doubleDashIndex === -1) return _parseParameters(definitions, parameters);
110
+ else {
111
+ const definitionBeforeDoubleDash = definitions.slice(0, doubleDashIndex);
112
+ const definitionAfterDoubleDash = definitions.slice(doubleDashIndex + 1);
113
+ return {
114
+ ..._parseParameters(definitionBeforeDoubleDash, parameters),
115
+ ..._parseParameters(definitionAfterDoubleDash, doubleDashParameters)
116
+ };
117
+ }
243
118
  }
244
- const INVALID_RE = /\s{2,}/;
245
- const isValidName = (name) => name === Root ? true : !(name.startsWith(" ") || name.endsWith(" ")) && !INVALID_RE.test(name);
246
- const withBrackets = (s, isOptional) => isOptional ? `[${s}]` : `<${s}>`;
247
- const ROOT = "<Root>";
248
- const formatCommandName = (name) => Array.isArray(name) ? name.join(" ") : typeof name === "string" ? name : ROOT;
249
- const detectLocale = () => process.env.CLERC_LOCALE ? process.env.CLERC_LOCALE : Intl.DateTimeFormat().resolvedOptions().locale;
250
- const stripFlags = (argv) => argv.filter((arg) => !arg.startsWith("-"));
251
119
 
252
- var __accessCheck = (obj, member, msg) => {
253
- if (!member.has(obj))
254
- throw TypeError("Cannot " + msg);
255
- };
256
- var __privateGet = (obj, member, getter) => {
257
- __accessCheck(obj, member, "read from private field");
258
- return getter ? getter.call(obj) : member.get(obj);
259
- };
260
- var __privateAdd = (obj, member, value) => {
261
- if (member.has(obj))
262
- throw TypeError("Cannot add the same private member more than once");
263
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
264
- };
265
- var __privateSet = (obj, member, value, setter) => {
266
- __accessCheck(obj, member, "write to private field");
267
- setter ? setter.call(obj, value) : member.set(obj, value);
268
- return value;
269
- };
270
- var __privateMethod = (obj, member, method) => {
271
- __accessCheck(obj, member, "access private method");
272
- return method;
273
- };
274
- var _name, _scriptName, _description, _version, _interceptors, _commands, _commandEmitter, _flags, _usedNames, _argv, _errorHandlers, _isOtherMethodCalled, _defaultLocale, _locale, _locales, _hasRootOrAlias, hasRootOrAlias_get, _hasRoot, hasRoot_get, _addCoreLocales, addCoreLocales_fn, _otherMethodCalled, otherMethodCalled_fn, _command, command_fn, _validateMeta, validateMeta_fn, _getContext, getContext_fn, _handleError, handleError_fn, _callWithErrorHandling, callWithErrorHandling_fn, _runMatchedCommand, runMatchedCommand_fn;
275
- const Root = Symbol.for("Clerc.Root");
276
- const _Clerc = class _Clerc {
277
- constructor(scriptName, description, version) {
278
- __privateAdd(this, _hasRootOrAlias);
279
- __privateAdd(this, _hasRoot);
280
- __privateAdd(this, _addCoreLocales);
281
- __privateAdd(this, _otherMethodCalled);
282
- __privateAdd(this, _command);
283
- __privateAdd(this, _validateMeta);
284
- __privateAdd(this, _getContext);
285
- __privateAdd(this, _handleError);
286
- __privateAdd(this, _callWithErrorHandling);
287
- __privateAdd(this, _runMatchedCommand);
288
- __privateAdd(this, _name, "");
289
- __privateAdd(this, _scriptName, "");
290
- __privateAdd(this, _description, "");
291
- __privateAdd(this, _version, "");
292
- __privateAdd(this, _interceptors, []);
293
- __privateAdd(this, _commands, /* @__PURE__ */ Object.create(null));
294
- __privateAdd(this, _commandEmitter, new LiteEmit({
295
- errorHandler: (msg) => {
296
- __privateMethod(this, _handleError, handleError_fn).call(this, new Error(msg));
297
- }
298
- }));
299
- __privateAdd(this, _flags, /* @__PURE__ */ Object.create(null));
300
- __privateAdd(this, _usedNames, /* @__PURE__ */ new Set());
301
- __privateAdd(this, _argv, void 0);
302
- __privateAdd(this, _errorHandlers, []);
303
- __privateAdd(this, _isOtherMethodCalled, false);
304
- __privateAdd(this, _defaultLocale, "en");
305
- __privateAdd(this, _locale, "en");
306
- __privateAdd(this, _locales, /* @__PURE__ */ Object.create(null));
307
- __privateSet(this, _scriptName, scriptName != null ? scriptName : __privateGet(this, _scriptName));
308
- __privateSet(this, _description, description != null ? description : __privateGet(this, _description));
309
- __privateSet(this, _version, version != null ? version : __privateGet(this, _version));
310
- __privateSet(this, _locale, detectLocale());
311
- __privateMethod(this, _addCoreLocales, addCoreLocales_fn).call(this);
312
- }
313
- get i18n() {
314
- return {
315
- add: (locales2) => {
316
- __privateSet(this, _locales, defu(__privateGet(this, _locales), locales2));
317
- },
318
- t: (name, ...args) => {
319
- const localeObject = __privateGet(this, _locales)[__privateGet(this, _locale)] || __privateGet(this, _locales)[__privateGet(this, _defaultLocale)];
320
- const defaultLocaleObject = __privateGet(this, _locales)[__privateGet(this, _defaultLocale)];
321
- return localeObject[name] ? format(localeObject[name], ...args) : defaultLocaleObject[name] ? format(defaultLocaleObject[name], ...args) : void 0;
322
- }
323
- };
324
- }
325
- get _name() {
326
- return __privateGet(this, _name) || __privateGet(this, _scriptName);
327
- }
328
- get _scriptName() {
329
- return __privateGet(this, _scriptName);
330
- }
331
- get _description() {
332
- return __privateGet(this, _description);
333
- }
334
- get _version() {
335
- return __privateGet(this, _version);
336
- }
337
- /**
338
- * @deprecated This is a typo. Use `_interceptor` instead.
339
- */
340
- get _inspectors() {
341
- return __privateGet(this, _interceptors);
342
- }
343
- get _interceptors() {
344
- return __privateGet(this, _interceptors);
345
- }
346
- get _commands() {
347
- return __privateGet(this, _commands);
348
- }
349
- get _flags() {
350
- return __privateGet(this, _flags);
351
- }
352
- /**
353
- * Create a new cli
354
- *
355
- * @example
356
- *
357
- * ```ts
358
- * const cli = Clerc.create();
359
- * ```
360
- *
361
- * @param name
362
- * @param description
363
- * @param version
364
- * @returns
365
- */
366
- static create(name, description, version) {
367
- return new _Clerc(name, description, version);
368
- }
369
- /**
370
- * Set the name of the cli
371
- *
372
- * @example
373
- *
374
- * ```ts
375
- * Clerc.create().name("test");
376
- * ```
377
- *
378
- * @param name
379
- * @returns
380
- */
381
- name(name) {
382
- __privateMethod(this, _otherMethodCalled, otherMethodCalled_fn).call(this);
383
- __privateSet(this, _name, name);
384
- return this;
385
- }
386
- /**
387
- * Set the script name of the cli
388
- *
389
- * @example
390
- *
391
- * ```ts
392
- * Clerc.create().scriptName("test");
393
- * ```
394
- *
395
- * @param scriptName
396
- * @returns
397
- */
398
- scriptName(scriptName) {
399
- __privateMethod(this, _otherMethodCalled, otherMethodCalled_fn).call(this);
400
- __privateSet(this, _scriptName, scriptName);
401
- return this;
402
- }
403
- /**
404
- * Set the description of the cli
405
- *
406
- * @example
407
- *
408
- * ```ts
409
- * Clerc.create().description("test cli");
410
- * ```
411
- *
412
- * @param description
413
- * @returns
414
- */
415
- description(description) {
416
- __privateMethod(this, _otherMethodCalled, otherMethodCalled_fn).call(this);
417
- __privateSet(this, _description, description);
418
- return this;
419
- }
420
- /**
421
- * Set the version of the cli
422
- *
423
- * @example
424
- *
425
- * ```ts
426
- * Clerc.create().version("1.0.0");
427
- * ```
428
- *
429
- * @param version
430
- * @returns
431
- */
432
- version(version) {
433
- __privateMethod(this, _otherMethodCalled, otherMethodCalled_fn).call(this);
434
- __privateSet(this, _version, version);
435
- return this;
436
- }
437
- /**
438
- * Set the Locale You must call this method once after you created the Clerc
439
- * instance.
440
- *
441
- * @example
442
- *
443
- * ```ts
444
- * Clerc.create()
445
- * .locale("en")
446
- * .command(...)
447
- * ```
448
- *
449
- * @param locale
450
- * @returns
451
- */
452
- locale(locale) {
453
- if (__privateGet(this, _isOtherMethodCalled)) {
454
- throw new LocaleNotCalledFirstError(this.i18n.t);
455
- }
456
- __privateSet(this, _locale, locale);
457
- return this;
458
- }
459
- /**
460
- * Set the fallback Locale You must call this method once after you created
461
- * the Clerc instance.
462
- *
463
- * @example
464
- *
465
- * ```ts
466
- * Clerc.create()
467
- * .fallbackLocale("en")
468
- * .command(...)
469
- * ```
470
- *
471
- * @param fallbackLocale
472
- * @returns
473
- */
474
- fallbackLocale(fallbackLocale) {
475
- if (__privateGet(this, _isOtherMethodCalled)) {
476
- throw new LocaleNotCalledFirstError(this.i18n.t);
477
- }
478
- __privateSet(this, _defaultLocale, fallbackLocale);
479
- return this;
480
- }
481
- /**
482
- * Register a error handler
483
- *
484
- * @example
485
- *
486
- * ```ts
487
- * Clerc.create().errorHandler((err) => {
488
- * console.log(err);
489
- * });
490
- * ```
491
- *
492
- * @param handler
493
- * @returns
494
- */
495
- errorHandler(handler) {
496
- __privateGet(this, _errorHandlers).push(handler);
497
- return this;
498
- }
499
- command(nameOrCommand, description, options = {}) {
500
- __privateMethod(this, _callWithErrorHandling, callWithErrorHandling_fn).call(this, () => {
501
- if (Array.isArray(nameOrCommand)) {
502
- for (const command of nameOrCommand) {
503
- __privateMethod(this, _command, command_fn).call(this, command);
504
- }
505
- } else {
506
- __privateMethod(this, _command, command_fn).call(this, nameOrCommand, description, options);
507
- }
508
- });
509
- return this;
510
- }
511
- /**
512
- * Register a global flag
513
- *
514
- * @example
515
- *
516
- * ```ts
517
- * Clerc.create().flag("help", "help", {
518
- * alias: "h",
519
- * type: Boolean,
520
- * });
521
- * ```
522
- *
523
- * @param name
524
- * @param description
525
- * @param options
526
- * @returns
527
- */
528
- flag(name, description, options) {
529
- __privateGet(this, _flags)[name] = {
530
- description,
531
- ...options
532
- };
533
- return this;
534
- }
535
- /**
536
- * Register a handler
537
- *
538
- * @example
539
- *
540
- * ```ts
541
- * Clerc.create()
542
- * .command("test", "test command")
543
- * .on("test", (ctx) => {
544
- * console.log(ctx);
545
- * });
546
- * ```
547
- *
548
- * @param name
549
- * @param handler
550
- * @returns
551
- */
552
- on(name, handler) {
553
- __privateGet(this, _commandEmitter).on(name, handler);
554
- return this;
555
- }
556
- /**
557
- * Use a plugin
558
- *
559
- * @example
560
- *
561
- * ```ts
562
- * Clerc.create().use(plugin);
563
- * ```
564
- *
565
- * @param plugin
566
- * @returns
567
- */
568
- use(plugin) {
569
- __privateMethod(this, _otherMethodCalled, otherMethodCalled_fn).call(this);
570
- return plugin.setup(this);
571
- }
572
- /**
573
- * @deprecated This is a typo. Use `intercetor()` instead.
574
- */
575
- inspector(interceptor) {
576
- return this.interceptor(interceptor);
577
- }
578
- /**
579
- * Register a interceptor
580
- *
581
- * @example
582
- *
583
- * ```ts
584
- * Clerc.create().interceptor((ctx, next) => {
585
- * console.log(ctx);
586
- * next();
587
- * });
588
- * ```
589
- *
590
- * @param interceptor
591
- * @returns
592
- */
593
- interceptor(interceptor) {
594
- __privateMethod(this, _otherMethodCalled, otherMethodCalled_fn).call(this);
595
- __privateGet(this, _interceptors).push(interceptor);
596
- return this;
597
- }
598
- /**
599
- * Parse the command line arguments
600
- *
601
- * @example
602
- *
603
- * ```ts
604
- * Clerc.create().parse(process.argv.slice(2)); // Optional
605
- * ```
606
- *
607
- * @param args
608
- * @param optionsOrArgv
609
- * @returns
610
- */
611
- parse(optionsOrArgv = resolveArgv()) {
612
- __privateMethod(this, _otherMethodCalled, otherMethodCalled_fn).call(this);
613
- const { argv, run } = Array.isArray(optionsOrArgv) ? {
614
- argv: optionsOrArgv,
615
- run: true
616
- } : {
617
- argv: resolveArgv(),
618
- ...optionsOrArgv
619
- };
620
- __privateSet(this, _argv, [...argv]);
621
- __privateMethod(this, _validateMeta, validateMeta_fn).call(this);
622
- if (run) {
623
- this.runMatchedCommand();
624
- }
625
- return this;
626
- }
627
- /**
628
- * Run matched command
629
- *
630
- * @example
631
- *
632
- * ```ts
633
- * Clerc.create().parse({ run: false }).runMatchedCommand();
634
- * ```
635
- *
636
- * @returns
637
- */
638
- runMatchedCommand() {
639
- __privateMethod(this, _callWithErrorHandling, callWithErrorHandling_fn).call(this, () => __privateMethod(this, _runMatchedCommand, runMatchedCommand_fn).call(this));
640
- process.title = __privateGet(this, _name);
641
- return this;
642
- }
643
- };
644
- _name = new WeakMap();
645
- _scriptName = new WeakMap();
646
- _description = new WeakMap();
647
- _version = new WeakMap();
648
- _interceptors = new WeakMap();
649
- _commands = new WeakMap();
650
- _commandEmitter = new WeakMap();
651
- _flags = new WeakMap();
652
- _usedNames = new WeakMap();
653
- _argv = new WeakMap();
654
- _errorHandlers = new WeakMap();
655
- _isOtherMethodCalled = new WeakMap();
656
- _defaultLocale = new WeakMap();
657
- _locale = new WeakMap();
658
- _locales = new WeakMap();
659
- _hasRootOrAlias = new WeakSet();
660
- hasRootOrAlias_get = function() {
661
- return __privateGet(this, _usedNames).has(Root);
662
- };
663
- _hasRoot = new WeakSet();
664
- hasRoot_get = function() {
665
- return Object.prototype.hasOwnProperty.call(this._commands, Root);
666
- };
667
- _addCoreLocales = new WeakSet();
668
- addCoreLocales_fn = function() {
669
- this.i18n.add(locales);
670
- };
671
- _otherMethodCalled = new WeakSet();
672
- otherMethodCalled_fn = function() {
673
- __privateSet(this, _isOtherMethodCalled, true);
674
- };
675
- _command = new WeakSet();
676
- command_fn = function(nameOrCommand, description, options = {}) {
677
- __privateMethod(this, _otherMethodCalled, otherMethodCalled_fn).call(this);
678
- const { t } = this.i18n;
679
- const checkIsCommandObject = (nameOrCommand2) => !(typeof nameOrCommand2 === "string" || nameOrCommand2 === Root);
680
- const isCommandObject = checkIsCommandObject(nameOrCommand);
681
- const name = isCommandObject ? nameOrCommand.name : nameOrCommand;
682
- if (!isValidName(name)) {
683
- throw new InvalidCommandNameError(name, t);
684
- }
685
- const { handler = void 0, ...commandToSave } = isCommandObject ? nameOrCommand : { name, description, ...options };
686
- const nameList = [commandToSave.name];
687
- const aliasList = commandToSave.alias ? toArray(commandToSave.alias) : [];
688
- commandToSave.alias && nameList.push(...aliasList);
689
- for (const name2 of nameList) {
690
- if (__privateGet(this, _usedNames).has(name2)) {
691
- throw new CommandExistsError(formatCommandName(name2), t);
692
- }
693
- }
694
- __privateGet(this, _commands)[name] = commandToSave;
695
- __privateGet(this, _usedNames).add(commandToSave.name);
696
- for (const a of aliasList) {
697
- __privateGet(this, _usedNames).add(a);
698
- }
699
- isCommandObject && handler && this.on(nameOrCommand.name, handler);
700
- return this;
701
- };
702
- _validateMeta = new WeakSet();
703
- validateMeta_fn = function() {
704
- const { t } = this.i18n;
705
- if (!__privateGet(this, _scriptName)) {
706
- throw new ScriptNameNotSetError(t);
707
- }
708
- if (!__privateGet(this, _description)) {
709
- throw new DescriptionNotSetError(t);
710
- }
711
- if (!__privateGet(this, _version)) {
712
- throw new VersionNotSetError(t);
713
- }
714
- };
715
- _getContext = new WeakSet();
716
- getContext_fn = function(getCommand) {
717
- var _a;
718
- const argv = __privateGet(this, _argv);
719
- const { t } = this.i18n;
720
- const [command, called] = getCommand();
721
- const isCommandResolved = !!command;
722
- const flagsMerged = {
723
- ...__privateGet(this, _flags),
724
- ...command == null ? void 0 : command.flags
725
- };
726
- const parsed = typeFlag(flagsMerged, [...argv]);
727
- const parametersOffset = (command == null ? void 0 : command.name) === Root || called === Root ? 0 : (called == null ? void 0 : called.length) ? called.length : command == null ? void 0 : command.name.split(" ").length;
728
- const { _: args, flags, unknownFlags } = parsed;
729
- let parameters = !isCommandResolved || command.name === Root ? args : args.slice(parametersOffset);
730
- let commandParameters = (_a = command == null ? void 0 : command.parameters) != null ? _a : [];
731
- const hasEof = commandParameters.indexOf("--");
732
- const eofParameters = commandParameters.slice(hasEof + 1) || [];
733
- const mapping = /* @__PURE__ */ Object.create(null);
734
- if (hasEof > -1 && eofParameters.length > 0) {
735
- commandParameters = commandParameters.slice(0, hasEof);
736
- const eofArguments = args["--"];
737
- parameters = parameters.slice(0, -eofArguments.length || void 0);
738
- mapParametersToArguments(
739
- mapping,
740
- parseParameters(commandParameters, t),
741
- parameters,
742
- t
743
- );
744
- mapParametersToArguments(
745
- mapping,
746
- parseParameters(eofParameters, t),
747
- eofArguments,
748
- t
749
- );
750
- } else {
751
- mapParametersToArguments(
752
- mapping,
753
- parseParameters(commandParameters, t),
754
- parameters,
755
- t
756
- );
757
- }
758
- const mergedFlags = { ...flags, ...unknownFlags };
759
- const context = {
760
- name: command == null ? void 0 : command.name,
761
- called: Array.isArray(called) ? called.join(" ") : called,
762
- resolved: isCommandResolved,
763
- hasRootOrAlias: __privateGet(this, _hasRootOrAlias, hasRootOrAlias_get),
764
- hasRoot: __privateGet(this, _hasRoot, hasRoot_get),
765
- raw: { ...parsed, parameters, mergedFlags },
766
- parameters: mapping,
767
- flags,
768
- unknownFlags,
769
- cli: this
770
- };
771
- return context;
772
- };
773
- _handleError = new WeakSet();
774
- handleError_fn = function(e) {
775
- if (__privateGet(this, _errorHandlers).length > 0) {
776
- for (const cb of __privateGet(this, _errorHandlers)) {
777
- cb(e);
778
- }
779
- } else {
780
- throw e;
781
- }
782
- };
783
- _callWithErrorHandling = new WeakSet();
784
- callWithErrorHandling_fn = function(fn) {
785
- try {
786
- fn();
787
- } catch (e) {
788
- __privateMethod(this, _handleError, handleError_fn).call(this, e);
789
- }
790
- };
791
- _runMatchedCommand = new WeakSet();
792
- runMatchedCommand_fn = function() {
793
- __privateMethod(this, _otherMethodCalled, otherMethodCalled_fn).call(this);
794
- const { t } = this.i18n;
795
- const argv = __privateGet(this, _argv);
796
- if (!argv) {
797
- throw new Error(t("core.cliParseMustBeCalled"));
798
- }
799
- const getCommand = () => resolveCommand(__privateGet(this, _commands), argv, t);
800
- const getContext = () => __privateMethod(this, _getContext, getContext_fn).call(this, getCommand);
801
- const emitHandler = {
802
- enforce: "post",
803
- fn: (ctx) => {
804
- const [command] = getCommand();
805
- const stringName = stripFlags(argv).join(" ");
806
- if (!command) {
807
- const error = stringName ? new NoSuchCommandError(stringName, t) : new NoCommandGivenError(t);
808
- throw error;
809
- }
810
- __privateGet(this, _commandEmitter).emit(command.name, ctx);
811
- }
812
- };
813
- const interceptor = [...__privateGet(this, _interceptors), emitHandler];
814
- const callInterceptor = compose(interceptor);
815
- callInterceptor(getContext());
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
+ //#endregion
127
+ //#region src/platform.ts
128
+ const platformArgv = IS_NODE ? process.argv.slice(IS_ELECTRON ? 1 : 2) : IS_DENO ? Deno.args : [];
129
+
130
+ //#endregion
131
+ //#region src/cli.ts
132
+ var Clerc = class Clerc {
133
+ #argv = [];
134
+ #commands = /* @__PURE__ */ new Map();
135
+ #emitter = new LiteEmit({ errorHandler: (error) => this.#handleError(error) });
136
+ #globalFlags = {};
137
+ #interceptors = [];
138
+ #errorHandlers = [];
139
+ #name = "";
140
+ #scriptName = "";
141
+ #description = "";
142
+ #version = "";
143
+ constructor({ name, scriptName, description, version } = {}) {
144
+ if (name) this.#name = name;
145
+ if (scriptName) this.#scriptName = scriptName;
146
+ if (description) this.#description = description;
147
+ if (version) this.#version = version;
148
+ }
149
+ get _name() {
150
+ return this.#name || this.#scriptName;
151
+ }
152
+ get _scriptName() {
153
+ return this.#scriptName;
154
+ }
155
+ get _description() {
156
+ return this.#description;
157
+ }
158
+ get _version() {
159
+ return this.#version;
160
+ }
161
+ get _commands() {
162
+ return this.#commands;
163
+ }
164
+ get _globalFlags() {
165
+ return this.#globalFlags;
166
+ }
167
+ static create(options) {
168
+ return new Clerc(options);
169
+ }
170
+ name(name) {
171
+ this.#name = name;
172
+ return this;
173
+ }
174
+ scriptName(scriptName) {
175
+ this.#scriptName = scriptName;
176
+ return this;
177
+ }
178
+ description(description) {
179
+ this.#description = description;
180
+ return this;
181
+ }
182
+ version(version) {
183
+ this.#version = version;
184
+ return this;
185
+ }
186
+ use(plugin) {
187
+ plugin.setup(this);
188
+ return this;
189
+ }
190
+ errorHandler(handler) {
191
+ this.#errorHandlers.push(handler);
192
+ return this;
193
+ }
194
+ #handleError(error) {
195
+ if (this.#errorHandlers.length > 0) for (const callback of this.#errorHandlers) callback(error);
196
+ else throw error;
197
+ }
198
+ #callWithErrorHandler(fn) {
199
+ try {
200
+ const result = fn();
201
+ if (result instanceof Promise) result.catch((error) => {
202
+ this.#handleError(error);
203
+ });
204
+ return result;
205
+ } catch (error) {
206
+ this.#handleError(error);
207
+ throw error;
208
+ }
209
+ }
210
+ #validateCommandNameAndAlias(name, aliases) {
211
+ if (this.#commands.has(name)) throw new InvalidCommandError(`Command with name "${name}" already exists.`);
212
+ for (const alias of aliases) if (this.#commands.has(alias)) throw new InvalidCommandError(`Command with name "${alias}" already exists.`);
213
+ }
214
+ command(nameOrCommandObject, description, options) {
215
+ const command = typeof nameOrCommandObject === "string" ? {
216
+ name: nameOrCommandObject,
217
+ description,
218
+ ...options
219
+ } : nameOrCommandObject;
220
+ const aliases = toArray(options?.alias ?? []);
221
+ this.#callWithErrorHandler(() => this.#validateCommandNameAndAlias(command.name, aliases));
222
+ this.#commands.set(command.name, command);
223
+ for (const alias of aliases) this.#commands.set(alias, {
224
+ ...command,
225
+ __isAlias: true
226
+ });
227
+ if (command.handler) this.on(command.name, command.handler);
228
+ return this;
229
+ }
230
+ globalFlag(name, description, options) {
231
+ this.#globalFlags[name] = {
232
+ description,
233
+ ...options
234
+ };
235
+ return this;
236
+ }
237
+ interceptor(interceptor) {
238
+ this.#interceptors.push(interceptor);
239
+ return this;
240
+ }
241
+ on(name, handler) {
242
+ this.#emitter.on(name, handler);
243
+ return this;
244
+ }
245
+ #validate() {
246
+ if (!this.#scriptName) throw new MissingRequiredMetadataError("script name");
247
+ if (!this.#description) throw new MissingRequiredMetadataError("description");
248
+ if (!this.#version) throw new MissingRequiredMetadataError("version");
249
+ }
250
+ #parseArgv(argv, command) {
251
+ const { flags, ignore } = command ?? {};
252
+ return this.#callWithErrorHandler(() => parse(argv, {
253
+ flags: {
254
+ ...this.#globalFlags,
255
+ ...flags
256
+ },
257
+ ignore
258
+ }));
259
+ }
260
+ run() {
261
+ const parametersToResolve = getParametersToResolve(this.#argv);
262
+ const [command, calledAs] = resolveCommand(this.#commands, parametersToResolve);
263
+ const argvToPass = command && calledAs.length > 0 ? this.#argv.slice(calledAs.split(" ").length) : this.#argv;
264
+ const parsed = this.#callWithErrorHandler(() => this.#parseArgv(argvToPass, command));
265
+ let parameters = {};
266
+ let parametersError;
267
+ try {
268
+ parameters = command?.parameters ? parseParameters(command.parameters, parsed.parameters, parsed.doubleDash) : {};
269
+ } catch (e) {
270
+ parametersError = e;
271
+ }
272
+ const context = {
273
+ resolved: !!command,
274
+ command,
275
+ calledAs,
276
+ parameters,
277
+ flags: parsed.flags,
278
+ ignored: parsed.ignored,
279
+ rawParsed: parsed,
280
+ maybeMissingParameters: !!parametersError
281
+ };
282
+ const emitInterceptor = {
283
+ enforce: "post",
284
+ handler: (ctx) => {
285
+ if (parametersError) throw parametersError;
286
+ if (command) this.#emitter.emit(command.name, ctx);
287
+ else throw parametersToResolve.length > 0 ? new NoSuchCommandError(parametersToResolve.join(" ")) : new NoCommandGivenError();
288
+ }
289
+ };
290
+ const composedInterceptor = compose([...this.#interceptors, emitInterceptor]);
291
+ this.#callWithErrorHandler(() => composedInterceptor(context));
292
+ }
293
+ parse(argv = platformArgv, { run = true } = {}) {
294
+ this.#callWithErrorHandler(() => this.#validate());
295
+ this.#argv = argv;
296
+ if (run) this.run();
297
+ return this;
298
+ }
816
299
  };
817
- let Clerc = _Clerc;
818
300
 
819
- const definePlugin = (p) => p;
820
- const defineHandler = (_cli, _key, handler) => handler;
821
- const defineInterceptor = (_cli, interceptor) => interceptor;
822
- const defineInspector = defineInterceptor;
823
- const defineCommand = (command, handler) => ({
824
- ...command,
825
- handler
826
- });
301
+ //#endregion
302
+ //#region src/helpers.ts
303
+ const defineCommand = (command) => command;
304
+
305
+ //#endregion
306
+ //#region src/ignore.ts
307
+ function createStopAtFirstParameter() {
308
+ let encounteredParameter = false;
309
+ return (type) => {
310
+ if (type === PARAMETER && !encounteredParameter) {
311
+ encounteredParameter = true;
312
+ return false;
313
+ }
314
+ return encounteredParameter;
315
+ };
316
+ }
317
+
318
+ //#endregion
319
+ //#region src/plugin.ts
320
+ const definePlugin = (plugin) => plugin;
827
321
 
828
- export { Clerc, CommandExistsError, CommandNameConflictError, DescriptionNotSetError, InvalidCommandNameError, LocaleNotCalledFirstError, NoCommandGivenError, NoSuchCommandError, Root, ScriptNameNotSetError, VersionNotSetError, compose, defineCommand, defineHandler, defineInspector, defineInterceptor, definePlugin, detectLocale, formatCommandName, isValidName, resolveArgv, resolveCommand, resolveFlattenCommands, stripFlags, withBrackets };
322
+ //#endregion
323
+ export { Clerc, InvalidCommandError, InvalidParametersError, MissingRequiredMetadataError, NoCommandGivenError, NoSuchCommandError, createStopAtFirstParameter, defineCommand, definePlugin, resolveCommand };