massarg 2.0.0-pre.1 → 2.0.0-pre.11

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/option.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { z } from 'zod';
2
- export declare const OptionConfig: <T extends z.ZodType<any, z.ZodTypeDef, any>>(type: T) => z.ZodObject<{
2
+ import { ArgsObject } from './command';
3
+ export declare const OptionConfig: <OptionType, Args extends ArgsObject = ArgsObject>(type: z.ZodType<OptionType, z.ZodTypeDef, OptionType>) => z.ZodObject<{
3
4
  /** Name of the option */
4
5
  name: z.ZodString;
5
6
  /** Description of the option, displayed in the help output */
@@ -12,7 +13,7 @@ export declare const OptionConfig: <T extends z.ZodType<any, z.ZodTypeDef, any>>
12
13
  * Parse the value of the option. You can return any type here, or throw an error if the value
13
14
  * is invalid.
14
15
  */
15
- parse: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodString], z.ZodUnknown>, T>>;
16
+ parse: z.ZodOptional<z.ZodType<Parser<Args, OptionType>, z.ZodTypeDef, Parser<Args, OptionType>>>;
16
17
  /**
17
18
  * Whether the option is an array.
18
19
  *
@@ -37,107 +38,153 @@ export declare const OptionConfig: <T extends z.ZodType<any, z.ZodTypeDef, any>>
37
38
  /** Specify a custom name for the output, which will be used when parsing the args. */
38
39
  outputName: z.ZodOptional<z.ZodString>;
39
40
  }, "strip", z.ZodTypeAny, {
40
- description: string;
41
41
  name: string;
42
+ description: string;
42
43
  aliases: string[];
43
44
  defaultValue?: any;
44
- parse?: ((args_0: string, ...args_1: unknown[]) => T["_output"]) | undefined;
45
+ parse?: Parser<Args, OptionType> | undefined;
45
46
  array?: boolean | undefined;
46
47
  required?: boolean | undefined;
47
48
  isDefault?: boolean | undefined;
48
49
  hidden?: boolean | undefined;
49
50
  outputName?: string | undefined;
50
51
  }, {
51
- description: string;
52
52
  name: string;
53
+ description: string;
53
54
  aliases: string[];
54
55
  defaultValue?: any;
55
- parse?: ((args_0: string, ...args_1: unknown[]) => T["_input"]) | undefined;
56
+ parse?: Parser<Args, OptionType> | undefined;
56
57
  array?: boolean | undefined;
57
58
  required?: boolean | undefined;
58
59
  isDefault?: boolean | undefined;
59
60
  hidden?: boolean | undefined;
60
61
  outputName?: string | undefined;
61
62
  }>;
