Skip to content

Commit a3b25f6

Browse files
committed
fix(@angular/cli): add choices to command line parser when type is array and has an enum
This commit enhances the command-line parser in `@angular/cli` by adding support for displaying available choices when a command option is of type `array` and has an `enum`. (cherry picked from commit 04094e8)
1 parent c43504d commit a3b25f6

File tree

2 files changed

+41
-13
lines changed

2 files changed

+41
-13
lines changed

packages/angular/cli/src/command-builder/utilities/json-schema.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ export async function parseJsonSchemaToOptions(
148148
if (
149149
json.isJsonObject(current.items) &&
150150
typeof current.items.type == 'string' &&
151-
['boolean', 'number', 'string'].includes(current.items.type)
151+
isValidTypeForEnum(current.items.type)
152152
) {
153153
return true;
154154
}
@@ -169,17 +169,15 @@ export async function parseJsonSchemaToOptions(
169169
}
170170

171171
// Only keep enum values we support (booleans, numbers and strings).
172-
const enumValues = ((json.isJsonArray(current.enum) && current.enum) || []).filter((x) => {
173-
switch (typeof x) {
174-
case 'boolean':
175-
case 'number':
176-
case 'string':
177-
return true;
178-
179-
default:
180-
return false;
181-
}
182-
}) as (string | true | number)[];
172+
const enumValues = (
173+
(json.isJsonArray(current.enum) && current.enum) ||
174+
(json.isJsonObject(current.items) &&
175+
json.isJsonArray(current.items.enum) &&
176+
current.items.enum) ||
177+
[]
178+
)
179+
.filter((value) => isValidTypeForEnum(typeof value))
180+
.sort() as (string | true | number)[];
183181

184182
let defaultValue: string | number | boolean | undefined = undefined;
185183
if (current.default !== undefined) {
@@ -356,3 +354,8 @@ export function addSchemaOptionsToCommand<T>(
356354

357355
return optionsWithAnalytics;
358356
}
357+
358+
const VALID_ENUM_TYPES = new Set(['boolean', 'number', 'string']);
359+
function isValidTypeForEnum(value: string): boolean {
360+
return VALID_ENUM_TYPES.has(value);
361+
}

packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import { json, schema } from '@angular-devkit/core';
10-
import yargs, { positional } from 'yargs';
10+
import yargs from 'yargs';
1111

1212
import { addSchemaOptionsToCommand, parseJsonSchemaToOptions } from './json-schema';
1313

@@ -74,6 +74,13 @@ describe('parseJsonSchemaToOptions', () => {
7474
'type': 'string',
7575
'enum': ['always', 'surprise-me', 'never'],
7676
},
77+
'arrayWithChoices': {
78+
'type': 'array',
79+
'items': {
80+
'type': 'string',
81+
'enum': ['always', 'never'],
82+
},
83+
},
7784
'extendable': {
7885
'type': 'object',
7986
'properties': {},
@@ -100,6 +107,24 @@ describe('parseJsonSchemaToOptions', () => {
100107
});
101108
});
102109

110+
describe('type=array, enum', () => {
111+
it('parses valid option value', async () => {
112+
expect(
113+
await parse(['--arrayWithChoices', 'always', '--arrayWithChoices', 'never']),
114+
).toEqual(
115+
jasmine.objectContaining({
116+
'arrayWithChoices': ['always', 'never'],
117+
}),
118+
);
119+
});
120+
121+
it('rejects non-enum values', async () => {
122+
await expectAsync(parse(['--arrayWithChoices', 'yes'])).toBeRejectedWithError(
123+
/Argument: array-with-choices, Given: "yes", Choices:/,
124+
);
125+
});
126+
});
127+
103128
describe('type=string, enum', () => {
104129
it('parses valid option value', async () => {
105130
expect(await parse(['--ssr', 'never'])).toEqual(

0 commit comments

Comments
 (0)