2
2
import eslintPluginTypeScript from '@typescript-eslint/eslint-plugin' ;
3
3
import { camelCase , pascalCase } from 'change-case' ;
4
4
import type { Rule } from 'eslint' ;
5
+ import * as eslint from 'eslint' ;
5
6
// @ts -expect-error
6
7
import eslintPluginJSDoc from 'eslint-plugin-jsdoc' ;
7
8
// @ts -expect-error
@@ -35,6 +36,10 @@ const PRETTIER_OPTIONS: Options = {
35
36
} ;
36
37
37
38
const generationMap : Record < string , Plugin > = {
39
+ eslint : {
40
+ name : 'Eslint' ,
41
+ rules : Object . fromEntries ( new eslint . Linter ( ) . getRules ( ) . entries ( ) )
42
+ } ,
38
43
jsdoc : {
39
44
name : 'JSDoc' ,
40
45
rules : ( eslintPluginJSDoc as Plugin ) . rules
@@ -65,28 +70,50 @@ async function main(): Promise<void> {
65
70
66
71
fs . mkdirSync ( ruleProviderDir , { mode : 0o755 , recursive : true } ) ;
67
72
73
+ const failedRules : string [ ] = [ ] ;
68
74
for ( const [ ruleName , { meta } ] of Object . entries ( rules ) ) {
69
- const rulePath : string = path . resolve ( ruleProviderDir , `${ ruleName } .d.ts` ) ;
70
- let ruleContent : string = "import type { RuleConfig } from '../rule-config';" ;
75
+ try {
76
+ const rulePath : string = path . resolve ( ruleProviderDir , `${ ruleName } .d.ts` ) ;
77
+ let ruleContent : string = "import type { RuleConfig } from '../rule-config';" ;
71
78
72
- const ruleNamePascalCase : string = pascalCase ( ruleName ) ;
79
+ const ruleNamePascalCase : string = pascalCase ( ruleName ) ;
73
80
74
- let description : string = upperCaseFirst ( meta ?. docs ?. description ?? '' ) ;
75
- if ( description . length > 0 && ! description . endsWith ( '.' ) ) {
76
- description += '.' ;
77
- }
78
- const seeDocLink : string = meta ?. docs ?. url ? `@see [${ ruleName } ](${ meta . docs . url } )` : '' ;
79
-
80
- const schema : JSONSchema4 | JSONSchema4 [ ] | undefined = meta ?. schema ;
81
- const mainSchema : JSONSchema4 | undefined = Array . isArray ( schema ) ? schema [ 0 ] : schema ;
82
- const sideSchema : JSONSchema4 | undefined =
83
- schema && Array . isArray ( schema ) && schema . length > 1 ? schema [ 1 ] : undefined ;
84
- const thirdSchema : JSONSchema4 | undefined =
85
- schema && Array . isArray ( schema ) && schema . length > 2 ? schema [ 2 ] : undefined ;
86
- if ( mainSchema ) {
87
- if ( sideSchema ) {
88
- if ( thirdSchema ) {
89
- const ruleSetting : string = await compile ( thirdSchema , `${ ruleNamePascalCase } Setting` , {
81
+ let description : string = upperCaseFirst ( meta ?. docs ?. description ?? '' ) ;
82
+ if ( description . length > 0 && ! description . endsWith ( '.' ) ) {
83
+ description += '.' ;
84
+ }
85
+ const seeDocLink : string = meta ?. docs ?. url ? `@see [${ ruleName } ](${ meta . docs . url } )` : '' ;
86
+
87
+ const schema : JSONSchema4 | JSONSchema4 [ ] | undefined = meta ?. schema ;
88
+ const mainSchema : JSONSchema4 | undefined = Array . isArray ( schema ) ? schema [ 0 ] : schema ;
89
+ const sideSchema : JSONSchema4 | undefined =
90
+ schema && Array . isArray ( schema ) && schema . length > 1 ? schema [ 1 ] : undefined ;
91
+ const thirdSchema : JSONSchema4 | undefined =
92
+ schema && Array . isArray ( schema ) && schema . length > 2 ? schema [ 2 ] : undefined ;
93
+ if ( mainSchema ) {
94
+ if ( sideSchema ) {
95
+ if ( thirdSchema ) {
96
+ const ruleSetting : string = await compile ( thirdSchema , `${ ruleNamePascalCase } Setting` , {
97
+ bannerComment : '' ,
98
+ style : {
99
+ bracketSpacing : true ,
100
+ printWidth : 120 ,
101
+ semi : true ,
102
+ singleQuote : true ,
103
+ tabWidth : 2 ,
104
+ trailingComma : 'none' ,
105
+ useTabs : false
106
+ } ,
107
+ unknownAny : false
108
+ } ) ;
109
+ ruleContent += `
110
+
111
+ /**
112
+ * Setting.
113
+ */
114
+ ${ ruleSetting } `;
115
+ }
116
+ const ruleConfig : string = await compile ( sideSchema , `${ ruleNamePascalCase } Config` , {
90
117
bannerComment : '' ,
91
118
style : {
92
119
bracketSpacing : true ,
@@ -102,11 +129,12 @@ async function main(): Promise<void> {
102
129
ruleContent += `
103
130
104
131
/**
105
- * Setting .
132
+ * Config .
106
133
*/
107
- ${ ruleSetting } `;
134
+ ${ ruleConfig } `;
108
135
}
109
- const ruleConfig : string = await compile ( sideSchema , `${ ruleNamePascalCase } Config` , {
136
+
137
+ const ruleOption : string = await compile ( mainSchema , `${ ruleNamePascalCase } Option` , {
110
138
bannerComment : '' ,
111
139
style : {
112
140
bracketSpacing : true ,
@@ -119,29 +147,8 @@ ${ruleSetting}`;
119
147
} ,
120
148
unknownAny : false
121
149
} ) ;
122
- ruleContent += `
123
150
124
- /**
125
- * Config.
126
- */
127
- ${ ruleConfig } `;
128
- }
129
-
130
- const ruleOption : string = await compile ( mainSchema , `${ ruleNamePascalCase } Option` , {
131
- bannerComment : '' ,
132
- style : {
133
- bracketSpacing : true ,
134
- printWidth : 120 ,
135
- semi : true ,
136
- singleQuote : true ,
137
- tabWidth : 2 ,
138
- trailingComma : 'none' ,
139
- useTabs : false
140
- } ,
141
- unknownAny : false
142
- } ) ;
143
-
144
- ruleContent += `
151
+ ruleContent += `
145
152
146
153
/**
147
154
* Option.
@@ -152,13 +159,13 @@ ${ruleOption}
152
159
* Options.
153
160
*/
154
161
export type ${ ruleNamePascalCase } Options = [${ ruleNamePascalCase } Option?${
155
- sideSchema ? `, ${ ruleNamePascalCase } Config?${ thirdSchema ? `, ${ ruleNamePascalCase } Setting?` : '' } ` : ''
156
- } ];`;
157
- }
162
+ sideSchema ? `, ${ ruleNamePascalCase } Config?${ thirdSchema ? `, ${ ruleNamePascalCase } Setting?` : '' } ` : ''
163
+ } ];`;
164
+ }
158
165
159
- // TODO: Add third option
166
+ // TODO: Add third option
160
167
161
- ruleContent += `
168
+ ruleContent += `
162
169
163
170
/**
164
171
* ${ description }
@@ -178,16 +185,23 @@ export type ${ruleNamePascalCase}Options = [${ruleNamePascalCase}Option?${
178
185
*
179
186
* ${ seeDocLink }
180
187
*/
181
- '${ prefix ?? camelCase ( pluginName ) } /${ ruleName } ': ${ ruleNamePascalCase } RuleConfig;
188
+ '${
189
+ pluginName !== 'eslint' ? `${ prefix ?? camelCase ( pluginName ) } /` : ''
190
+ } ${ ruleName } ': ${ ruleNamePascalCase } RuleConfig;
182
191
}
183
192
` ;
184
- ruleContent = format ( ruleContent , PRETTIER_OPTIONS ) ;
185
- fs . writeFileSync ( rulePath , ruleContent ) ;
193
+ ruleContent = format ( ruleContent , PRETTIER_OPTIONS ) ;
194
+ fs . writeFileSync ( rulePath , ruleContent ) ;
195
+ } catch ( error ) {
196
+ console . log ( `Failed to generate rule ${ ruleName } for ${ name } ` , error ) ;
197
+ failedRules . push ( ruleName ) ;
198
+ }
186
199
}
187
200
188
201
// Generating index.d.ts for rules
189
202
const indexPath : string = path . resolve ( ruleProviderDir , 'index.d.ts' ) ;
190
203
let indexContent : string = Object . keys ( rules )
204
+ . filter ( ( name ) => ! failedRules . includes ( name ) )
191
205
. map ( ( name ) => `import type { ${ pascalCase ( name ) } Rule } from './${ name } ';` )
192
206
. join ( '\n' ) ;
193
207
@@ -197,6 +211,7 @@ export type ${ruleNamePascalCase}Options = [${ruleNamePascalCase}Option?${
197
211
* All ${ name } rules.
198
212
*/
199
213
export type ${ name } Rules = ${ Object . keys ( rules )
214
+ . filter ( ( name ) => ! failedRules . includes ( name ) )
200
215
. map ( ( name ) => `${ pascalCase ( name ) } Rule` )
201
216
. join ( ' & ' ) }
202
217
` ;
0 commit comments