62
- export type OptionConfig<T = unknown> = z.infer<ReturnType<typeof OptionConfig<z.ZodType<T>>>>;
63
- export declare const TypedOptionConfig: <T extends z.ZodType<any, z.ZodTypeDef, any>>(type: T) => z.ZodObject<{
64
- array: z.ZodOptional<z.ZodBoolean>;
63
+ export type OptionConfig<T = unknown, Args extends ArgsObject = ArgsObject> = z.infer<ReturnType<typeof OptionConfig<T, Args>>>;
64
+ /**
65
+ * Configuration for a flag (boolean argument) that can be passed to a command.
66
+ */
67
+ export declare const FlagConfig: z.ZodObject<{
68
+ name: z.ZodString;
65
69
  description: z.ZodString;
70
+ defaultValue: z.ZodOptional<z.ZodAny>;
71
+ aliases: z.ZodArray<z.ZodString, "many">;
72
+ array: z.ZodOptional<z.ZodBoolean>;
73
+ required: z.ZodOptional<z.ZodBoolean>;
74
+ hidden: z.ZodOptional<z.ZodBoolean>;
75
+ outputName: z.ZodOptional<z.ZodString>;
76
+ negatable: z.ZodOptional<z.ZodBoolean>;
77
+ negationName: z.ZodOptional<z.ZodString>;
78
+ negationAliases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
79
+ }, "strip", z.ZodTypeAny, {
80
+ name: string;
81
+ description: string;
82
+ aliases: string[];
83
+ defaultValue?: any;
84
+ array?: boolean | undefined;
85
+ required?: boolean | undefined;
86
+ hidden?: boolean | undefined;
87
+ outputName?: string | undefined;
88
+ negatable?: boolean | undefined;
89
+ negationName?: string | undefined;
90
+ negationAliases?: string[] | undefined;
91
+ }, {
92
+ name: string;
93
+ description: string;
94
+ aliases: string[];
95
+ defaultValue?: any;
96
+ array?: boolean | undefined;
97
+ required?: boolean | undefined;
98
+ hidden?: boolean | undefined;
99
+ outputName?: string | undefined;
100
+ negatable?: boolean | undefined;
101
+ negationName?: string | undefined;
102
+ negationAliases?: string[] | undefined;
103
+ }>;
104
+ export type FlagConfig = z.infer<typeof FlagConfig>;
105
+ /**
106
+ * A function that parses an option value.
107
+ */
108
+ export type Parser<Args extends ArgsObject = ArgsObject, OptionType extends any = any> = (x: string, y: Args) => OptionType;
109
+ /** {@link OptionConfig} with a specified value type */
110
+ export declare const TypedOptionConfig: <OptionType, Args extends ArgsObject = ArgsObject>(type: z.ZodType<OptionType, z.ZodTypeDef, OptionType>) => z.ZodObject<{
66
111
  name: z.ZodString;
112
+ description: z.ZodString;
67
113
  defaultValue: z.ZodOptional<z.ZodAny>;
68
114
  aliases: z.ZodArray<z.ZodString, "many">;
69
- parse: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodString], z.ZodUnknown>, T>>;
115
+ array: z.ZodOptional<z.ZodBoolean>;
70
116
  required: z.ZodOptional<z.ZodBoolean>;
71
117
  isDefault: z.ZodOptional<z.ZodBoolean>;
72
118
  hidden: z.ZodOptional<z.ZodBoolean>;
73
119
  outputName: z.ZodOptional<z.ZodString>;
120
+ parse: z.ZodOptional<z.ZodType<Parser<Args, OptionType>, z.ZodTypeDef, Parser<Args, OptionType>>>;
74
121
  type: z.ZodOptional<z.ZodEnum<["number"]>>;
75
122
  }, "strip", z.ZodTypeAny, {
76
- description: string;
77
123
  name: string;
124
+ description: string;
78
125
  aliases: string[];
79
- array?: boolean | undefined;
80
126
  defaultValue?: any;
81
- parse?: ((args_0: string, ...args_1: unknown[]) => T["_output"]) | undefined;
127
+ array?: boolean | undefined;
82
128
  required?: boolean | undefined;
83
129
  isDefault?: boolean | undefined;
84
130
  hidden?: boolean | undefined;
85
131
  outputName?: string | undefined;
132
+ parse?: Parser<Args, OptionType> | undefined;
86
133
  type?: "number" | undefined;
87
134
  }, {
88
- description: string;
89
135
  name: string;
136
+ description: string;
90
137
  aliases: string[];
91
- array?: boolean | undefined;
92
138
  defaultValue?: any;
93
- parse?: ((args_0: string, ...args_1: unknown[]) => T["_input"]) | undefined;
139
+ array?: boolean | undefined;
94
140
  required?: boolean | undefined;
95
141
  isDefault?: boolean | undefined;
96
142
  hidden?: boolean | undefined;
97
143
  outputName?: string | undefined;
144
+ parse?: Parser<Args, OptionType> | undefined;
98
145
  type?: "number" | undefined;
99
146
  }>;
