Skip to content

Commit 372b1ca

Browse files
committed
Use stricter eslint rules
1 parent f2b3de5 commit 372b1ca

33 files changed

+132
-72
lines changed

eslint.config.js

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

eslint.config.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { fileURLToPath } from "node:url";
2+
import eslint from "@eslint/js";
3+
import tseslint, { ConfigArray } from "typescript-eslint";
4+
import { includeIgnoreFile } from "@eslint/compat";
5+
import eslintConfigPrettier from "eslint-config-prettier/flat";
6+
7+
const gitignorePath = fileURLToPath(new URL(".gitignore", import.meta.url));
8+
9+
const config: ConfigArray = tseslint.config(
10+
eslint.configs.recommended,
11+
...tseslint.configs.recommended,
12+
...tseslint.configs.recommendedTypeChecked,
13+
{
14+
languageOptions: {
15+
parserOptions: {
16+
projectService: true,
17+
tsconfigRootDir: import.meta.dirname,
18+
},
19+
},
20+
},
21+
includeIgnoreFile(gitignorePath, "Imported .gitignore patterns"),
22+
eslintConfigPrettier,
23+
{
24+
rules: {
25+
"@typescript-eslint/strict-boolean-expressions": "error",
26+
"no-undef": "off",
27+
"@typescript-eslint/no-explicit-any": "off",
28+
"@typescript-eslint/no-unsafe-return": "off",
29+
"@typescript-eslint/no-unsafe-assignment": "off",
30+
"@typescript-eslint/require-await": "off",
31+
},
32+
},
33+
);
34+
35+
export default config;

src/cli/cli.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,14 @@ async function main() {
4040
}
4141
}
4242

43+
interface Argv {
44+
help: boolean;
45+
init: boolean;
46+
}
47+
4348
async function runCli(): Promise<number> {
4449
const unknownArgs: string[] = [];
45-
const argv = minimist(process.argv.slice(2), {
50+
const argv = minimist<Argv>(process.argv.slice(2), {
4651
boolean: ["help", "init"],
4752
alias: { h: "help" },
4853
unknown: (arg) => {
@@ -111,7 +116,16 @@ async function runCli(): Promise<number> {
111116
throw new SlippyError(result.message, result.code, result.hint);
112117
}
113118
}),
114-
).finally(() => pool.terminate());
119+
).then(
120+
async (x) => {
121+
await pool.terminate();
122+
return x;
123+
},
124+
async (e) => {
125+
await pool.terminate();
126+
throw e;
127+
},
128+
);
115129

116130
const sortedResults = results
117131
.flatMap((x) => x.lintResults)
@@ -150,7 +164,7 @@ async function getSlippyVersion(): Promise<string> {
150164

151165
const packageJsonContents = await fs.readFile(packageJsonPath, "utf8");
152166

153-
const packageJson = JSON.parse(packageJsonContents);
167+
const packageJson = JSON.parse(packageJsonContents) as { version?: string };
154168

155169
return packageJson.version ?? "unknown";
156170
}
@@ -172,4 +186,4 @@ ${chalk.bold("Options")}:
172186
);
173187
}
174188

175-
main();
189+
await main();

