Skip to content

Commit 664e27c

Browse files
committed
Fix mapped options using TS enums as a map
1 parent c901dbc commit 664e27c

File tree

3 files changed

+21
-10
lines changed

3 files changed

+21
-10
lines changed

src/lib/utils/options/declaration.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -380,14 +380,17 @@ const converters: {
380380
return strArrValue;
381381
},
382382
[ParameterType.Map](value, option) {
383-
const key = String(value).toLowerCase();
383+
const key = String(value);
384384
if (option.map instanceof Map) {
385385
if (option.map.has(key)) {
386386
return option.map.get(key);
387387
} else if ([...option.map.values()].includes(value)) {
388388
return value;
389389
}
390390
} else if (key in option.map) {
391+
if (isTsNumericEnum(option.map) && typeof value === "number") {
392+
return value;
393+
}
391394
return option.map[key];
392395
} else if (Object.values(option.map).includes(value)) {
393396
return value;
@@ -505,6 +508,10 @@ function resolveModulePaths(modules: readonly string[], configPath: string) {
505508
});
506509
}
507510

511+
function isTsNumericEnum(map: Record<string, any>) {
512+
return Object.values(map).every((key) => map[map[key]] === key);
513+
}
514+
508515
/**
509516
* Returns an error message for a map option, indicating that a given value was not one of the values within the map.
510517
* @param map The values for the option.
@@ -516,15 +523,10 @@ function getMapError(
516523
name: string
517524
): string {
518525
let keys = map instanceof Map ? [...map.keys()] : Object.keys(map);
519-
const getString = (key: string) =>
520-
String(map instanceof Map ? map.get(key) : map[key]);
521526

522527
// If the map is a TS numeric enum we need to filter out the numeric keys.
523528
// TS numeric enums have the property that every key maps to a value, which maps back to that key.
524-
if (
525-
!(map instanceof Map) &&
526-
keys.every((key) => getString(getString(key)) === key)
527-
) {
529+
if (!(map instanceof Map) && isTsNumericEnum(map)) {
528530
// This works because TS enum keys may not be numeric.
529531
keys = keys.filter((key) => Number.isNaN(parseInt(key, 10)));
530532
}

src/test/.editorconfig

Lines changed: 0 additions & 2 deletions
This file was deleted.

src/test/utils/options/options.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Logger, Options, ParameterType } from "../../../lib/utils";
1+
import { Logger, LogLevel, Options, ParameterType } from "../../../lib/utils";
22
import {
33
BindOption,
44
MapDeclarationOption,
@@ -94,6 +94,17 @@ describe("Options", () => {
9494
throws(() => options.setValue("mapped" as any, "nonsense" as any));
9595
});
9696

97+
it("Handles mapped enums properly", () => {
98+
const options = new Options(new Logger());
99+
options.addDefaultDeclarations();
100+
101+
equal(options.getValue("logLevel"), LogLevel.Info);
102+
options.setValue("logLevel", LogLevel.Error);
103+
equal(options.getValue("logLevel"), LogLevel.Error);
104+
options.setValue("logLevel", "Verbose");
105+
equal(options.getValue("logLevel"), LogLevel.Verbose);
106+
});
107+
97108
it("Supports directly getting values", () => {
98109
equal(options.getRawValues().entryPoints, []);
99110
});

0 commit comments

Comments
 (0)