100
- export type TypedOptionConfig<T = unknown> = z.infer<ReturnType<typeof TypedOptionConfig<z.ZodType<T>>>>;
147
+ export type TypedOptionConfig<T, A extends ArgsObject = ArgsObject> = z.infer<ReturnType<typeof TypedOptionConfig<T, A>>>;
101
148
  /**
102
149
  * @see OptionConfig
103
150
  * @see ArrayOptionConfig
104
151
  */
105
- export declare const ArrayOptionConfig: <T extends z.ZodType<any, z.ZodTypeDef, any>>(type: T) => z.ZodObject<{
152
+ export declare const ArrayOptionConfig: <T, A extends ArgsObject = ArgsObject>(type: z.ZodType<T, z.ZodTypeDef, T>) => z.ZodObject<{
106
153
  type: z.ZodOptional<z.ZodEnum<["number"]>>;
107
- array: z.ZodOptional<z.ZodBoolean>;
108
- description: z.ZodString;
109
154
  name: z.ZodString;
155
+ description: z.ZodString;
110
156
  aliases: z.ZodArray<z.ZodString, "many">;
111
- parse: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodString], z.ZodUnknown>, z.ZodArray<T, "many">>>;
157
+ array: z.ZodOptional<z.ZodBoolean>;
112
158
  required: z.ZodOptional<z.ZodBoolean>;
113
159
  isDefault: z.ZodOptional<z.ZodBoolean>;
114
160
  hidden: z.ZodOptional<z.ZodBoolean>;
115
161
  outputName: z.ZodOptional<z.ZodString>;
116
- defaultValue: z.ZodOptional<z.ZodArray<T, "many">>;
162
+ parse: z.ZodOptional<z.ZodType<Parser<A, T[]>, z.ZodTypeDef, Parser<A, T[]>>>;
163
+ defaultValue: z.ZodOptional<z.ZodArray<z.ZodType<T, z.ZodTypeDef, T>, "many">>;
117
164
  }, "strip", z.ZodTypeAny, {
118
- description: string;
119
165
  name: string;
166
+ description: string;
120
167
  aliases: string[];
121
168
  type?: "number" | undefined;
122
169
  array?: boolean | undefined;
123
- parse?: ((args_0: string, ...args_1: unknown[]) => T["_output"][]) | undefined;
124
170
  required?: boolean | undefined;
125
171
  isDefault?: boolean | undefined;
126
172
  hidden?: boolean | undefined;
127
173
  outputName?: string | undefined;
128
- defaultValue?: T["_output"][] | undefined;
174
+ parse?: Parser<A, T[]> | undefined;
175
+ defaultValue?: T[] | undefined;
129
176
  }, {
130
- description: string;
131
177
  name: string;
178
+ description: string;
132
179
  aliases: string[];
133
180
  type?: "number" | undefined;
134
181
  array?: boolean | undefined;
135
- parse?: ((args_0: string, ...args_1: unknown[]) => T["_input"][]) | undefined;
136
182
  required?: boolean | undefined;
137
183
  isDefault?: boolean | undefined;
138
184
  hidden?: boolean | undefined;
139
185
  outputName?: string | undefined;
140
- defaultValue?: T["_input"][] | undefined;
186
+ parse?: Parser<A, T[]> | undefined;
187
+ defaultValue?: T[] | undefined;
141
188
  }>;
142
189
  /**
143
190
  * An option that can be passed to a command.
@@ -145,6 +192,25 @@ export declare const ArrayOptionConfig: <T extends z.ZodType<any, z.ZodTypeDef,
145
192
  * This type represents an array option, which can be specified multiple times.
146
193
  */
147
194
  export type ArrayOptionConfig<T = unknown> = z.infer<ReturnType<typeof ArrayOptionConfig<z.ZodType<T>>>>;
