@clerc/parser 1.0.3 → 1.1.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/README.md CHANGED
@@ -20,18 +20,18 @@ The core of this package is the `parse` function. It takes an array of arguments
20
20
  import { parse } from "@clerc/parser";
21
21
 
22
22
  const { flags, parameters, unknown } = parse(process.argv.slice(2), {
23
- flags: {
24
- // Define your flags here
25
- port: {
26
- type: Number,
27
- alias: "p",
28
- default: 8080,
29
- },
30
- help: {
31
- type: Boolean,
32
- alias: "h",
33
- },
34
- },
23
+ flags: {
24
+ // Define your flags here
25
+ port: {
26
+ type: Number,
27
+ alias: "p",
28
+ default: 8080,
29
+ },
30
+ help: {
31
+ type: Boolean,
32
+ alias: "h",
33
+ },
34
+ },
35
35
  });
36
36
 
37
37
  console.log("Flags:", flags);
@@ -81,11 +81,11 @@ Supports `Boolean`, `String`, and `Number`.
81
81
 
82
82
  ```typescript
83
83
  const { flags } = parse(["--bool", "--str", "hello", "--num", "42"], {
84
- flags: {
85
- bool: { type: Boolean },
86
- str: { type: String },
87
- num: { type: Number },
88
- },
84
+ flags: {
85
+ bool: { type: Boolean },
86
+ str: { type: String },
87
+ num: { type: Number },
88
+ },
89
89
  });
90
90
  // flags: { bool: true, str: "hello", num: 42 }
91
91
  ```
@@ -96,10 +96,10 @@ Use `alias` to define short or alternative names for flags.
96
96
 
97
97
  ```typescript
98
98
  const { flags } = parse(["-b", "-s", "hello"], {
99
- flags: {
100
- bool: { type: Boolean, alias: "b" },
101
- str: { type: String, alias: "s" },
102
- },
99
+ flags: {
100
+ bool: { type: Boolean, alias: "b" },
101
+ str: { type: String, alias: "s" },
102
+ },
103
103
  });
104
104
  // flags: { bool: true, str: "hello" }
105
105
  ```
