@oclif/core 4.5.6-autocomplete.0 → 4.6.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.
@@ -58,7 +58,8 @@ class CommandHelp extends formatter_1.HelpFormatter {
58
58
  return;
59
59
  return args.map((a) => {
60
60
  // Add ellipsis to indicate that the argument takes multiple values if strict is false
61
- const name = this.command.strict === false ? `${a.name.toUpperCase()}...` : a.name.toUpperCase();
61
+ let name = this.command.strict === false ? `${a.name.toUpperCase()}...` : a.name.toUpperCase();
62
+ name = a.required ? `${name}` : `[${name}]`;
62
63
  let description = a.description || '';
63
64
  if (a.default)
64
65
  description = `${(0, theme_1.colorize)(this.config?.theme?.flagDefaultValue, `[default: ${a.default}]`)} ${description}`;
@@ -165,8 +165,22 @@ class DocOpts {
165
165
  if (Array.isArray(flag.dependsOn)) {
166
166
  this.combineElementsToFlag(elementMap, flag.name, flag.dependsOn, ' ');
167
167
  }
168
+ let exclusive;
168
169
  if (Array.isArray(flag.exclusive)) {
169
- this.combineElementsToFlag(elementMap, flag.name, flag.exclusive, ' | ');
170
+ exclusive = new Set(flag.exclusive);
171
+ }
172
+ if (Array.isArray(flag.combinable)) {
173
+ const combinableFlags = new Set(flag.combinable);
174
+ exclusive ??= new Set();
175
+ for (const item of this.flagList) {
176
+ // each flag not in the "combinable" list, is equivalent to an "exclusive" flag
177
+ if (flag !== item && !combinableFlags.has(item.name)) {
178
+ exclusive.add(item.name);
179
+ }
180
+ }
181
+ }
182
+ if (exclusive !== undefined && exclusive.size > 0) {
183
+ this.combineElementsToFlag(elementMap, flag.name, [...exclusive], ' | ');
170
184
  }
171
185
  }
172
186
  // Since combineElementsToFlag deletes the references in this.flags when it combines
@@ -7,7 +7,7 @@ export type { HelpOptions } from './help';
7
7
  export type { Hook, Hooks } from './hooks';
8
8
  export type { Logger } from './logger';
9
9
  export type { Manifest } from './manifest';
10
- export type { Arg, ArgDefinition, ArgInput, BooleanFlag, Completion, CompletionContext, CustomOptions, Deprecation, Flag, FlagDefinition, FlagInput, Input, OptionFlag, OutputArgs, OutputFlags, ParserOutput, } from './parser';
10
+ export type { Arg, ArgDefinition, ArgInput, BooleanFlag, CustomOptions, Deprecation, Flag, FlagDefinition, FlagInput, Input, OptionFlag, OutputArgs, OutputFlags, ParserOutput, } from './parser';
11
11
  export type { LinkedPlugin, OclifConfiguration, PJSON, S3, S3Templates, UserPJSON, UserPlugin } from './pjson';
12
12
  export type { Options, Plugin, PluginOptions } from './plugin';
13
13
  export type { S3Manifest } from './s3-manifest';
@@ -1,6 +1,5 @@
1
1
  import { Command } from '../command';
2
2
  import { AlphabetLowercase, AlphabetUppercase } from './alphabet';
3
- import { Config } from './config';
4
3
  export type FlagOutput = {
5
4
  [name: string]: any;
6
5
  };
@@ -88,7 +87,7 @@ export type FlagRelationship = string | {
88
87
  when: (flags: Record<string, unknown>) => Promise<boolean>;
89
88
  };
90
89
  export type Relationship = {
91
- type: 'all' | 'some' | 'none';
90
+ type: 'all' | 'some' | 'none' | 'only';
92
91
  flags: FlagRelationship[];
93
92
  };
94
93
  export type Deprecation = {
@@ -139,6 +138,10 @@ export type FlagProps = {
139
138
  * List of flags that cannot be used with this flag.
140
139
  */
141
140
  exclusive?: string[];
141
+ /**
142
+ * List of the only flags that can be used with this flag.
143
+ */
144
+ combinable?: string[];
142
145
  /**
143
146
  * Exactly one of these flags must be provided.
144
147
  */
@@ -224,21 +227,6 @@ export type OptionFlagProps = FlagProps & {
224
227
  * Should only be used on one flag at a time.
225
228
  */
226
229
  allowStdin?: boolean | 'only';
227
- /**
228
- * Optional dynamic completion configuration.
229
- * Provides intelligent autocomplete suggestions for flag values based on context.
230
- * Requires autocomplete plugin to be installed.
231
- *
232
- * @example
233
- * ```typescript
234
- * completion: {
235
- * options: async (ctx) => {
236
- * return ['option1', 'option2', 'option3']
237
- * }
238
- * }
239
- * ```
240
- */
241
- completion?: Completion;
242
230
  };
243
231
  export type FlagParserContext = Command & {
244
232
  token: FlagToken;
@@ -463,58 +451,6 @@ export type ParserInput = {
463
451
  context: ParserContext | undefined;
464
452
  '--'?: boolean | undefined;
465
453
  };
466
- /**
467
- * Context provided to flag completion functions
468
- */
469
- export type CompletionContext = {
470
- /**
471
- * Parsed arguments from the current command line
472
- */
473
- args?: {
474
- [name: string]: string;
475
- };
476
- /**
477
- * Array of raw arguments
478
- */
479
- argv?: string[];
480
- /**
481
- * oclif configuration object
482
- */
483
- config: Config;
484
- /**
485
- * Parsed flags from the current command line
486
- */
487
- flags?: {
488
- [name: string]: string;
489
- };
490
- };
491
- /**
492
- * Completion configuration for a flag
493
- */
494
- export type Completion = {
495
- /**
496
- * Function that returns completion options based on context
497
- *
498
- * @param ctx - Context containing parsed args, flags, and config
499
- * @returns Promise resolving to array of completion strings
500
- *
501
- * @example
502
- * ```typescript
503
- * static flags = {
504
- * 'target-org': Flags.string({
505
- * description: 'Target org',
506
- * completion: {
507
- * options: async (ctx) => {
508
- * const orgs = await getAuthenticatedOrgs()
509
- * return orgs.map(o => o.alias)
510
- * }
511
- * }
512
- * })
513
- * }
514
- * ```
515
- */
516
- options(ctx: CompletionContext): Promise<string[]>;
517
- };
518
454
  export type ParserContext = Command & {
519
455
  token?: FlagToken | ArgToken | undefined;
520
456
  };
@@ -57,6 +57,7 @@ async function validate(parse) {
57
57
  ...(flag.relationships ? validateRelationships(name, flag) : []),
58
58
  ...(flag.dependsOn ? [validateDependsOn(name, flag.dependsOn)] : []),
59
59
  ...(flag.exclusive ? [validateExclusive(name, flag.exclusive)] : []),
60
+ ...(flag.combinable ? [validateCombinable(name, flag.combinable)] : []),
60
61
  ...(flag.exactlyOne ? [validateExactlyOne(name, flag.exactlyOne)] : []),
61
62
  ];
62
63
  }
@@ -143,6 +144,29 @@ async function validate(parse) {
143
144
  }
144
145
  return { ...base, status: 'success' };
145
146
  }
147
+ async function validateCombinable(name, flags) {
148
+ const base = { name, validationFn: 'validateCombinable' };
149
+ const combinableFlags = new Set(flags.map((flag) => (typeof flag === 'string' ? flag : flag.name)));
150
+ const resolved = await resolveFlags(flags);
151
+ for (const flag of Object.keys(parse.output.flags)) {
152
+ // do not enforce exclusivity for flags that were defaulted
153
+ if (parse.output.metadata.flags && parse.output.metadata.flags[flag]?.setFromDefault)
154
+ continue;
155
+ if (parse.output.metadata.flags && parse.output.metadata.flags[name]?.setFromDefault)
156
+ continue;
157
+ if (flag !== name && parse.output.flags[flag] !== undefined && !combinableFlags.has(flag)) {
158
+ const formattedFlags = Object.keys(resolved)
159
+ .map((f) => `--${f}`)
160
+ .join(', ');
161
+ return {
162
+ ...base,
163
+ reason: `Only the following can be provided when using --${name}: ${formattedFlags}`,
164
+ status: 'failed',
165
+ };
166
+ }
167
+ }
168
+ return { ...base, status: 'success' };
169
+ }
146
170
  async function validateExactlyOne(name, flags) {
147
171
  const base = { name, validationFn: 'validateExactlyOne' };
148
172
  const resolved = await resolveFlags(flags);
@@ -195,6 +219,9 @@ async function validate(parse) {
195
219
  case 'none': {
196
220
  return validateExclusive(name, relationship.flags);
197
221
  }
222
+ case 'only': {
223
+ return validateCombinable(name, relationship.flags);
224
+ }
198
225
  case 'some': {
199
226
  return validateSome(name, relationship.flags);
200
227
  }
@@ -20,6 +20,7 @@ async function cacheFlags(cmdFlags, respectNoCacheDefault) {
20
20
  aliases: flag.aliases,
21
21
  char: flag.char,
22
22
  charAliases: flag.charAliases,
23
+ combinable: flag.combinable,
23
24
  dependsOn: flag.dependsOn,
24
25
  deprecateAliases: flag.deprecateAliases,
25
26
  deprecated: flag.deprecated,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oclif/core",
3
3
  "description": "base library for oclif CLIs",
4
- "version": "4.5.6-autocomplete.0",
4
+ "version": "4.6.0",
5
5
  "author": "Salesforce",
6
6
  "bugs": "https://github.com/oclif/core/issues",
7
7
  "dependencies": {