195
+ /** The default prefixes for options */
196
+ export declare const DEFAULT_OPT_FULL_PREFIX = "--";
197
+ /** The default prefix for option aliases */
198
+ export declare const DEFAULT_OPT_SHORT_PREFIX = "-";
199
+ export type Prefixes = {
200
+ normalPrefix: string;
201
+ aliasPrefix: string;
202
+ };
203
+ export type Names = {
204
+ name: string;
205
+ aliases: string[];
206
+ };
207
+ /** Names with prefixes built-in */
208
+ export type QualifiedNames = {
209
+ name: string;
210
+ aliases: string[];
211
+ negationName: string;
212
+ negationAliases: string[];
213
+ };
148
214
  /** @internal */
149
215
  export type ArgvValue<T> = {
150
216
  argv: string[];
@@ -173,22 +239,43 @@ export type ArgvValue<T> = {
173
239
  * })
174
240
  * ```
175
241
  */
176
- export declare class MassargOption<T = unknown> {
242
+ export declare class MassargOption<OptionType extends any = unknown, Args extends ArgsObject = ArgsObject> implements OptionConfig<OptionType, Args> {
177
243
  name: string;
178
244
  description: string;
179
- defaultValue?: T;
245
+ defaultValue?: OptionType;
180
246
  aliases: string[];
181
- parse: (value: string) => T;
247
+ parse: Parser<Args, OptionType>;
248
+ /**
249
+ * Whether this option can be used multiple times. Any passed values will end up in an array
250
+ * instead of each usage overwriting the existing value.
251
+ */
182
252
  isArray: boolean;
253
+ /** Whether this option is required. Failing to specify this option will throw an error. */
254
+ isRequired: boolean;
183
255
  isDefault: boolean;
184
256
  outputName?: string;
185
- constructor(options: OptionConfig<T>);
186
- static fromTypedConfig<T = unknown>(config: TypedOptionConfig<T>): MassargOption<T>;
187
- _parseDetails(argv: string[]): ArgvValue<T>;
257
+ constructor(options: OptionConfig<OptionType, Args>);
258
+ /**
259
+ * Create a typed option from a configuration. Currently supports `number` options which
260
+ * are automatically transformed from `string` to `number`.
261
+ */
262
+ static fromTypedConfig<T = unknown, A extends ArgsObject = ArgsObject>(config: TypedOptionConfig<T, A>): MassargOption<T>;
263
+ /**
264
+ * Returns the key which this option outputs to in the final object.
265
+ *
266
+ * @default The camelCase version of this option's name.
267
+ *
268
+ * Can be overridden with {@link outputName}.
269
+ */
270
+ getOutputName(): string;
271
+ /** @internal */
272
+ parseDetails(argv: string[], options: ArgsObject, prefixes: Prefixes): ArgvValue<OptionType>;
273
+ /** Get the help string for this option */
188
274
  helpString(): string;
189
- _match(arg: string): boolean;
190
- _isOption(arg: string): boolean;
191
- static getName(arg: string): string;
275
+ /** Returns true if the flag (including any prefixes) matches the name or aliases */
276
+ isMatch(arg: string, prefixes: Prefixes): boolean;
277
+ /** Return the finalized names that will cause this option to match. */
278
+ qualifiedNames(prefixes: Prefixes): QualifiedNames;
192
279
  }
193
280
  /**
194
281
  * An option that can be passed to a command.
@@ -208,18 +295,19 @@ export declare class MassargOption<T = unknown> {
208
295
  */
209
296
  export declare class MassargNumber extends MassargOption<number> {
210
297
  constructor(options: Omit<OptionConfig<number>, 'parse'>);
211
- _parseDetails(argv: string[]): ArgvValue<number>;
298
+ parseDetails(argv: string[], options: ArgsObject, prefixes: Prefixes): ArgvValue<number>;
212
299
  }
213
300
  /**
214
- * An option that can be passed to a command.
301
+ * A boolean option that can be passed to a command.
215
302
  *
216
303
  * A flag is an option that is either present or not. It can be used to toggle
217
304
  * a boolean value, or to indicate that a command should be run in a different
218
305
  * mode.
219
306
  *
220
- * A flag can be negated by prefixing it with `no-`. For example, `--no-verbose`,
221
- * or by prefixing the alias with `^` instead of `-`. This is configurable via the command's
222
- * configuration.
307
+ * A flag can be negated by using `negatable: true`. By default, the negated name is the same
308
+ * as the option name, prefixed by `no-`, and each of the aliases will be uppercased.
309
+ * For example, `--verbose` and `--no-verbose`, or `-v` and `-V`.
310
+ * This behavior can be overridden by the `negatedName` and `negatedAliases` options.
223
311
  *
224
312
  * @example
225
313
  * ```ts
