Skip to content
This repository was archived by the owner on Mar 7, 2025. It is now read-only.

Commit 48865e2

Browse files
committed
Fix lint warnings
1 parent c4efe4d commit 48865e2

File tree

6 files changed

+83
-61
lines changed

6 files changed

+83
-61
lines changed

scripts/generate-rule-files/cli.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { run } from '.';
22

3-
const selectedPlugins = process.argv
3+
const selectedPlugins: string[] | undefined = process.argv
44
.slice(2)
55
.find((arg) => arg.startsWith('--plugins='))
66
?.replace('--plugins=', '')

scripts/generate-rule-files/index.ts

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { logger } from '@poppinss/cliui';
22
import { pascalCase } from 'change-case';
33
import type { Rule } from 'eslint';
4-
import * as fs from 'node:fs';
4+
import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
55
import { join } from 'node:path';
66
import dedent from 'ts-dedent';
77
import type { Plugin } from './contracts';
@@ -19,40 +19,40 @@ function generateRuleIndexFile(
1919
{ rules, name }: Plugin,
2020
failedRules: string[],
2121
): void {
22-
const generatedRules = Object.keys(rules).filter(
22+
const generatedRules: string[] = Object.keys(rules).filter(
2323
(ruleName) => !failedRules.includes(ruleName),
2424
);
2525

2626
/**
2727
* Build all the import statements for the rules
2828
*/
29-
const rulesImports = generatedRules
29+
const rulesImports: string = generatedRules
3030
.map((name) => `import type { ${pascalCase(name)}Rule } from './${name}';`)
3131
.join('\n');
3232

3333
/**
3434
* Build the exported type that is an intersection of all the rules
3535
*/
36-
const rulesFinalIntersection = generatedRules
36+
const rulesFinalIntersection: string = generatedRules
3737
.map((name) => `${pascalCase(name)}Rule`)
3838
.join(' & ');
3939

40-
const pluginRulesType = dedent(`
40+
const pluginRulesType: string = dedent(`
4141
${JsDocBuilder.build().add(`All ${name} rules.`).output()}
4242
export type ${name}Rules = ${rulesFinalIntersection};
4343
`);
4444

4545
/**
4646
* Write the final index.d.ts file
4747
*/
48-
const fileContent = dedent(`
48+
const fileContent: string = dedent(`
4949
${rulesImports}
5050
5151
${pluginRulesType}
5252
`);
5353

54-
const indexPath = join(pluginDirectory, 'index.d.ts');
55-
fs.writeFileSync(indexPath, format(fileContent));
54+
const indexPath: string = join(pluginDirectory, 'index.d.ts');
55+
writeFileSync(indexPath, format(fileContent));
5656
}
5757

5858
/**
@@ -62,7 +62,9 @@ function printGenerationReport(
6262
rules: [string, Rule.RuleModule][],
6363
failedRules: string[],
6464
): void {
65-
const msg = ` ✅ Generated ${rules.length - failedRules.length} rules`;
65+
const msg: string = ` ✅ Generated ${
66+
rules.length - failedRules.length
67+
} rules`;
6668
logger.logUpdate(logger.colors.green(msg));
6769
logger.logUpdatePersist();
6870

@@ -81,11 +83,16 @@ async function generateRulesFiles(
8183
): Promise<{ failedRules: string[] }> {
8284
const failedRules: string[] = [];
8385

84-
const rules = Object.entries(plugin.rules);
86+
const rules: Array<[string, Rule.RuleModule]> = Object.entries(plugin.rules);
8587
for (const [ruleName, rule] of rules) {
8688
logger.logUpdate(logger.colors.yellow(` Generating > ${ruleName}`));
8789

88-
const ruleFile = new RuleFile(plugin, pluginDirectory, ruleName, rule);
90+
const ruleFile: RuleFile = new RuleFile(
91+
plugin,
92+
pluginDirectory,
93+
ruleName,
94+
rule,
95+
);
8996
try {
9097
await ruleFile.generate();
9198
ruleFile.writeGeneratedContent();
@@ -106,34 +113,43 @@ function createPluginDirectory(
106113
pluginName: string,
107114
targetDirectory?: string,
108115
): string {
109-
const rulesDirectory = join(__dirname, targetDirectory || '../../src/rules');
110-
const pluginDirectory = join(rulesDirectory, pluginName);
116+
const rulesDirectory: string = join(
117+
__dirname,
118+
targetDirectory ?? '../../src/rules',
119+
);
120+
const pluginDirectory: string = join(rulesDirectory, pluginName);
111121

112-
if (fs.existsSync(pluginDirectory)) {
113-
fs.rmSync(pluginDirectory, { recursive: true, force: true });
122+
if (existsSync(pluginDirectory)) {
123+
rmSync(pluginDirectory, { recursive: true, force: true });
114124
}
115125

116-
fs.mkdirSync(pluginDirectory, { mode: 0o755, recursive: true });
126+
mkdirSync(pluginDirectory, { mode: 0o755, recursive: true });
117127
return pluginDirectory;
118128
}
119129

120-
export async function run(options?: {
121-
plugins?: string[];
122-
targetDirectory?: string;
123-
}): Promise<void> {
124-
const { plugins, targetDirectory } = options || {};
125-
const wantedPlugins = plugins ?? Object.keys(pluginsMap);
130+
export async function run(
131+
options: {
132+
plugins?: string[];
133+
targetDirectory?: string;
134+
} = {},
135+
): Promise<void> {
136+
const { plugins, targetDirectory } = options;
137+
138+
const wantedPlugins: string[] = plugins ?? Object.keys(pluginsMap);
126139

127140
for (const pluginName of wantedPlugins) {
128-
const plugin = pluginsMap[pluginName]!;
141+
const plugin: Plugin = pluginsMap[pluginName]!;
129142

130143
if (!plugin) {
131144
throw new Error(`Plugin ${pluginName} doesn't exist`);
132145
}
133146

134147
logger.info(`Generating ${plugin.name} rules`);
135148

136-
const pluginDir = createPluginDirectory(pluginName, targetDirectory);
149+
const pluginDir: string = createPluginDirectory(
150+
pluginName,
151+
targetDirectory,
152+
);
137153
const { failedRules } = await generateRulesFiles(plugin, pluginDir);
138154

139155
generateRuleIndexFile(pluginDir, plugin, failedRules);

scripts/generate-rule-files/src/format.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ const PRETTIER_OPTIONS: Options = {
1414
/**
1515
* Format the given content with Prettier.
1616
*/
17-
export const format = (content: string): string => {
17+
export function format(content: string): string {
1818
return prettierFormat(content, PRETTIER_OPTIONS);
19-
};
19+
}

scripts/generate-rule-files/src/json-schema-to-ts.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { compile } from 'json-schema-to-typescript';
66
* and that we don't need
77
*/
88
function removeGarbageFromJsDocs(content: string): string {
9-
const patterns = [
9+
const patterns: RegExp[] = [
1010
/\* This interface was referenced by .+ JSON-Schema definition/,
1111
/\* via the `.+` "/,
1212
];
@@ -24,7 +24,7 @@ export async function generateTypeFromSchema(
2424
schema: JSONSchema4,
2525
typeName: string,
2626
): Promise<string> {
27-
const result = await compile(schema, typeName, {
27+
const result: string = await compile(schema, typeName, {
2828
format: false,
2929
bannerComment: '',
3030
style: { singleQuote: true, trailingComma: 'all' },

scripts/generate-rule-files/src/rule-file.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { JsDocBuilder } from './js-doc-builder';
1010
import { generateTypeFromSchema } from './json-schema-to-ts';
1111

1212
export class RuleFile {
13-
private content = '';
13+
private content: string = '';
1414
private readonly rulePath: string;
1515
private readonly ruleNamePascalCase: string;
1616

@@ -31,7 +31,9 @@ export class RuleFile {
3131
}
3232

3333
private assignSchemasInfo(): void {
34-
const schema = this.rule.meta?.schema;
34+
const schema: JSONSchema4 | JSONSchema4[] | undefined =
35+
this.rule.meta?.schema;
36+
// eslint-disable-next-line @typescript-eslint/typedef
3537
const isArray = Array.isArray(schema);
3638

3739
this.mainSchema = isArray ? schema[0] : schema;
@@ -44,8 +46,9 @@ export class RuleFile {
4446
* Append the `import type { RuleConfig } at the top of the file
4547
*/
4648
public appendRuleConfigImport(): void {
47-
const nestedDepth = this.ruleName.split('/').length;
48-
const ruleConfigImportPath = '../'.repeat(nestedDepth) + 'rule-config';
49+
const nestedDepth: number = this.ruleName.split('/').length;
50+
const ruleConfigImportPath: string =
51+
'../'.repeat(nestedDepth) + 'rule-config';
4952
this.content += `import type { RuleConfig } from '${ruleConfigImportPath}'\n\n`;
5053
}
5154

@@ -96,12 +99,12 @@ export class RuleFile {
9699
schema: JSONSchema4,
97100
comment: string,
98101
): Promise<void> {
99-
const type = await generateTypeFromSchema(
102+
const type: string = await generateTypeFromSchema(
100103
schema,
101104
this.ruleNamePascalCase + comment,
102105
);
103106

104-
const jsdoc = JsDocBuilder.build().add(`${comment}.`).output();
107+
const jsdoc: string = JsDocBuilder.build().add(`${comment}.`).output();
105108
this.content += `\n${jsdoc}`;
106109
this.content += `\n${type}\n`;
107110
}
@@ -127,9 +130,9 @@ export class RuleFile {
127130
* Append the rule type options to the file content
128131
*/
129132
private appendRuleOptions(): void {
130-
const ruleName = this.ruleNamePascalCase;
133+
const ruleName: string = this.ruleNamePascalCase;
131134

132-
let type = '';
135+
let type: string = '';
133136
if (!this.isSchemaArray) {
134137
type = `${ruleName}Option`;
135138
} else if (this.thirdSchema) {
@@ -148,8 +151,10 @@ export class RuleFile {
148151
* Append the rule config type to the file content
149152
*/
150153
private appendRuleConfig(): void {
151-
const ruleName = this.ruleNamePascalCase;
152-
const genericContent = this.mainSchema ? `${ruleName}Options` : '[]';
154+
const ruleName: string = this.ruleNamePascalCase;
155+
const genericContent: string = this.mainSchema
156+
? `${ruleName}Options`
157+
: '[]';
153158

154159
this.content += this.generateTypeJsDoc() + '\n';
155160
this.content += `export type ${ruleName}RuleConfig = RuleConfig<${genericContent}>;\n\n`;
@@ -159,9 +164,9 @@ export class RuleFile {
159164
* Append the final rule interface to the file content
160165
*/
161166
private appendRule(): void {
162-
const ruleName = this.ruleNamePascalCase;
167+
const ruleName: string = this.ruleNamePascalCase;
163168
const { prefix, name } = this.plugin;
164-
let rulePrefix = (prefix ?? kebabCase(name)) + '/';
169+
let rulePrefix: string = (prefix ?? kebabCase(name)) + '/';
165170
if (name === 'Eslint') {
166171
rulePrefix = '';
167172
}
@@ -178,7 +183,7 @@ export class RuleFile {
178183
* Create the directory of the rule file if it doesn't exist
179184
*/
180185
private createRuleDirectory(): void {
181-
const subPath = dirname(this.rulePath.toLowerCase());
186+
const subPath: string = dirname(this.rulePath.toLowerCase());
182187
if (!existsSync(subPath)) {
183188
mkdirSync(subPath, { recursive: true });
184189
}

tests/generate-rule-files.test.ts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/* eslint-disable @typescript-eslint/no-unsafe-argument */
22

3+
import type { Rule } from 'eslint';
34
import { describe, expect, it } from 'vitest';
45
import { generateTypeFromSchema } from '../scripts/generate-rule-files/src/json-schema-to-ts';
56
import { RuleFile } from '../scripts/generate-rule-files/src/rule-file';
67

78
describe('Json schema to ts', () => {
89
it('Should remove garbage comments', async () => {
9-
const result = await generateTypeFromSchema(
10+
const result: string = await generateTypeFromSchema(
1011
{
1112
type: 'object',
1213
properties: {
@@ -30,29 +31,29 @@ describe('Json schema to ts', () => {
3031

3132
describe('Rule File', () => {
3233
it('Main schema', async () => {
33-
const rule = {
34+
const rule: Rule.RuleModule = {
3435
meta: {
3536
docs: {
3637
description: 'My rule description',
3738
url: 'http://test.com/my-rule',
3839
},
3940
schema: [{ type: 'integer', minimum: 0 }],
4041
},
41-
};
42+
} as Rule.RuleModule;
4243

43-
const ruleFile = new RuleFile(
44+
const ruleFile: RuleFile = new RuleFile(
4445
{ name: 'my-plugin', rules: {} },
4546
'my-plugin',
4647
'my-rule',
47-
rule as any,
48+
rule,
4849
);
4950

50-
const content = await ruleFile.generate();
51+
const content: string = await ruleFile.generate();
5152
expect(content).toMatchSnapshot();
5253
});
5354

5455
it('Two schemas', async () => {
55-
const rule = {
56+
const rule: Rule.RuleModule = {
5657
meta: {
5758
docs: {
5859
description: 'My rule description',
@@ -63,21 +64,21 @@ describe('Rule File', () => {
6364
{ type: 'string', minLength: 1 },
6465
],
6566
},
66-
};
67+
} as Rule.RuleModule;
6768

68-
const ruleFile = new RuleFile(
69+
const ruleFile: RuleFile = new RuleFile(
6970
{ name: 'my-plugin', rules: {} },
7071
'my-plugin',
7172
'my-rule',
72-
rule as any,
73+
rule,
7374
);
7475

75-
const content = await ruleFile.generate();
76+
const content: string = await ruleFile.generate();
7677
expect(content).toMatchSnapshot();
7778
});
7879

7980
it('Three schemas', async () => {
80-
const rule = {
81+
const rule: Rule.RuleModule = {
8182
meta: {
8283
docs: {
8384
description: 'My rule description',
@@ -89,21 +90,21 @@ describe('Rule File', () => {
8990
{ type: 'boolean' },
9091
],
9192
},
92-
};
93+
} as Rule.RuleModule;
9394

94-
const ruleFile = new RuleFile(
95+
const ruleFile: RuleFile = new RuleFile(
9596
{ name: 'my-plugin', rules: {} },
9697
'my-plugin',
9798
'my-rule',
9899
rule as any,
99100
);
100101

101-
const content = await ruleFile.generate();
102+
const content: string = await ruleFile.generate();
102103
expect(content).toMatchSnapshot();
103104
});
104105

105106
it('Object schema', async () => {
106-
const rule = {
107+
const rule: Rule.RuleModule = {
107108
meta: {
108109
docs: {
109110
description: 'My rule description',
@@ -113,16 +114,16 @@ describe('Rule File', () => {
113114
type: 'object',
114115
},
115116
},
116-
};
117+
} as Rule.RuleModule;
117118

118-
const ruleFile = new RuleFile(
119+
const ruleFile: RuleFile = new RuleFile(
119120
{ name: 'my-plugin', rules: {} },
120121
'my-plugin',
121122
'my-rule',
122123
rule as any,
123124
);
124125

125-
const content = await ruleFile.generate();
126+
const content: string = await ruleFile.generate();
126127
expect(content).toMatchSnapshot();
127128
});
128129
});

0 commit comments

Comments
 (0)