@clerc/core 1.0.0-beta.1 → 1.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,23 @@
1
1
  import { ErrorHandler as ErrorHandler$1 } from "lite-emit";
2
2
 
3
+ //#region ../parser/src/flag-types.d.ts
4
+
5
+ /**
6
+ * Creates a Choices type function that validates the input against allowed values.
7
+ * The display name will be formatted as "value1 | value2 | ..." for help output.
8
+ *
9
+ * @param values - Array of allowed string values
10
+ * @returns A FlagTypeFunction that validates and returns the input value
11
+ * @throws {Error} If the value is not in the allowed values list
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const format = Choices(['json', 'yaml', 'xml']);
16
+ * // Help output will show: json | yaml | xml
17
+ * ```
18
+ */
19
+ declare function Choices<T extends string>(...values: T[]): FlagTypeFunction<T>;
20
+ //#endregion
3
21
  //#region ../utils/src/types/type-fest.d.ts
4
22
  type LiteralUnion<LiteralType, BaseType> = LiteralType | (BaseType & Record<never, never>);
5
23
  type Prettify<T> = { [K in keyof T]: T[K] } & {};
@@ -10,11 +28,13 @@ type UnknownArray = readonly unknown[];
10
28
  type MapsSetsOrArrays = ReadonlyMap<unknown, unknown> | WeakMap<WeakKey, unknown> | ReadonlySet<unknown> | WeakSet<WeakKey> | UnknownArray;
11
29
  type ConditionalDeepPrettify<T, E = never, I$1 = unknown> = T extends E ? T : T extends I$1 ? { [TypeKey in keyof T]: ConditionalDeepPrettify<T[TypeKey], E, I$1> } : T;
12
30
  type DeepPrettify<T, E = never> = ConditionalDeepPrettify<T, E | NonRecursiveType | MapsSetsOrArrays, object>;
31
+ type IsAny<T> = 0 extends 1 & T ? true : false;
13
32
  //#endregion
14
33
  //#region ../utils/src/types/index.d.ts
15
34
  type MaybeArray<T> = T | T[];
16
35
  type PartialRequired<T, K$1 extends keyof T> = T & { [P in K$1]-?: T[P] };
17
36
  type UnionToIntersection<U$1> = (U$1 extends any ? (k: U$1) => void : never) extends ((k: infer I) => void) ? I : never;
37
+ type CamelCase<S extends string> = S extends `${infer Head} ${infer Tail}` ? `${Head}${Capitalize<CamelCase<Tail>>}` : S extends `${infer Head}-${infer Tail}` ? `${Head}${Capitalize<CamelCase<Tail>>}` : S;
18
38
  //#endregion
19
39
  //#region ../parser/src/types.d.ts
20
40
  type FlagDefaultValue<T = unknown> = T | (() => T);
@@ -23,7 +43,13 @@ type FlagDefaultValue<T = unknown> = T | (() => T);
23
43
  *
24
44
  * @template T The target type.
25
45
  */
