@clerc/parser 1.0.0-beta.25 → 1.0.0-beta.26

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
@@ -2,13 +2,11 @@
2
2
  declare class InvalidSchemaError extends Error {
3
3
  constructor(message: string);
4
4
  }
5
- declare class MissingRequiredFlagError extends Error {
6
- constructor(name: string);
7
- }
8
5
  //#endregion
9
6
  //#region ../utils/src/types/type-fest.d.ts
10
7
  type Prettify<T> = { [K in keyof T]: T[K] } & {};
11
8
  type IsAny<T> = 0 extends 1 & T ? true : false;
9
+ type RequireExactlyOneOrNone<T, Keys extends keyof T = keyof T> = ({ [K in Keys]-?: Required<Pick<T, K>> & Partial<Record<Exclude<Keys, K>, never>> }[Keys] & Omit<T, Keys>) | (Partial<Record<Keys, never>> & Omit<T, Keys>);
12
10
  //#endregion
13
11
  //#region src/iterator.d.ts
14
12
  declare const KNOWN_FLAG = "known-flag";
@@ -44,7 +42,13 @@ interface TypeFunction<T = unknown> {
44
42
  */
45
43
  type IgnoreFunction = (type: typeof KNOWN_FLAG | typeof UNKNOWN_FLAG | typeof PARAMETER, arg: string) => boolean;
46
44
  type TypeValue<T = unknown> = TypeFunction<T> | readonly [TypeFunction<T>];
47
- interface BaseFlagOptions<T extends TypeValue = TypeValue> {
45
+ type Foo = RequireExactlyOneOrNone<{
46
+ /** The default value of the flag. */
47
+ default?: unknown;
48
+ /** Whether the flag is required. */
49
+ required?: boolean;
50
+ }, "default" | "required">;
51
+ type BaseFlagOptions<T extends TypeValue = TypeValue> = Foo & {
48
52
  /**
49
53
  * The type constructor or a function to convert the string value.
50
54
  * To support multiple occurrences of a flag (e.g., --file a --file b), wrap the type in an array: [String], [Number].
@@ -53,11 +57,7 @@ interface BaseFlagOptions<T extends TypeValue = TypeValue> {
53
57
  type: T;
54
58
  /** Short flag alias (single character). */
55
59
  short?: string;
56
- /** The default value of the flag. */
57
- default?: unknown;
58
- /** Whether the flag is required. */
59
- required?: boolean;
60
- }
60
+ };
61
61
  type FlagOptions = (BaseFlagOptions<BooleanConstructor> & {
62
62
  /**
63
63
  * Whether to enable the `--no-<flag>` syntax to set the value to false.
@@ -118,6 +118,8 @@ interface ParsedResult<TFlags extends Record<string, any>> {
118
118
  unknown: Record<string, RawInputType>;
119
119
  /** Arguments that were not parsed due to ignore callback. */
120
120
  ignored: string[];
121
+ /** List of required flags that were not provided. */
122
+ missingRequiredFlags: string[];
121
123
  }
122
124
  type InferFlagDefault<T extends FlagDefinitionValue, Fallback> = T extends {
123
125
  default: FlagDefaultValue<infer DefaultType>;
@@ -187,4 +189,4 @@ declare function createParser<T extends FlagsDefinition>(options?: ParserOptions
187
189
  };
188
190
  declare const parse: <T extends FlagsDefinition>(args: string[], options?: ParserOptions<T>) => ParsedResult<InferFlags<T>>;
189
191
  //#endregion
190
- export { BaseFlagOptions, DOUBLE_DASH, Enum, FlagDefaultValue, FlagDefaultValueFunction, FlagDefinitionValue, FlagOptions, FlagsDefinition, IgnoreFunction, InferFlags, InvalidSchemaError, KNOWN_FLAG, MissingRequiredFlagError, ObjectInputType, PARAMETER, ParsedResult, ParserOptions, Range, RawInputType, Regex, TypeFunction, TypeValue, UNKNOWN_FLAG, createParser, parse };
192
+ export { BaseFlagOptions, DOUBLE_DASH, Enum, FlagDefaultValue, FlagDefaultValueFunction, FlagDefinitionValue, FlagOptions, FlagsDefinition, IgnoreFunction, InferFlags, InvalidSchemaError, KNOWN_FLAG, ObjectInputType, PARAMETER, ParsedResult, ParserOptions, Range, RawInputType, Regex, TypeFunction, TypeValue, UNKNOWN_FLAG, createParser, parse };
package/dist/index.js CHANGED
@@ -5,12 +5,6 @@ var InvalidSchemaError = class extends Error {
5
5
  this.name = "InvalidSchemaError";
6
6
  }
7
7
  };
8
- var MissingRequiredFlagError = class extends Error {
9
- constructor(name) {
10
- super(`Missing required flag: ${name}`);
11
- this.name = "MissingRequiredFlagError";
12
- }
13
- };
14
8
 
15
9
  //#endregion
16
10
  //#region src/flag-types.ts
@@ -167,6 +161,7 @@ function buildConfigsAndAliases(delimiters, flags) {
167
161
  names.push(options.short);
168
162
  }
169
163
  if (names.some(isNameInvalid)) throw new InvalidSchemaError(`${prefix} contains reserved characters, which are used as delimiters.`);
164
+ if (options.required && options.default !== void 0) throw new InvalidSchemaError(`${prefix} cannot be both required and have a default value.`);
170
165
  }
171
166
  for (const [name, config] of Object.entries(flags)) {
172
167
  const normalized = normalizeConfig(config);
@@ -240,7 +235,7 @@ const DOUBLE_DASH = "--";
240
235
  function createParser(options = {}) {
241
236
  const { flags: flagsConfig = {}, delimiters, ignore } = resolveParserOptions(options);
242
237
  const { configs, aliases } = buildConfigsAndAliases(delimiters, flagsConfig);
243
- function resolve(name) {
238
+ function resolve(name, isShortFlag = false) {
244
239
  const dotIdx = name.indexOf(".");
245
240
  const rootName = dotIdx === -1 ? name : name.slice(0, dotIdx);
246
241
  let key = aliases.get(rootName);
@@ -249,6 +244,7 @@ function createParser(options = {}) {
249
244
  if (!key) return;
250
245
  }
251
246
  const config = configs.get(key);
247
+ if (!isShortFlag && config.short === rootName) return;
252
248
  return {
253
249
  key,
254
250
  config,
@@ -269,21 +265,22 @@ function createParser(options = {}) {
269
265
  if (len < 2) return false;
270
266
  const secondChar = arg.charCodeAt(1);
271
267
  if (isLetter(secondChar)) return true;
272
- if (isDigit(secondChar)) return !!resolve(secondChar !== 45 ? arg[1] : arg.slice(2));
268
+ if (isDigit(secondChar)) {
269
+ const isShortFlag = secondChar !== 45;
270
+ return !!resolve(isShortFlag ? arg[1] : arg.slice(2), isShortFlag);
271
+ }
273
272
  if (secondChar === 45 && len > 2) return isLetter(arg.charCodeAt(2));
274
273
  return false;
275
274
  }
276
275
  function isKnownFlag(arg) {
277
- const secondChar = arg.charCodeAt(1);
278
- if (secondChar === 45) {
276
+ if (arg.charCodeAt(1) === 45) {
279
277
  const { rawName } = splitNameAndValue(arg.slice(2), delimiters);
280
- if (resolve(rawName)) return true;
278
+ if (resolve(rawName, false)) return true;
281
279
  if (resolveNegated(rawName)) return true;
282
280
  return false;
283
281
  }
284
- if (isDigit(secondChar)) return true;
285
282
  const chars = arg.slice(1);
286
- for (const char of chars) if (!resolve(char)) return false;
283
+ for (const char of chars) if (!resolve(char, true)) return false;
287
284
  return true;
288
285
  }
289
286
  const parse$1 = (args) => {
@@ -293,7 +290,8 @@ function createParser(options = {}) {
293
290
  flags: {},
294
291
  raw: args,
295
292
  unknown: {},
296
- ignored: []
293
+ ignored: [],
294
+ missingRequiredFlags: []
297
295
  };
298
296
  iterateArgs(args, result, shouldProcessAsFlag, isKnownFlag, ignore, ({ current, eat, exit, hasNext, index, next, shouldIgnore }) => {
299
297
  if (current === DOUBLE_DASH) {
@@ -310,13 +308,13 @@ function createParser(options = {}) {
310
308
  result.parameters.push(current);
311
309
  return;
312
310
  }
313
- const isAlias = !current.startsWith(DOUBLE_DASH);
314
- const chars = current.slice(isAlias ? 1 : 2);
315
- if (isAlias) {
311
+ const isShortFlag = !current.startsWith(DOUBLE_DASH);
312
+ const chars = current.slice(isShortFlag ? 1 : 2);
313
+ if (isShortFlag) {
316
314
  const charsLen = chars.length;
317
315
  for (let j = 0; j < charsLen; j++) {
318
316
  const char = chars[j];
319
- const resolved = resolve(char);
317
+ const resolved = resolve(char, true);
320
318
  if (!resolved) {
321
319
  result.unknown[char] = true;
322
320
  continue;
@@ -373,7 +371,7 @@ function createParser(options = {}) {
373
371
  else if (Array.isArray(config.type)) result.flags[key] = isArrayOfType(config.type, Boolean) ? 0 : [];
374
372
  else if (config.type === Object) result.flags[key] = {};
375
373
  else if (config.type === Boolean) result.flags[key] = false;
376
- else if (config.required) throw new MissingRequiredFlagError(key);
374
+ else if (config.required) result.missingRequiredFlags.push(key);
377
375
  }
378
376
  return result;
379
377
  };
@@ -382,4 +380,4 @@ function createParser(options = {}) {
382
380
  const parse = (args, options = {}) => createParser(options).parse(args);
383
381
 
384
382
  //#endregion
385
- export { DOUBLE_DASH, Enum, InvalidSchemaError, KNOWN_FLAG, MissingRequiredFlagError, PARAMETER, Range, Regex, UNKNOWN_FLAG, createParser, parse };
383
+ export { DOUBLE_DASH, Enum, InvalidSchemaError, KNOWN_FLAG, PARAMETER, Range, Regex, UNKNOWN_FLAG, createParser, parse };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clerc/parser",
3
- "version": "1.0.0-beta.25",
3
+ "version": "1.0.0-beta.26",
4
4
  "author": "Ray <i@mk1.io> (https://github.com/so1ve)",
5
5
  "type": "module",
6
6
  "description": "Clerc parser",
@@ -56,6 +56,6 @@
56
56
  "nopt": "^9.0.0",
57
57
  "type-flag": "^4.0.3",
58
58
  "yargs-parser": "^22.0.0",
59
- "@clerc/utils": "1.0.0-beta.25"
59
+ "@clerc/utils": "1.0.0-beta.26"
60
60
  }
61
61
  }