src/cli/init.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export async function initConfig() {
1919
let isEsm = false;
2020
if (packageJsonPath !== undefined) {
2121
const packageJsonContents = await fs.readFile(packageJsonPath, "utf8");
22-
const packageJson = JSON.parse(packageJsonContents);
22+
const packageJson = JSON.parse(packageJsonContents) as { type?: string };
2323
isEsm = packageJson.type === "module";
2424
}
2525

src/config.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,15 @@ function validateRuleConfig(config: unknown): string | undefined {
8585
return "Invalid option: expected an array with at most two elements";
8686
}
8787

88-
const severity = config[0];
89-
if (typeof severity !== "string") {
90-
if (typeof severity === "number" && 0 <= severity && severity <= 2) {
88+
if (typeof config[0] !== "string") {
89+
if (typeof config[0] === "number" && 0 <= config[0] && config[0] <= 2) {
9190
return levelAsSeverityMessage;
9291
}
9392
return "Invalid option: expected the first element to be a string";
9493
}
9594

95+
const severity = config[0];
96+
9697
const parsedSeverity = SeveritySchema.safeParse(severity);
9798
if (!parsedSeverity.success) {
9899
return invalidSeverityMessage;
@@ -101,9 +102,14 @@ function validateRuleConfig(config: unknown): string | undefined {
101102

102103
async function loadSlippyConfig(slippyConfigPath: string): Promise<unknown> {
103104
try {
105+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
104106
return (await import(pathToFileURL(slippyConfigPath).href)).default;
105-
} catch (error: any) {
106-
throw new SlippyConfigLoadingError(slippyConfigPath, error.message);
107+
} catch (error: unknown) {
108+
if (error instanceof Error) {
109+
throw new SlippyConfigLoadingError(slippyConfigPath, error.message);
110+
}
111+
112+
throw error;
107113
}
108114
}
109115

src/linter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export class Linter {
8585
}
8686
rule = Rule.create();
8787
}
88-
const ruleResults: LintResult[] = await rule.run({
88+
const ruleResults: LintResult[] = rule.run({
8989
unit,
9090
file,
9191
});

src/rules/naming-convention.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ class NamingConventionRule implements RuleWithConfig<Config> {
455455
if (
456456
config.modifiers?.some(
457457
(modifier) => !hasModifier(definitionCursor.spawn(), modifier),
458-
)
458+
) === true
459459
) {
460460
// does not have the required modifiers
461461
continue;
@@ -539,7 +539,7 @@ class NamingConventionRule implements RuleWithConfig<Config> {
539539
position === "leading"
540540
? config.leadingUnderscore
541541
: config.trailingUnderscore;
542-
if (!option) {
542+
if (option === null) {
543543
return name;
544544
}
545545

@@ -673,7 +673,7 @@ class NamingConventionRule implements RuleWithConfig<Config> {
673673
originalName: string,
674674
): LintResult | undefined {
675675
const formats = config.format;
676-
if (!formats?.length) {
676+
if (formats === null || formats.length === 0) {
677677
return;
678678
}
679679

@@ -716,7 +716,7 @@ function normalizeOption(option: Selector): NormalizedSelector[] {
716716
});
717717

718718
// give selectors with a filter the _highest_ priority
719-
if (option.filter) {
719+
if (option.filter !== undefined) {
720720
weight |= 1 << 30;
721721
}
722722

src/slang/compilation-unit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export async function compilationUnitFromContent({
2727
const builder = CompilationBuilder.create({
2828
languageVersion,
2929
readFile,
30-
resolveImport: async () => undefined,
30+
resolveImport: () => Promise.resolve(undefined),
3131
});
3232

3333
await builder.addFile(filePath);

test/config.test.ts

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,21 @@ describe("config", function () {
5858
const parseAndReturnErrorMessage = (config: unknown) => {
5959
try {
6060
validateUserConfig(config, "/path/to/config.js");
61-
} catch (error: any) {
62-
return error;
61+
} catch (error: unknown) {
62+
if (error instanceof SlippyInvalidConfigError) {
63+
return error;
64+
}
65+
66+
throw error;
6367
}
6468
};
6569

6670
it("undefined config", function () {
6771
const error = parseAndReturnErrorMessage(undefined);
6872

69-
expect(error).instanceOf(SlippyInvalidConfigError);
73+
if (error === undefined) {
74+
expect.fail();
75+
}
7076
expect(error.message).toMatchInlineSnapshot(
7177
`"Invalid config at '/path/to/config.js': Configuration must be an object"`,
7278
);
@@ -78,7 +84,9 @@ describe("config", function () {
7884
it("unknown key", function () {
7985
const error = parseAndReturnErrorMessage({ invalidKey: {} });
8086

81-
expect(error).instanceOf(SlippyInvalidConfigError);
87+
if (error === undefined) {
88+
expect.fail();
89+
}
8290
expect(error.message).toMatchInlineSnapshot(`
8391
"Invalid config at '/path/to/config.js':
8492
@@ -91,7 +99,9 @@ describe("config", function () {
9199
rules: { "some-rule": "erro" },
92100
});
93101

94-
expect(error).instanceOf(SlippyInvalidConfigError);
102+
if (error === undefined) {
103+
expect.fail();
104+
}
95105
expect(error.message).toMatchInlineSnapshot(`
96106
"Invalid config at '/path/to/config.js':
97107
@@ -105,7 +115,9 @@ describe("config", function () {
105115
rules: { "some-rule": ["erro"] },
106116
});
107117

108-
expect(error).instanceOf(SlippyInvalidConfigError);
118+
if (error === undefined) {
119+
expect.fail();
120+
}
109121
expect(error.message).toMatchInlineSnapshot(`
110122
"Invalid config at '/path/to/config.js':
111123
@@ -117,7 +129,9 @@ describe("config", function () {
117129
it("rule config is empty array", function () {
118130
const error = parseAndReturnErrorMessage({ rules: { "some-rule": [] } });
119131

120-
expect(error).instanceOf(SlippyInvalidConfigError);
132+
if (error === undefined) {
133+
expect.fail();
134+
}
121135
expect(error.message).toMatchInlineSnapshot(`
122136
"Invalid config at '/path/to/config.js':
123137
@@ -131,7 +145,9 @@ describe("config", function () {
131145
rules: { "some-rule": ["error", {}, {}] },
132146
});
133147

134-
expect(error).instanceOf(SlippyInvalidConfigError);
148+
if (error === undefined) {
149+
expect.fail();
150+
}
135151
expect(error.message).toMatchInlineSnapshot(`
136152
"Invalid config at '/path/to/config.js':
137153
@@ -143,7 +159,9 @@ describe("config", function () {
143159
it("severity as a level, shorthand", function () {
144160
const error = parseAndReturnErrorMessage({ rules: { "some-rule": 1 } });
145161

146-
expect(error).instanceOf(SlippyInvalidConfigError);
162+
if (error === undefined) {
163+
expect.fail();
164+
}
147165
expect(error.message).toMatchInlineSnapshot(`
148166
"Invalid config at '/path/to/config.js':
149167
@@ -155,7 +173,9 @@ describe("config", function () {
155173
it("severity as a level", function () {
156174
const error = parseAndReturnErrorMessage({ rules: { "some-rule": [1] } });
157175

158-
expect(error).instanceOf(SlippyInvalidConfigError);
176+
if (error === undefined) {
177+
expect.fail();
178+
}
159179
expect(error.message).toMatchInlineSnapshot(`
160180
"Invalid config at '/path/to/config.js':
161181

test/examples.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ interface Example {
1111
config: any;
1212
}
1313

14-
describe("rules examples", async function () {
14+
describe("rules examples", function () {
1515
const rules = getAllRules();
1616

1717
for (const rule of rules) {

0 commit comments

Comments
 (0)