26
- type FlagTypeFunction<T = unknown> = (value: string) => T;
46
+ type FlagTypeFunction<T = unknown> = ((value: string) => T) & {
47
+ /**
48
+ * Optional display name for the type, useful in help output.
49
+ * If provided, this will be shown instead of the function name.
50
+ */
51
+ displayName?: string;
52
+ };
27
53
  /**
28
54
  * A callback function to conditionally stop parsing.
29
55
  * When it returns true, parsing stops and remaining arguments are preserved in `ignored`.
@@ -88,7 +114,10 @@ interface ParsedResult<TFlags extends Record<string, any>> {
88
114
  type InferFlagDefault<T extends FlagDefinitionValue, Fallback> = T extends {
89
115
  default: FlagDefaultValue<infer DefaultType>;
90
116
  } ? DefaultType : Fallback;
91
- type _InferFlags<T extends FlagsDefinition> = { [K in keyof T]: T[K] extends readonly [BooleanConstructor] | {
117
+ type IsTypeAny<T extends FlagDefinitionValue> = IsAny<T> extends true ? true : T extends {
118
+ type: infer Type;
119
+ } ? IsAny<Type> extends true ? true : false : false;
120
+ type _InferFlags<T extends FlagsDefinition> = { [K in keyof T]: IsTypeAny<T[K]> extends true ? any : T[K] extends readonly [BooleanConstructor] | {
92
121
  type: readonly [BooleanConstructor];
93
122
  } ? number : T[K] extends ObjectConstructor | {
94
123
  type: ObjectConstructor;
@@ -110,17 +139,23 @@ declare const KNOWN_FLAG = "known-flag";
110
139
  declare const UNKNOWN_FLAG = "unknown-flag";
111
140
  declare const PARAMETER = "parameter";
112
141
  //#endregion
142
+ //#region ../parser/src/parse.d.ts
143
+ declare const DOUBLE_DASH = "--";
144
+ //#endregion
113
145
  //#region src/types/clerc.d.ts
114
146
  type ErrorHandler = (error: unknown) => void;
115
147
  //#endregion
116
148
  //#region src/types/flag.d.ts
117
- type ClercFlagOptions = FlagOptions & {
149
+ interface FlagCustomOptions {}
150
+ type ClercFlagOptions = FlagOptions & FlagCustomOptions;
151
+ type ClercGlobalFlagDefinitionValue = ClercFlagOptions | FlagType;
152
+ type ClercFlagOptionsWithDescription = ClercFlagOptions & {
118
153
  description: string;
119
154
  };
120
- type ClercFlagsDefinition = Record<string, ClercFlagOptions>;
155
+ type ClercFlagsDefinition = Record<string, ClercFlagOptionsWithDescription>;
121
156
  //#endregion
122
157
  //#region src/types/parameters.d.ts
123
- type InferParameter<T extends string> = T extends `<${infer Name extends string}...>` | `[${infer Name extends string}...]` ? Record<Name, string[]> : T extends `<${infer Name extends string}>` ? Record<Name, string> : T extends `[${infer Name extends string}]` ? Record<Name, string | undefined> : never;
158
+ type InferParameter<T extends string> = T extends `<${infer Name extends string}...>` | `[${infer Name extends string}...]` ? Record<CamelCase<Name>, string[]> : T extends `<${infer Name extends string}>` ? Record<CamelCase<Name>, string> : T extends `[${infer Name extends string}]` ? Record<CamelCase<Name>, string | undefined> : never;
124
159
  type InferParameters<T extends string[]> = T extends (infer U extends string)[] ? Prettify<UnionToIntersection<InferParameter<U>>> : never;
125
160
  //#endregion
126
161
  //#region src/types/context.d.ts
@@ -134,7 +169,7 @@ interface BaseContext<C extends Command = Command, GF extends ClercFlagsDefiniti
134
169
  flags: InferFlagsWithGlobal<C, GF>;
135
170
  ignored: string[];
136
171
  rawParsed: ParsedResult<InferFlagsWithGlobal<C, GF>>;
137
- maybeMissingParameters?: boolean;
172
+ missingParameters: boolean;
138
173
  }
139
174
  //#endregion
140
175
  //#region src/types/command.d.ts
@@ -189,8 +224,9 @@ interface CreateOptions {
189
224
  description?: string;
190
225
  version?: string;
191
226
  }
192
- interface ParseOptions {
193
- run?: boolean;
227
+ interface ParseOptions<Run extends boolean = true> {
228
+ argv?: string[];
229
+ run?: Run;
194
230
  }
195
231
  declare class Clerc<Commands extends CommandsRecord = {}, GlobalFlags extends ClercFlagsDefinition = {}> {
196
232
  #private;
@@ -210,13 +246,11 @@ declare class Clerc<Commands extends CommandsRecord = {}, GlobalFlags extends Cl
210
246
  errorHandler(handler: ErrorHandler$1): this;
211
247
  command<Name$1 extends string, Parameters extends string[] = [], Flags extends ClercFlagsDefinition = {}>(command: CommandWithHandler<Name$1, [...Parameters], Flags>): Clerc<Commands & Record<string, CommandWithHandler<Name$1, Parameters, Flags>>, GlobalFlags>;
212
248
  command<Name$1 extends string, Parameters extends string[] = [], Flags extends ClercFlagsDefinition = {}>(name: Name$1 extends keyof Commands ? ["COMMAND ALREADY EXISTS"] : Name$1, description: string, options?: CommandOptions<[...Parameters], Flags>): Clerc<Commands & Record<Name$1, Command<Name$1, Parameters, Flags>>, GlobalFlags>;
213
- globalFlag<Name$1 extends string, Flag extends FlagDefinitionValue>(name: Name$1, description: string, options: Flag): Clerc<Commands, GlobalFlags & Record<Name$1, Flag>>;
249
+ globalFlag<Name$1 extends string, Flag extends ClercGlobalFlagDefinitionValue>(name: Name$1, description: string, options: Flag): Clerc<Commands, GlobalFlags & Record<Name$1, Flag>>;
214
250
  interceptor(interceptor: Interceptor<Command, GlobalFlags>): this;
215
251
  on<Name$1 extends LiteralUnion<keyof Commands, string>>(name: Name$1, handler: CommandHandler<Commands[Name$1], GlobalFlags>): this;
216
- run(): void;
217
- parse(argv?: string[], {
218
- run
219
- }?: ParseOptions): this;
252
+ run(): Promise<void>;
253
+ parse<Run extends boolean = true>(argvOrOptions?: string[] | ParseOptions<Run>): Run extends true ? Promise<void> : this;
220
254
  }
221
255
  //#endregion
222
256
  //#region src/commands.d.ts
@@ -225,10 +259,10 @@ declare function resolveCommand(commandsMap: CommandsMap, parameters: string[]):
225
259
  //#region src/errors.d.ts
226
260
  declare class NoSuchCommandError extends Error {
227
261
  commandName: string;
228
- constructor(commandName: string);
262
+ constructor(commandName: string, text?: string);
229
263
  }
230
- declare class NoCommandGivenError extends Error {
231
- constructor();
264
+ declare class NoCommandSpecifiedError extends Error {
265
+ constructor(text?: string);
232
266
  }
233
267
  declare class InvalidCommandError extends Error {
234
268
  constructor(message: string);
@@ -249,4 +283,4 @@ declare function createStopAtFirstParameter(): IgnoreFunction;
249
283
  //#region src/plugin.d.ts
250
284
  declare const definePlugin: (plugin: Plugin) => Plugin;
251
285
  //#endregion
252
- export { BaseContext, Clerc, ClercFlagOptions, ClercFlagsDefinition, Command, CommandCustomOptions, CommandHandler, CommandHandlerContext, CommandOptions, CommandWithHandler, CommandsMap, CommandsRecord, ErrorHandler, InferParameters, Interceptor, InterceptorContext, InterceptorHandler, InterceptorNext, InterceptorObject, InvalidCommandError, InvalidParametersError, MakeEmitterEvents, MissingRequiredMetadataError, NoCommandGivenError, NoSuchCommandError, Plugin, createStopAtFirstParameter, defineCommand, definePlugin, resolveCommand };
286
+ export { BaseContext, Choices, Clerc, ClercFlagOptions, ClercFlagOptionsWithDescription, ClercFlagsDefinition, ClercGlobalFlagDefinitionValue, Command, CommandCustomOptions, CommandHandler, CommandHandlerContext, CommandOptions, CommandWithHandler, CommandsMap, CommandsRecord, DOUBLE_DASH, ErrorHandler, FlagCustomOptions, InferParameters, Interceptor, InterceptorContext, InterceptorHandler, InterceptorNext, InterceptorObject, InvalidCommandError, InvalidParametersError, KNOWN_FLAG, MakeEmitterEvents, MissingRequiredMetadataError, NoCommandSpecifiedError, NoSuchCommandError, PARAMETER, Plugin, UNKNOWN_FLAG, createStopAtFirstParameter, defineCommand, definePlugin, resolveCommand };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { DOUBLE_DASH, PARAMETER, parse } from "@clerc/parser";
2
- import { toArray } from "@clerc/utils";
1
+ import { Choices, DOUBLE_DASH, DOUBLE_DASH as DOUBLE_DASH$1, KNOWN_FLAG, PARAMETER, PARAMETER as PARAMETER$1, UNKNOWN_FLAG, parse } from "@clerc/parser";
2
+ import { camelCase, toArray } from "@clerc/utils";
3
3
  import { LiteEmit } from "lite-emit";
4
4
 
5
5
  //#region src/commands.ts
@@ -14,14 +14,14 @@ function resolveCommand(commandsMap, parameters) {
14
14
  //#endregion
15
15
  //#region src/errors.ts
16
16
  var NoSuchCommandError = class extends Error {
17
- constructor(commandName) {
18
- super(`No such command: "${commandName}".`);
17
+ constructor(commandName, text = `No such command: "${commandName}".`) {
18
+ super(text);
19
19
  this.commandName = commandName;
20
20
  }
21
21
  };
22
- var NoCommandGivenError = class extends Error {
23
- constructor() {
24
- super("No command specified.");
22
+ var NoCommandSpecifiedError = class extends Error {
23
+ constructor(text = "No command specified.") {
24
+ super(text);
25
25
  }
26
26
  };
27
27
  var InvalidCommandError = class extends Error {
@@ -82,7 +82,7 @@ function getParametersToResolve(argv) {
82
82
  }
83
83
  return parameters;
84
84
  }
85
- const PARAMETER_REGEX = /^(<|\[)(\w+)(\.\.\.)?(\]|>)$/;
85
+ const PARAMETER_REGEX = /^(<|\[)([\w ]+)(\.\.\.)?(\]|>)$/;
86
86
  const isParameterDefinitionBracketsValid = (definition) => definition.startsWith("<") && definition.endsWith(">") || definition.startsWith("[") && definition.endsWith("]");
87
87
  function _parseParameters(definitions, parameters) {
88
88
  const result = {};
@@ -90,7 +90,7 @@ function _parseParameters(definitions, parameters) {
90
90
  for (const [i, definition] of definitions.entries()) {
91
91
  const match = definition.match(PARAMETER_REGEX);
92
92
  if (!match || !isParameterDefinitionBracketsValid(definition)) throw new InvalidParametersError(`Invalid parameter definition: ${definition}`);
93
- const name = match[2];
93
+ const name = camelCase(match[2]);
94
94
  const isVariadic = !!match[3];
95
95
  const isRequired = definition.startsWith("<");
96
96
  if (name in result) throw new InvalidParametersError(`Duplicate parameter name: ${name}`);
@@ -105,7 +105,7 @@ function _parseParameters(definitions, parameters) {
105
105
  return result;
106
106
  }
107
107
  function parseParameters(definitions, parameters, doubleDashParameters) {
108
- const doubleDashIndex = definitions.indexOf(DOUBLE_DASH);
108
+ const doubleDashIndex = definitions.indexOf(DOUBLE_DASH$1);
109
109
  if (doubleDashIndex === -1) return _parseParameters(definitions, parameters);
110
110
  else {
111
111
  const definitionBeforeDoubleDash = definitions.slice(0, doubleDashIndex);
@@ -198,7 +198,7 @@ var Clerc = class Clerc {
198
198
  #callWithErrorHandler(fn) {
199
199
  try {
200
200
  const result = fn();
201
- if (result instanceof Promise) result.catch((error) => {
201
+ if (result instanceof Promise) return result.catch((error) => {
202
202
  this.#handleError(error);
203
203
  });
204
204
  return result;
@@ -257,7 +257,7 @@ var Clerc = class Clerc {
257
257
  ignore
258
258
  }));
259
259
  }
260
- run() {
260
+ async run() {
261
261
  const parametersToResolve = getParametersToResolve(this.#argv);
262
262
  const [command, calledAs] = resolveCommand(this.#commands, parametersToResolve);
263
263
  const argvToPass = command && calledAs.length > 0 ? this.#argv.slice(calledAs.split(" ").length) : this.#argv;
@@ -277,23 +277,25 @@ var Clerc = class Clerc {
277
277
  flags: parsed.flags,
278
278
  ignored: parsed.ignored,
279
279
  rawParsed: parsed,
280
- maybeMissingParameters: !!parametersError
280
+ missingParameters: !!parametersError
281
281
  };
282
282
  const emitInterceptor = {
283
283
  enforce: "post",
284
284
  handler: (ctx) => {
285
285
  if (parametersError) throw parametersError;
286
286
  if (command) this.#emitter.emit(command.name, ctx);
287
- else throw parametersToResolve.length > 0 ? new NoSuchCommandError(parametersToResolve.join(" ")) : new NoCommandGivenError();
287
+ else throw parametersToResolve.length > 0 ? new NoSuchCommandError(parametersToResolve.join(" ")) : new NoCommandSpecifiedError();
288
288
  }
289
289
  };
290
290
  const composedInterceptor = compose([...this.#interceptors, emitInterceptor]);
291
- this.#callWithErrorHandler(() => composedInterceptor(context));
291
+ return this.#callWithErrorHandler(() => composedInterceptor(context));
292
292
  }
293
- parse(argv = platformArgv, { run = true } = {}) {
293
+ parse(argvOrOptions = platformArgv) {
294
294
  this.#callWithErrorHandler(() => this.#validate());
295
+ if (Array.isArray(argvOrOptions)) argvOrOptions = { argv: argvOrOptions };
296
+ const { argv = platformArgv, run = true } = argvOrOptions;
295
297
  this.#argv = argv;
296
- if (run) this.run();
298
+ if (run) return this.run();
297
299
  return this;
298
300
  }
299
301
  };
@@ -307,7 +309,7 @@ const defineCommand = (command) => command;
307
309
  function createStopAtFirstParameter() {
308
310
  let encounteredParameter = false;
309
311
  return (type) => {
310
- if (type === PARAMETER && !encounteredParameter) {
312
+ if (type === PARAMETER$1 && !encounteredParameter) {
311
313
  encounteredParameter = true;
312
314
  return false;
313
315
  }
@@ -320,4 +322,4 @@ function createStopAtFirstParameter() {
320
322
  const definePlugin = (plugin) => plugin;
321
323
 
322
324
  //#endregion
323
- export { Clerc, InvalidCommandError, InvalidParametersError, MissingRequiredMetadataError, NoCommandGivenError, NoSuchCommandError, createStopAtFirstParameter, defineCommand, definePlugin, resolveCommand };
325
+ export { Choices, Clerc, DOUBLE_DASH, InvalidCommandError, InvalidParametersError, KNOWN_FLAG, MissingRequiredMetadataError, NoCommandSpecifiedError, NoSuchCommandError, PARAMETER, UNKNOWN_FLAG, createStopAtFirstParameter, defineCommand, definePlugin, resolveCommand };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clerc/core",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.3",
4
4
  "author": "Ray <i@mk1.io> (https://github.com/so1ve)",
5
5
  "type": "module",
6
6
  "description": "Clerc core",
@@ -45,8 +45,8 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "lite-emit": "^3.1.0",
48
- "@clerc/parser": "^1.0.0-beta.1",
49
- "@clerc/utils": "1.0.0-beta.1"
48
+ "@clerc/parser": "^1.0.0-beta.3",
49
+ "@clerc/utils": "1.0.0-beta.3"
50
50
  },
51
51
  "devDependencies": {
52
52
  "is-platform": "^1.0.0"