@@ -112,17 +112,17 @@ const { flags } = parse(["-b", "-s", "hello"], {
112
112
  ```typescript
113
113
  // Array of strings
114
114
  const { flags: arrayFlags } = parse(["--arr", "a", "--arr", "b"], {
115
- flags: {
116
- arr: { type: [String] },
117
- },
115
+ flags: {
116
+ arr: { type: [String] },
117
+ },
118
118
  });
119
119
  // arrayFlags: { arr: ["a", "b"] }
120
120
 
121
121
  // Counter
122
122
  const { flags: counterFlags } = parse(["-vvv"], {
123
- flags: {
124
- verbose: { type: [Boolean], alias: "v" },
125
- },
123
+ flags: {
124
+ verbose: { type: [Boolean], alias: "v" },
125
+ },
126
126
  });
127
127
  // counterFlags: { verbose: 3 }
128
128
  ```
@@ -134,27 +134,27 @@ Multiple boolean short flags can be combined. The last flag in the group can tak
134
134
  ```typescript
135
135
  // -abc => a=true, b=true, c=true
136
136
  const { flags: merged } = parse(["-abc"], {
137
- flags: {
138
- a: Boolean,
139
- b: Boolean,
140
- c: Boolean,
141
- },
137
+ flags: {
138
+ a: Boolean,
139
+ b: Boolean,
140
+ c: Boolean,
141
+ },
142
142
  });
143
143
  // merged: { a: true, b: true, c: true }
144
144
 
145
145
  // -ab val => a=true, b="val"
146
146
  const { flags: withValue } = parse(["-ab", "val"], {
147
- flags: {
148
- a: Boolean,
149
- b: String,
150
- },
147
+ flags: {
148
+ a: Boolean,
149
+ b: String,
150
+ },
151
151
  });
152
152
  // or -abval, b is not boolean
153
153
  const { flags: withValue } = parse(["-abval"], {
154
- flags: {
155
- a: Boolean,
156
- b: String,
157
- },
154
+ flags: {
155
+ a: Boolean,
156
+ b: String,
157
+ },
158
158
  });
159
159
  // withValue: { a: true, b: "val" }
160
160
  ```
@@ -165,11 +165,11 @@ Provide a `default` value for flags that are not present.
165
165
 
166
166
  ```typescript
167
167
  const { flags } = parse([], {
168
- flags: {
169
- str: { type: String, default: "default" },
170
- num: { type: Number, default: 123 },
171
- fn: { type: String, default: () => "computed" },
172
- },
168
+ flags: {
169
+ str: { type: String, default: "default" },
170
+ num: { type: Number, default: 123 },
171
+ fn: { type: String, default: () => "computed" },
172
+ },
173
173
  });
174
174
  // flags: { str: "default", num: 123, fn: "computed" }
175
175
  ```
@@ -189,14 +189,14 @@ If you want to disable this behavior, set `negatable: false` in the flag configu
189
189
 
190
190
  ```typescript
191
191
  const { flags, unknown } = parse(
192
- ["--no-cache", "--no-ssl=false", "--no-disable-negate"],
193
- {
194
- flags: {
195
- cache: { type: Boolean, default: true },
196
- ssl: { type: Boolean, default: true },
197
- disableNegate: { type: Boolean, negatable: false, default: true },
198
- },
199
- },
192
+ ["--no-cache", "--no-ssl=false", "--no-disable-negate"],
193
+ {
194
+ flags: {
195
+ cache: { type: Boolean, default: true },
196
+ ssl: { type: Boolean, default: true },
197
+ disableNegate: { type: Boolean, negatable: false, default: true },
198
+ },
199
+ },
200
200
  );
201
201
  // flags: { cache: false, ssl: true, disableNegate: true }
202
202
  // unknown: { noDisableNegate: true }
@@ -209,21 +209,21 @@ You can provide a custom function to the `type` property for advanced parsing lo
209
209
  ```typescript
210
210
  // Let's limit port between 1 and 65535
211
211
  const { flags } = parse(["--port", "8080"], {
212
- flags: {
213
- port: {
214
- type: (value: string) => {
215
- const parsed = Number.parseInt(value, 10);
216
- if (Number.isNaN(parsed)) {
217
- throw new TypeError("Port must be a number!");
218
- }
219
- if (parsed < 1 || parsed > 65_535) {
220
- throw new Error("Port must be between 1 and 65535!");
221
- }
222
-
223
- return parsed;
224
- },
225
- },
226
- },
212
+ flags: {
213
+ port: {
214
+ type: (value: string) => {
215
+ const parsed = Number.parseInt(value, 10);
216
+ if (Number.isNaN(parsed)) {
217
+ throw new TypeError("Port must be a number!");
218
+ }
219
+ if (parsed < 1 || parsed > 65_535) {
220
+ throw new Error("Port must be between 1 and 65535!");
221
+ }
222
+
223
+ return parsed;
224
+ },
225
+ },
226
+ },
227
227
  });
228
228
  // flags: { port: 8080 }
229
229
  ```
@@ -234,12 +234,12 @@ Define flags with `Object` type to parse dot-notation arguments into a nested ob
234
234
 
235
235
  ```typescript
236
236
  const { flags } = parse(
237
- ["--config.port", "8080", "--config.host", "localhost"],
238
- {
239
- flags: {
240
- config: { type: Object },
241
- },
242
- },
237
+ ["--config.port", "8080", "--config.host", "localhost"],
238
+ {
239
+ flags: {
240
+ config: { type: Object },
241
+ },
242
+ },
243
243
  );
244
244
  // flags: { config: { port: "8080", host: "localhost" } }
245
245
  ```
@@ -248,21 +248,21 @@ Multi-level nesting is also supported.
248
248
 
249
249
  ```typescript
250
250
  const { flags } = parse(
251
- [
252
- "--db.host",
253
- "localhost",
254
- "--db.port",
255
- "5432",
256
- "--db.credentials.user",
257
- "admin",
258
- "--db.credentials.password",
259
- "secret",
260
- ],
261
- {
262
- flags: {
263
- db: { type: Object },
264
- },
265
- },
251
+ [
252
+ "--db.host",
253
+ "localhost",
254
+ "--db.port",
255
+ "5432",
256
+ "--db.credentials.user",
257
+ "admin",
258
+ "--db.credentials.password",
259
+ "secret",
260
+ ],
261
+ {
262
+ flags: {
263
+ db: { type: Object },
264
+ },
265
+ },
266
266
  );
267
267
  // flags: { db: { host: "localhost", port: "5432", credentials: { user: "admin", password: "secret" } } }
268
268
  ```
@@ -273,11 +273,11 @@ Flags that are not defined in the schema are collected in the `unknown` object.
273
273
 
274
274
  ```typescript
275
275
  const { flags, unknown } = parse([
276
- "--unknown1",
277
- "--unknown2=foo",
278
- "--unknown3",
279
- "bar",
280
- "--unknown.foo",
276
+ "--unknown1",
277
+ "--unknown2=foo",
278
+ "--unknown3",
279
+ "bar",
280
+ "--unknown.foo",
281
281
  ]);
282
282
 
283
283
  // unknown: { unknown1: true, unknown2: "foo", unknown3: "bar", "unknown.foo": true }
@@ -289,12 +289,12 @@ Use the `ignore` function to stop parsing when a certain condition is met. Subse
289
289
 
290
290
  ```typescript
291
291
  const { flags, ignored } = parse(["--a", "--b", "stop", "--c"], {
292
- flags: {
293
- a: Boolean,
294
- b: Boolean,
295
- c: Boolean,
296
- },
297
- ignore: (type, arg) => arg === "stop",
292
+ flags: {
293
+ a: Boolean,
294
+ b: Boolean,
295
+ c: Boolean,
296
+ },
297
+ ignore: (type, arg) => arg === "stop",
298
298
  });
299
299
  // flags: { a: true, b: true, c: false }
300
300
  // ignored: ["stop", "--c"]
@@ -304,13 +304,13 @@ You can ignore everything after the first positional parameter by checking the `
304
304
 
305
305
  ```typescript
306
306
  const { flags, parameters, ignored } = parse(
307
- ["--allow-all", "./deno.ts", "--param"],
308
- {
309
- flags: {
310
- allowAll: Boolean,
311
- },
312
- ignore: (type) => type === "parameter",
313
- },
307
+ ["--allow-all", "./deno.ts", "--param"],
308
+ {
309
+ flags: {
310
+ allowAll: Boolean,
311
+ },
312
+ ignore: (type) => type === "parameter",
313
+ },
314
314
  );
315
315
 
316
316
  // flags: { allowAll: true }
@@ -324,10 +324,10 @@ Arguments after `--` are not parsed as flags and are collected in the `doubleDas
324
324
 
325
325
  ```typescript
326
326
  const { flags, doubleDash } = parse(["--foo", "--", "--bar"], {
327
- flags: {
328
- foo: Boolean,
329
- bar: Boolean,
330
- },
327
+ flags: {
328
+ foo: Boolean,
329
+ bar: Boolean,
330
+ },
331
331
  });
332
332
  // flags: { foo: true, bar: false }
333
333
  // doubleDash: ["--bar"]
@@ -19,42 +19,50 @@ type FlagDefaultValue<T = unknown> = T | FlagDefaultValueFunction<T>;
19
19
  interface TypeFunction<T = unknown> {
20
20
  (value: string): T;
21
21
  /**
22
- * Optional display name for the type, useful in help output.
23
- * If provided, this will be shown instead of the function name.
22
+ * Optional display name for the type, useful in help output. If provided,
23
+ * this will be shown instead of the function name.
24
24
  */
25
25
  display?: string;
26
26
  }
27
27
  /**
28
- * A callback function to conditionally stop parsing.
29
- * When it returns true, parsing stops and remaining arguments are preserved in `ignored`.
28
+ * A callback function to conditionally stop parsing. When it returns true,
29
+ * parsing stops and remaining arguments are preserved in `ignored`.
30
30
  *
31
- * @param type - The type of the current argument: 'known-flag' or 'unknown-flag' for flags, 'parameter' for positional arguments
31
+ * @param type - The type of the current argument: 'known-flag' or
32
+ * 'unknown-flag' for flags, 'parameter' for positional arguments
32
33
  * @param arg - The current argument being processed
33
- * @returns true to stop parsing, false to continue
34
+ * @returns True to stop parsing, false to continue
34
35
  */
35
36
  type IgnoreFunction = (type: typeof KNOWN_FLAG | typeof UNKNOWN_FLAG | typeof PARAMETER, arg: string) => boolean;
36
37
  type TypeValue<T = unknown> = TypeFunction<T> | readonly [TypeFunction<T>];
37
38
  type FlagRequiredOrDefault = RequireExactlyOneOrNone<{
38
- /** The default value of the flag. */
39
+ /**
40
+ * The default value of the flag.
41
+ */
39
42
  default?: unknown;
40
- /** Whether the flag is required. */
43
+ /**
44
+ * Whether the flag is required.
45
+ */
41
46
  required?: boolean;
42
47
  }, "default" | "required">;
43
48
  type BaseFlagOptions<T extends TypeValue = TypeValue> = FlagRequiredOrDefault & {
44
49
  /**
45
- * The type constructor or a function to convert the string value.
46
- * To support multiple occurrences of a flag (e.g., --file a --file b), wrap the type in an array: [String], [Number].
47
- * e.g., String, Number, [String], (val) => val.split(',')
50
+ * The type constructor or a function to convert the string value. To
51
+ * support multiple occurrences of a flag (e.g., --file a --file b), wrap
52
+ * the type in an array: [String], [Number]. e.g., String, Number, [String],
53
+ * (val) => val.split(',')
48
54
  */
49
55
  type: T;
50
- /** Short flag alias (single character). */
56
+ /**
57
+ * Short flag alias (single character).
58
+ */
51
59
  short?: string;
52
60
  };
53
61
  type FlagOptions = (BaseFlagOptions<BooleanConstructor> & {
54
62
  /**
55
63
  * Whether to enable the `--no-<flag>` syntax to set the value to false.
56
- * Only useful for boolean flags.
57
- * When set on a non-boolean flag, a type error will be shown.
64
+ * Only useful for boolean flags. When set on a non-boolean flag, a type
65
+ * error will be shown.
58
66
  *
59
67
  * @default true
60
68
  */
@@ -69,20 +77,20 @@ type FlagsDefinition = Record<string, FlagDefinitionValue>;
69
77
  */
70
78
  interface ParserOptions<T extends FlagsDefinition = {}> {
71
79
  /**
72
- * Detailed configuration for flags.
73
- * Supports the full object syntax or a type constructor as a shorthand.
74
- * The key is the flag name (e.g., "file" for "--file").
80
+ * Detailed configuration for flags. Supports the full object syntax or a type
81
+ * constructor as a shorthand. The key is the flag name (e.g., "file" for
82
+ * "--file").
75
83
  */
76
84
  flags?: T;
77
85
  /**
78
86
  * Delimiters to split flag names and values.
79
87
  *
80
- * @default ['=', ':']
88
+ * @default ["=", ":"]
81
89
  */
82
90
  delimiters?: string[];
83
91
  /**
84
- * A callback function to conditionally stop parsing.
85
- * When it returns true, parsing stops and remaining arguments are preserved in `ignored`.
92
+ * A callback function to conditionally stop parsing. When it returns true,
93
+ * parsing stops and remaining arguments are preserved in `ignored`.
86
94
  */
87
95
  ignore?: IgnoreFunction;
88
96
  }
@@ -92,25 +100,38 @@ interface ObjectInputType {
92
100
  }
93
101
  /**
94
102
  * The parsed result.
103
+ *
95
104
  * @template TFlags The specific flags type inferred from ParserOptions.
96
105
  */
97
106
  interface ParsedResult<TFlags extends Record<string, any>> {
98
- /** Positional arguments or commands. */
107
+ /**
108
+ * Positional arguments or commands.
109
+ */
99
110
  parameters: string[];
100
- /** Arguments after the `--` delimiter. */
111
+ /**
112
+ * Arguments after the `--` delimiter.
113
+ */
101
114
  doubleDash: string[];
102
115
  /**
103
- * The parsed flags.
104
- * This is a strongly-typed object whose structure is inferred from the `flags` configuration in ParserOptions.
116
+ * The parsed flags. This is a strongly-typed object whose structure is
117
+ * inferred from the `flags` configuration in ParserOptions.
105
118
  */
106
119
  flags: TFlags;
107
- /** The raw command-line arguments. */
120
+ /**
121
+ * The raw command-line arguments.
122
+ */
108
123
  raw: string[];
109
- /** Unknown flags encountered during parsing. */
124
+ /**
125
+ * Unknown flags encountered during parsing.
126
+ */
110
127
  unknown: Record<string, RawInputType>;
111
- /** Arguments that were not parsed due to ignore callback. */
128
+ /**
129
+ * Arguments that were not parsed due to ignore callback.
130
+ */
112
131
  ignored: string[];
113
- /** List of required flags that were not provided. */
132
+ /**
133
+ * List of required flags that were not provided.
134
+ */
114
135
  missingRequiredFlags: string[];
115
136
  }
116
137
  type InferFlagDefault<T extends FlagDefinitionValue, Fallback> = T extends {
@@ -131,8 +152,8 @@ type _InferFlags<T extends FlagsDefinition> = { [K in keyof T]: IsTypeAny<T[K]>
131
152
  required: true;
132
153
  } ? never : undefined> : never };
133
154
  /**
134
- * An advanced utility type that infers the exact type of the `flags` object in the parsed result,
135
- * based on the provided `flags` configuration object T.
155
+ * An advanced utility type that infers the exact type of the `flags` object in
156
+ * the parsed result, based on the provided `flags` configuration object T.
136
157
  *
137
158
  * @template T The type of the flags configuration object.
138
159
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clerc/parser",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "author": "Ray <i@mk1.io> (https://github.com/so1ve)",
5
5
  "type": "module",
6
6
  "description": "Clerc parser",
@@ -27,19 +27,12 @@
27
27
  "license": "MIT",
28
28
  "sideEffects": false,
29
29
  "exports": {
30
- ".": "./dist/index.js"
31
- },
32
- "main": "./dist/index.js",
33
- "module": "./dist/index.js",
34
- "types": "dist/index.d.ts",
35
- "typesVersions": {
36
- "*": {
37
- "*": [
38
- "./dist/*",
39
- "./dist/index.d.ts"
40
- ]
41
- }
30
+ ".": "./dist/index.mjs",
31
+ "./package.json": "./package.json"
42
32
  },
33
+ "main": "./dist/index.mjs",
34
+ "module": "./dist/index.mjs",
35
+ "types": "./dist/index.d.mts",
43
36
  "files": [
44
37
  "dist"
45
38
  ],
@@ -47,7 +40,7 @@
47
40
  "access": "public"
48
41
  },
49
42
  "dependencies": {
50
- "@clerc/utils": "1.0.3"
43
+ "@clerc/utils": "1.1.0"
51
44
  },
52
45
  "devDependencies": {
53
46
  "@types/minimist": "^1.2.5",
File without changes