@@ -232,9 +320,17 @@ export declare class MassargNumber extends MassargOption<number> {
232
320
  * ```
233
321
  */
234
322
  export declare class MassargFlag extends MassargOption<boolean> {
235
- constructor(options: Omit<OptionConfig<boolean>, 'parse'>);
236
- _parseDetails(argv: string[]): ArgvValue<boolean>;
323
+ /** Whether this flag may be negated using `negationName` or `negationAliases`. */
324
+ negatable: boolean;
325
+ /** The negation name of this flag, which can be used with the full option notation. */
326
+ negationName: string;
327
+ /** The negation aliases of this flag, which can be used with the shorthand option notation. */
328
+ negationAliases: string[];
329
+ constructor(options: FlagConfig);
330
+ parseDetails(argv: string[], _options: ArgsObject, prefixes: Prefixes): ArgvValue<boolean>;
331
+ qualifiedNames(prefixes: Prefixes): QualifiedNames;
237
332
  }
333
+ /** A flag that can be passed to a command to show the help message. */
238
334
  export declare class MassargHelpFlag extends MassargFlag {
239
335
  constructor(config?: Partial<Omit<OptionConfig<boolean>, 'parse'>>);
240
336
  }
package/option.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"option.d.ts","sourceRoot":"","sources":["../src/option.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"option.d.ts","sourceRoot":"","sources":["../src/option.ts"],"names":[],"mappings":"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"}
package/option.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MassargHelpFlag = exports.MassargFlag = exports.MassargNumber = exports.MassargOption = exports.ArrayOptionConfig = exports.TypedOptionConfig = exports.OptionConfig = void 0;
3
+ exports.MassargHelpFlag = exports.MassargFlag = exports.MassargNumber = exports.MassargOption = exports.DEFAULT_OPT_SHORT_PREFIX = exports.DEFAULT_OPT_FULL_PREFIX = exports.ArrayOptionConfig = exports.TypedOptionConfig = exports.FlagConfig = exports.OptionConfig = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const error_1 = require("./error");
6
6
  const utils_1 = require("./utils");
@@ -17,7 +17,7 @@ const OptionConfig = (type) => zod_1.z.object({
17
17
  * Parse the value of the option. You can return any type here, or throw an error if the value
18
18
  * is invalid.
19
19
  */
20
- parse: zod_1.z.function().args(zod_1.z.string()).returns(type).optional(),
20
+ parse: zod_1.z.function().args(zod_1.z.string(), zod_1.z.any()).returns(type).optional(),
21
21
  /**
22
22
  * Whether the option is an array.
23
23
  *
@@ -43,6 +43,32 @@ const OptionConfig = (type) => zod_1.z.object({
43
43
  outputName: zod_1.z.string().optional(),
44
44
  });
45
45
  exports.OptionConfig = OptionConfig;
46
+ /**
47
+ * Configuration for a flag (boolean argument) that can be passed to a command.
48
+ */
49
+ exports.FlagConfig = (0, exports.OptionConfig)(zod_1.z.any())
50
+ .omit({ parse: true, isDefault: true })
51
+ .merge(zod_1.z.object({
52
+ /** Whether the flag can be negated, e.g. `--no-verbose` */
53
+ negatable: zod_1.z.boolean().optional(),
54
+ /**
55
+ * Negation name of the option, which can be used with the full option notation.
56
+ *
57
+ * Defaults to `no-{name}` of your option's name, e.g. `verbose` becomes `--no-verbose`.
58
+ *
59
+ * To use this, you must set `negatable: true` in the option's configuration.
60
+ */
61
+ negationName: zod_1.z.string().optional(),
62
+ /**
63
+ * Negation aliases for the option, which can be used with the shorthand option notation.
64
+ *
65
+ * Defaults to uppercase of each of the aliases provided, e.g. `q` becomes `-Q`.
66
+ *
67
+ * To use this, you must set `negatable: true` in the option's configuration.
68
+ */
69
+ negationAliases: zod_1.z.string().array().optional(),
70
+ }));
71
+ /** {@link OptionConfig} with a specified value type */
46
72
  const TypedOptionConfig = (type) => (0, exports.OptionConfig)(type).merge(zod_1.z.object({
47
73
  type: zod_1.z.enum(['number']).optional(),
48
74
  }));
@@ -57,11 +83,10 @@ zod_1.z.object({
57
83
  defaultValue: zod_1.z.array(type).optional(),
58
84
  }));
59
85
  exports.ArrayOptionConfig = ArrayOptionConfig;
60
- // TODO turn to options
61
- const OPT_FULL_PREFIX = '--';
62
- const OPT_SHORT_PREFIX = '-';
63
- const NEGATE_FULL_PREFIX = 'no-';
64
- const NEGATE_SHORT_PREFIX = '^';
86
+ /** The default prefixes for options */
87
+ exports.DEFAULT_OPT_FULL_PREFIX = '--';
88
+ /** The default prefix for option aliases */
89
+ exports.DEFAULT_OPT_SHORT_PREFIX = '-';
65
90
  /**
66
91
  * An option that can be passed to a command.
67
92
  *
@@ -94,8 +119,13 @@ class MassargOption {
94
119
  this.parse = options.parse ?? ((x) => x);
95
120
  this.isArray = options.array ?? false;
96
121
  this.isDefault = options.isDefault ?? false;
122
+ this.isRequired = options.required ?? false;
97
123
  this.outputName = options.outputName;
98
124
  }
125
+ /**
126
+ * Create a typed option from a configuration. Currently supports `number` options which
127
+ * are automatically transformed from `string` to `number`.
128
+ */
99
129
  static fromTypedConfig(config) {
100
130
  switch (config.type) {
101
131
  case 'number':
@@ -103,11 +133,21 @@ class MassargOption {
103
133
  }
104
134
  return new MassargOption(config);
105
135
  }
106
- _parseDetails(argv) {
107
- // TODO: support --option=value
136
+ /**
137
+ * Returns the key which this option outputs to in the final object.
138
+ *
139
+ * @default The camelCase version of this option's name.
140
+ *
141
+ * Can be overridden with {@link outputName}.
142
+ */
143
+ getOutputName() {
144
+ return this.outputName || (0, utils_1.toCamelCase)(this.name);
145
+ }
146
+ /** @internal */
147
+ parseDetails(argv, options, prefixes) {
108
148
  let input = '';
109
149
  try {
110
- if (!this._match(argv[0])) {
150
+ if (!this.isMatch(argv[0], prefixes)) {
111
151
  throw new error_1.ParseError({
112
152
  path: [this.name],
113
153
  code: 'invalid_option',
@@ -117,8 +157,8 @@ class MassargOption {
117
157
  }
118
158
  argv.shift();
119
159
  input = argv.shift();
120
- const value = this.parse(input);
121
- return { key: this.outputName || (0, utils_1.toCamelCase)(this.name), value, argv };
160
+ const value = this.parse(input, options);
161
+ return { key: this.getOutputName(), value, argv };
122
162
  }
123
163
  catch (e) {
124
164
  if ((0, error_1.isZodError)(e)) {
@@ -132,54 +172,27 @@ class MassargOption {
132
172
  throw e;
133
173
  }
134
174
  }
175
+ /** Get the help string for this option */
135
176
  helpString() {
136
177
  const aliases = this.aliases.length ? `|${this.aliases.join('|-')}` : '';
137
178
  return `--${this.name}${aliases} ${this.description}`;
138
179
  }
139
- _match(arg) {
140
- if (!arg)
141
- return false;
142
- // full prefix
143
- if (arg.startsWith(OPT_FULL_PREFIX)) {
144
- // negate full prefix
145
- if (arg.startsWith(`--${NEGATE_FULL_PREFIX}`)) {
146
- return this.name === arg.slice(`--${NEGATE_FULL_PREFIX}`.length);
147
- }
148
- return this.name === arg.slice(OPT_FULL_PREFIX.length);
149
- }
150
- // short prefix
151
- if (arg.startsWith(OPT_SHORT_PREFIX) || arg.startsWith(NEGATE_SHORT_PREFIX)) {
152
- return this.aliases.includes(arg.slice(OPT_SHORT_PREFIX.length));
153
- }
154
- // negate short prefix
155
- if (arg.startsWith(NEGATE_SHORT_PREFIX)) {
156
- return this.aliases.includes(arg.slice(NEGATE_SHORT_PREFIX.length));
157
- }
158
- // no prefix
159
- return false;
160
- }
161
- _isOption(arg) {
162
- return (arg.startsWith(OPT_FULL_PREFIX) ||
163
- arg.startsWith(OPT_SHORT_PREFIX) ||
164
- arg.startsWith(NEGATE_SHORT_PREFIX));
180
+ /** Returns true if the flag (including any prefixes) matches the name or aliases */
181
+ isMatch(arg, prefixes) {
182
+ const qualifiedNames = this.qualifiedNames(prefixes);
183
+ return (arg === qualifiedNames.name ||
184
+ arg === qualifiedNames.negationName ||
185
+ qualifiedNames.aliases.includes(arg) ||
186
+ qualifiedNames.negationAliases.includes(arg));
165
187
  }
166
- static getName(arg) {
167
- if (arg.startsWith(OPT_FULL_PREFIX)) {
168
- // negate full prefix
169
- if (arg.startsWith(`--${NEGATE_FULL_PREFIX}`)) {
170
- return arg.slice(`--${NEGATE_FULL_PREFIX}`.length);
171
- }
172
- return arg.slice(OPT_FULL_PREFIX.length);
173
- }
174
- // short prefix
175
- if (arg.startsWith(OPT_SHORT_PREFIX) || arg.startsWith(NEGATE_SHORT_PREFIX)) {
176
- return arg.slice(OPT_SHORT_PREFIX.length);
177
- }
178
- // negate short prefix
179
- if (arg.startsWith(NEGATE_SHORT_PREFIX)) {
180
- return arg.slice(NEGATE_SHORT_PREFIX.length);
181
- }
182
- return '<blank>';
188
+ /** Return the finalized names that will cause this option to match. */
189
+ qualifiedNames(prefixes) {
190
+ return {
191
+ name: prefixes.normalPrefix + this.name,
192
+ aliases: this.aliases.map((a) => prefixes.aliasPrefix + a),
193
+ negationName: '',
194
+ negationAliases: [],
195
+ };
183
196
  }
184
197
  }
185
198
  exports.MassargOption = MassargOption;
@@ -206,9 +219,9 @@ class MassargNumber extends MassargOption {
206
219
  parse: (value) => Number(value),
207
220
  });
208
221
  }
209
- _parseDetails(argv) {
222
+ parseDetails(argv, options, prefixes) {
210
223
  try {
211
- const { argv: _argv, value } = super._parseDetails(argv);
224
+ const { argv: _argv, value } = super.parseDetails(argv, options, prefixes);
212
225
  if (isNaN(value)) {
213
226
  throw new error_1.ParseError({
214
227
  path: [this.name],
@@ -234,15 +247,16 @@ class MassargNumber extends MassargOption {
234
247
  }
235
248
  exports.MassargNumber = MassargNumber;
236
249
  /**
237
- * An option that can be passed to a command.
250
+ * A boolean option that can be passed to a command.
238
251
  *
239
252
  * A flag is an option that is either present or not. It can be used to toggle
240
253
  * a boolean value, or to indicate that a command should be run in a different
241
254
  * mode.
242
255
  *
243
- * A flag can be negated by prefixing it with `no-`. For example, `--no-verbose`,
244
- * or by prefixing the alias with `^` instead of `-`. This is configurable via the command's
245
- * configuration.
256
+ * A flag can be negated by using `negatable: true`. By default, the negated name is the same
257
+ * as the option name, prefixed by `no-`, and each of the aliases will be uppercased.
258
+ * For example, `--verbose` and `--no-verbose`, or `-v` and `-V`.
259
+ * This behavior can be overridden by the `negatedName` and `negatedAliases` options.
246
260
  *
247
261
  * @example
248
262
  * ```ts
@@ -260,11 +274,24 @@ class MassargFlag extends MassargOption {
260
274
  ...options,
261
275
  parse: () => true,
262
276
  });
