This repository was archived by the owner on Mar 7, 2025. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathgenerate-eslint-dts.ts
84 lines (70 loc) · 2.26 KB
/
generate-eslint-dts.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import { pascalCase } from 'change-case';
import type { Rule } from 'eslint';
import eslint from 'eslint';
import type { JSONSchema4 } from 'json-schema';
import { compile } from 'json-schema-to-typescript';
import { writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { URL, fileURLToPath } from 'node:url';
const __dirname = fileURLToPath(new URL('.', import.meta.url));
const rules = Object.fromEntries(new eslint.Linter().getRules().entries());
const ruleOptionImports: string[] = [];
const ruleDeclarations: string[] = [];
for (const [ruleName, ruleDefinition] of Object.entries(rules ?? {})) {
const meta = ruleDefinition.meta ?? {};
let schemas = (meta.schema as JSONSchema4[]) ?? [];
if (!Array.isArray(schemas)) {
schemas = [schemas];
}
const options = await Promise.all(
schemas.map(async (schema, index) => {
schema = JSON.parse(
JSON.stringify(schema).replaceAll('#/items/0/$defs/', '#/$defs/'),
);
return await compile(schema, `Schema${index}`, {
bannerComment: '',
});
}),
);
const optionTypes = options.map((_, index) => `Schema${index}?`);
const ruleOptionTypeValue = Array.isArray(meta.schema)
? `[${optionTypes.join(', ')}]`
: meta.schema
? 'Schema0'
: '[]';
await writeFile(
join(__dirname, '..', 'src', 'rules', 'eslint', `${ruleName}.d.ts`),
`${options.join('\n')}
export type ${pascalCase(ruleName)}RuleOptions = ${
ruleName === 'no-constructor-return' ? '[Schema0?]' : ruleOptionTypeValue
};
`,
{
encoding: 'utf8',
flag: 'w',
},
);
ruleOptionImports.push(
`import type { ${pascalCase(ruleName)}RuleOptions } from "./${ruleName}"`,
);
const documentation: Rule.RuleMetaData['docs'] = meta.docs ?? {};
ruleDeclarations.push(`/**
* ${documentation.description?.replace(/\*\/`/g, '*\\/`')}
*
* @see [${ruleName}](${documentation.url})
*/
"${ruleName}": RuleConfig<${pascalCase(ruleName)}RuleOptions>;`);
}
await writeFile(
join(__dirname, '..', 'src', 'rules', 'eslint', 'index.d.ts'),
`${ruleOptionImports.join('\n')}
import type { RuleConfig } from '../rule-config';
export interface EslintRules {
${ruleDeclarations.join('\n')}
}
`,
{
encoding: 'utf8',
flag: 'w',
},
);