@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.
- package/lib/help/command.js +2 -1
- package/lib/help/docopts.js +15 -1
- package/lib/interfaces/index.d.ts +1 -1
- package/lib/interfaces/parser.d.ts +5 -69
- package/lib/parser/validate.js +27 -0
- package/lib/util/cache-command.js +1 -0
- package/package.json +1 -1
package/lib/help/command.js
CHANGED
|
@@ -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
|
-
|
|
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}`;
|
package/lib/help/docopts.js
CHANGED
|
@@ -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
|
-
|
|
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,
|
|
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
|
};
|
package/lib/parser/validate.js
CHANGED
|
@@ -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,
|