277
+ this.negatable = options.negatable ?? false;
278
+ this.negationName = options.negationName ?? `no-${options.name}`;
279
+ this.negationAliases = options.negationAliases ?? this.aliases.map((a) => a.toUpperCase());
263
280
  }
264
- _parseDetails(argv) {
281
+ parseDetails(argv, _options, prefixes) {
265
282
  try {
266
- const isNegation = argv[0]?.startsWith(NEGATE_SHORT_PREFIX) || argv[0]?.startsWith(NEGATE_FULL_PREFIX);
267
- if (!this._match(argv[0])) {
283
+ const qualifiedNames = this.qualifiedNames(prefixes);
284
+ const isNegation = (qualifiedNames.negationName && argv[0] === qualifiedNames.negationName) ||
285
+ (qualifiedNames.negationAliases.length && qualifiedNames.negationAliases.includes(argv[0]));
286
+ if (!this.negatable && isNegation) {
287
+ throw new error_1.ParseError({
288
+ path: [this.name],
289
+ code: 'invalid_option',
290
+ message: `Option ${this.name} cannot be negated`,
291
+ received: JSON.stringify(argv[0]),
292
+ });
293
+ }
294
+ if (!this.isMatch(argv[0], prefixes)) {
268
295
  throw new error_1.ParseError({
269
296
  path: [this.name],
270
297
  code: 'invalid_option',
@@ -274,9 +301,9 @@ class MassargFlag extends MassargOption {
274
301
  }
275
302
  argv.shift();
276
303
  if (isNegation) {
277
- return { key: this.name, value: false, argv };
304
+ return { key: this.getOutputName(), value: false, argv };
278
305
  }
279
- return { key: this.name, value: true, argv };
306
+ return { key: this.getOutputName(), value: true, argv };
280
307
  }
281
308
  catch (e) {
282
309
  if ((0, error_1.isZodError)(e)) {
@@ -289,8 +316,16 @@ class MassargFlag extends MassargOption {
289
316
  throw e;
290
317
  }
291
318
  }
319
+ qualifiedNames(prefixes) {
320
+ return {
321
+ ...super.qualifiedNames(prefixes),
322
+ negationName: prefixes.normalPrefix + this.negationName,
323
+ negationAliases: this.negationAliases.map((a) => prefixes.aliasPrefix + a),
324
+ };
325
+ }
292
326
  }
293
327
  exports.MassargFlag = MassargFlag;
328
+ /** A flag that can be passed to a command to show the help message. */
294
329
  class MassargHelpFlag extends MassargFlag {
295
330
  constructor(config = {}) {
296
331
  super({