@clerc/parser 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/README.md CHANGED
@@ -332,3 +332,31 @@ const { flags, doubleDash } = parse(["--foo", "--", "--bar"], {
332
332
  // flags: { foo: true, bar: false }
333
333
  // doubleDash: ["--bar"]
334
334
  ```
335
+
336
+ ## Benchmark
337
+
338
+ Benchmarked with vitest.
339
+
340
+ ```
341
+ ✓ packages/parser/bench/bench.bench.ts > bench 6267ms
342
+ name hz min max mean p75 p99 p995 p999 rme samples
343
+ · minimist 684,422.77 0.0012 3.5582 0.0015 0.0013 0.0031 0.0040 0.0222 ±1.50% 342212
344
+ · mri 2,451,855.02 0.0003 0.2422 0.0004 0.0004 0.0007 0.0009 0.0021 ±0.33% 1225928
345
+ · yargs-parser 90,437.66 0.0092 3.1595 0.0111 0.0103 0.0346 0.0602 0.1311 ±1.42% 45219
346
+ · nopt 636,086.73 0.0014 0.3214 0.0016 0.0015 0.0027 0.0031 0.0056 ±0.38% 318044
347
+ · type-flag 715,908.28 0.0012 0.3783 0.0014 0.0013 0.0022 0.0027 0.0282 ±0.61% 357955
348
+ · node:util parseArgs 1,204,359.72 0.0007 0.3827 0.0008 0.0008 0.0016 0.0017 0.0047 ±0.56% 602196
349
+ · args-tokens 2,379,934.00 0.0002 0.2923 0.0004 0.0004 0.0010 0.0015 0.0051 ±0.49% 1189967
350
+ · @clerc/parser 2,119,030.30 0.0003 0.2482 0.0005 0.0005 0.0009 0.0011 0.0017 ±0.49% 1059516
351
+
352
+ BENCH Summary
353
+
354
+ mri - packages/parser/bench/bench.bench.ts > bench
355
+ 1.03x faster than args-tokens
356
+ 1.16x faster than @clerc/parser
357
+ 2.04x faster than node:util parseArgs
358
+ 3.42x faster than type-flag
359
+ 3.58x faster than minimist
360
+ 3.85x faster than nopt
361
+ 27.11x faster than yargs-parser
362
+ ```
package/dist/index.d.ts CHANGED
@@ -3,8 +3,26 @@ declare class InvalidSchemaError extends Error {
3
3
  constructor(message: string);
4
4
  }
5
5
  //#endregion
6
+ //#region src/flag-types.d.ts
7
+ /**
8
+ * Creates a Choices type function that validates the input against allowed values.
9
+ * The display name will be formatted as "value1 | value2 | ..." for help output.
10
+ *
11
+ * @param values - Array of allowed string values
12
+ * @returns A FlagTypeFunction that validates and returns the input value
13
+ * @throws {Error} If the value is not in the allowed values list
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const format = Choices(['json', 'yaml', 'xml']);
18
+ * // Help output will show: json | yaml | xml
19
+ * ```
20
+ */
21
+ declare function Choices<T extends string>(...values: T[]): FlagTypeFunction<T>;
22
+ //#endregion
6
23
  //#region ../utils/src/types/type-fest.d.ts
7
24
  type Prettify<T> = { [K in keyof T]: T[K] } & {};
25
+ type IsAny<T> = 0 extends 1 & T ? true : false;
8
26
  //#endregion
9
27
  //#region ../utils/src/types/index.d.ts
10
28
  type MaybeArray<T> = T | T[];
@@ -16,7 +34,13 @@ type FlagDefaultValue<T = unknown> = T | (() => T);
16
34
  *
17
35
  * @template T The target type.
18
36
  */
19
- type FlagTypeFunction<T = unknown> = (value: string) => T;
37
+ type FlagTypeFunction<T = unknown> = ((value: string) => T) & {
38
+ /**
39
+ * Optional display name for the type, useful in help output.
40
+ * If provided, this will be shown instead of the function name.
41
+ */
42
+ displayName?: string;
43
+ };
20
44
  /**
21
45
  * A callback function to conditionally stop parsing.
22
46
  * When it returns true, parsing stops and remaining arguments are preserved in `ignored`.
@@ -103,7 +127,10 @@ interface ParsedResult<TFlags extends Record<string, any>> {
103
127
  type InferFlagDefault<T extends FlagDefinitionValue, Fallback> = T extends {
104
128
  default: FlagDefaultValue<infer DefaultType>;
105
129
  } ? DefaultType : Fallback;
106
- type _InferFlags<T extends FlagsDefinition> = { [K in keyof T]: T[K] extends readonly [BooleanConstructor] | {
130
+ type IsTypeAny<T extends FlagDefinitionValue> = IsAny<T> extends true ? true : T extends {
131
+ type: infer Type;
132
+ } ? IsAny<Type> extends true ? true : false : false;
133
+ type _InferFlags<T extends FlagsDefinition> = { [K in keyof T]: IsTypeAny<T[K]> extends true ? any : T[K] extends readonly [BooleanConstructor] | {
107
134
  type: readonly [BooleanConstructor];
108
135
  } ? number : T[K] extends ObjectConstructor | {
109
136
  type: ObjectConstructor;
@@ -133,4 +160,4 @@ declare function createParser<T extends FlagsDefinition>(options?: ParserOptions
133
160
  };
134
161
  declare const parse: <T extends FlagsDefinition>(args: string[], options?: ParserOptions<T>) => ParsedResult<InferFlags<T>>;
135
162
  //#endregion
136
- export { BaseFlagOptions, DOUBLE_DASH, FlagDefaultValue, FlagDefinitionValue, FlagOptions, FlagType, FlagTypeFunction, FlagsDefinition, IgnoreFunction, InferFlags, InvalidSchemaError, KNOWN_FLAG, ObjectInputType, PARAMETER, ParsedResult, ParserOptions, RawInputType, UNKNOWN_FLAG, createParser, parse };
163
+ export { BaseFlagOptions, Choices, DOUBLE_DASH, FlagDefaultValue, FlagDefinitionValue, FlagOptions, FlagType, FlagTypeFunction, FlagsDefinition, IgnoreFunction, InferFlags, InvalidSchemaError, KNOWN_FLAG, ObjectInputType, PARAMETER, ParsedResult, ParserOptions, RawInputType, UNKNOWN_FLAG, createParser, parse };
package/dist/index.js CHANGED
@@ -6,6 +6,31 @@ var InvalidSchemaError = class extends Error {
6
6
  }
7
7
  };
8
8
 
9
+ //#endregion
10
+ //#region src/flag-types.ts
11
+ /**
12
+ * Creates a Choices type function that validates the input against allowed values.
13
+ * The display name will be formatted as "value1 | value2 | ..." for help output.
14
+ *
15
+ * @param values - Array of allowed string values
16
+ * @returns A FlagTypeFunction that validates and returns the input value
17
+ * @throws {Error} If the value is not in the allowed values list
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const format = Choices(['json', 'yaml', 'xml']);
22
+ * // Help output will show: json | yaml | xml
23
+ * ```
24
+ */
25
+ function Choices(...values) {
26
+ const fn = ((value) => {
27
+ if (!values.includes(value)) throw new Error(`Invalid value: ${value}. Must be one of: ${values.join(", ")}`);
28
+ return value;
29
+ });
30
+ fn.displayName = values.join(" | ");
31
+ return fn;
32
+ }
33
+
9
34
  //#endregion
10
35
  //#region src/iterator.ts
11
36
  const KNOWN_FLAG = "known-flag";
@@ -59,14 +84,14 @@ function iterateArgs(args, result, shouldProcessAsFlag, isKnownFlag, ignore, cal
59
84
  //#region ../utils/dist/index.js
60
85
  const toArray = (a) => Array.isArray(a) ? a : [a];
61
86
  /**
62
- * Converts a dash-separated string to camelCase.
87
+ * Converts a dash- or space-separated string to camelCase.
63
88
  * Not using regexp for better performance, because this function is used in parser.
64
89
  */
65
90
  function camelCase(str) {
66
- const dashIdx = str.indexOf("-");
67
- if (dashIdx === -1) return str;
68
- let result = str.slice(0, dashIdx);
69
- for (let i = dashIdx; i < str.length; i++) if (str[i] === "-" && i + 1 < str.length) {
91
+ const firstIdx = Math.min(str.includes("-") ? str.indexOf("-") : Infinity, str.includes(" ") ? str.indexOf(" ") : Infinity);
92
+ if (firstIdx === Infinity) return str;
93
+ let result = str.slice(0, firstIdx);
94
+ for (let i = firstIdx; i < str.length; i++) if ((str[i] === "-" || str[i] === " ") && i + 1 < str.length) {
70
95
  const nextChar = str.charCodeAt(i + 1);
71
96
  if (nextChar >= 97 && nextChar <= 122) {
72
97
  result += String.fromCharCode(nextChar - 32);
@@ -75,7 +100,7 @@ function camelCase(str) {
75
100
  result += str[i + 1];
76
101
  i++;
77
102
  }
78
- } else if (str[i] !== "-") result += str[i];
103
+ } else if (str[i] !== "-" && str[i] !== " ") result += str[i];
79
104
  return result;
80
105
  }
81
106
 
@@ -316,4 +341,4 @@ function createParser(options = {}) {
316
341
  const parse = (args, options = {}) => createParser(options).parse(args);
317
342
 
318
343
  //#endregion
319
- export { DOUBLE_DASH, InvalidSchemaError, KNOWN_FLAG, PARAMETER, UNKNOWN_FLAG, createParser, parse };
344
+ export { Choices, DOUBLE_DASH, InvalidSchemaError, KNOWN_FLAG, PARAMETER, 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.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 parser",
@@ -50,12 +50,13 @@
50
50
  "@types/minimist": "^1.2.5",
51
51
  "@types/nopt": "^3.0.32",
52
52
  "@types/yargs-parser": "^21.0.3",
53
+ "args-tokens": "^0.23.0",
53
54
  "minimist": "^1.2.8",
54
55
  "mri": "^1.2.0",
55
56
  "nopt": "^9.0.0",
56
57
  "type-flag": "^4.0.3",
57
58
  "yargs-parser": "^22.0.0",
58
- "@clerc/utils": "1.0.0-beta.1"
59
+ "@clerc/utils": "1.0.0-beta.3"
59
60
  },
60
61
  "scripts": {
61
62
  "build": "tsdown",