@@ -22,9 +22,20 @@ interface CheckNameFormatParams {
22
22
trailingUnderscore : 'allow' | 'forbid' ;
23
23
prefix : string ;
24
24
suffix : string ;
25
+ forbiddenPrefixes : string [ ] ;
26
+ forbiddenSuffixes : string [ ] ;
25
27
}
26
28
function checkNameFormat ( params : CheckNameFormatParams ) : { ok : false ; errorMessage : string } | { ok : true } {
27
- const { value, style, leadingUnderscore, trailingUnderscore, suffix, prefix } = params ;
29
+ const {
30
+ value,
31
+ style,
32
+ leadingUnderscore,
33
+ trailingUnderscore,
34
+ suffix,
35
+ prefix,
36
+ forbiddenPrefixes,
37
+ forbiddenSuffixes,
38
+ } = params ;
28
39
let name = value ;
29
40
if ( leadingUnderscore === 'allow' ) {
30
41
[ , name ] = name . match ( / ^ _ * ( .* ) $ / ) ;
@@ -46,6 +57,22 @@ function checkNameFormat(params: CheckNameFormatParams): { ok: false; errorMessa
46
57
) } `,
47
58
} ;
48
59
}
60
+ if ( forbiddenPrefixes . some ( forbiddenPrefix => name . startsWith ( forbiddenPrefix ) ) ) {
61
+ return {
62
+ ok : false ,
63
+ errorMessage :
64
+ '{{nodeType}} "{{nodeName}}" should not have one of the following prefix(es): {{forbiddenPrefixes}}' ,
65
+ } ;
66
+ }
67
+
68
+ if ( forbiddenSuffixes . some ( forbiddenSuffix => name . endsWith ( forbiddenSuffix ) ) ) {
69
+ return {
70
+ ok : false ,
71
+ errorMessage :
72
+ '{{nodeType}} "{{nodeName}}" should not have one of the following suffix(es): {{forbiddenSuffixes}}' ,
73
+ } ;
74
+ }
75
+
49
76
if ( ! formats [ style ] ) {
50
77
return { ok : true } ;
51
78
}
@@ -64,12 +91,15 @@ interface PropertySchema {
64
91
style ?: ValidNaming ;
65
92
suffix ?: string ;
66
93
prefix ?: string ;
94
+ forbiddenPrefixes ?: string [ ] ;
95
+ forbiddenSuffixes ?: string [ ] ;
67
96
}
68
97
69
98
type NamingConventionRuleConfig = [
70
99
{
71
100
leadingUnderscore ?: 'allow' | 'forbid' ;
72
101
trailingUnderscore ?: 'allow' | 'forbid' ;
102
+ QueryDefinition ?: ValidNaming | PropertySchema ;
73
103
[ Kind . FIELD_DEFINITION ] ?: ValidNaming | PropertySchema ;
74
104
[ Kind . ENUM_VALUE_DEFINITION ] ?: ValidNaming | PropertySchema ;
75
105
[ Kind . INPUT_VALUE_DEFINITION ] ?: ValidNaming | PropertySchema ;
@@ -135,6 +165,22 @@ const rule: GraphQLESLintRule<NamingConventionRuleConfig> = {
135
165
suffix : {
136
166
type : 'string' ,
137
167
} ,
168
+ forbiddenPrefixes : {
169
+ additionalItems : false ,
170
+ type : 'array' ,
171
+ minItems : 1 ,
172
+ items : {
173
+ type : 'string' ,
174
+ } ,
175
+ } ,
176
+ forbiddenSuffixes : {
177
+ additionalItems : false ,
178
+ type : 'array' ,
179
+ minItems : 1 ,
180
+ items : {
181
+ type : 'string' ,
182
+ } ,
183
+ } ,
138
184
} ,
139
185
} ,
140
186
} ,
@@ -154,6 +200,7 @@ const rule: GraphQLESLintRule<NamingConventionRuleConfig> = {
154
200
[ Kind . SCALAR_TYPE_DEFINITION as string ] : schemaOption ,
155
201
[ Kind . OPERATION_DEFINITION as string ] : schemaOption ,
156
202
[ Kind . FRAGMENT_DEFINITION as string ] : schemaOption ,
203
+ QueryDefinition : schemaOption ,
157
204
leadingUnderscore : {
158
205
type : 'string' ,
159
206
enum : [ 'allow' , 'forbid' ] ,
@@ -175,14 +222,17 @@ const rule: GraphQLESLintRule<NamingConventionRuleConfig> = {
175
222
...( context . options [ 0 ] || { } ) ,
176
223
} ;
177
224
178
- const checkNode = ( node , style , nodeType , suffix = '' , prefix = '' ) => {
225
+ const checkNode = ( node , property : PropertySchema , nodeType : string ) => {
226
+ const { style, suffix = '' , prefix = '' , forbiddenPrefixes = [ ] , forbiddenSuffixes = [ ] } = property ;
179
227
const result = checkNameFormat ( {
180
228
value : node . value ,
181
229
style,
182
230
leadingUnderscore : options . leadingUnderscore ,
183
231
trailingUnderscore : options . trailingUnderscore ,
184
232
prefix : prefix ,
185
233
suffix : suffix ,
234
+ forbiddenPrefixes : forbiddenPrefixes ,
235
+ forbiddenSuffixes : forbiddenSuffixes ,
186
236
} ) ;
187
237
if ( result . ok === false ) {
188
238
context . report ( {
@@ -192,6 +242,8 @@ const rule: GraphQLESLintRule<NamingConventionRuleConfig> = {
192
242
prefix : prefix ,
193
243
suffix : suffix ,
194
244
format : style ,
245
+ forbiddenPrefixes : forbiddenPrefixes . join ( ', ' ) ,
246
+ forbiddenSuffixes : forbiddenSuffixes . join ( ', ' ) ,
195
247
nodeType,
196
248
nodeName : node . value ,
197
249
} ,
@@ -210,6 +262,12 @@ const rule: GraphQLESLintRule<NamingConventionRuleConfig> = {
210
262
} ;
211
263
} ;
212
264
265
+ const isQueryType = ( node ) : boolean => {
266
+ return (
267
+ ( node . type === 'ObjectTypeDefinition' || node . type === 'ObjectTypeExtension' ) && node . name . value === 'Query'
268
+ ) ;
269
+ } ;
270
+
213
271
return {
214
272
Name : node => {
215
273
if ( node . value . startsWith ( '_' ) && options . leadingUnderscore === 'forbid' ) {
@@ -225,61 +283,66 @@ const rule: GraphQLESLintRule<NamingConventionRuleConfig> = {
225
283
ObjectTypeDefinition : node => {
226
284
if ( options . ObjectTypeDefinition ) {
227
285
const property = normalisePropertyOption ( options . ObjectTypeDefinition ) ;
228
- checkNode ( node . name , property . style , 'Type' , property . suffix , property . prefix ) ;
286
+ checkNode ( node . name , property , 'Type' ) ;
229
287
}
230
288
} ,
231
289
InterfaceTypeDefinition : node => {
232
290
if ( options . InterfaceTypeDefinition ) {
233
291
const property = normalisePropertyOption ( options . InterfaceTypeDefinition ) ;
234
- checkNode ( node . name , property . style , 'Interface' , property . suffix , property . prefix ) ;
292
+ checkNode ( node . name , property , 'Interface' ) ;
235
293
}
236
294
} ,
237
295
EnumTypeDefinition : node => {
238
296
if ( options . EnumTypeDefinition ) {
239
297
const property = normalisePropertyOption ( options . EnumTypeDefinition ) ;
240
- checkNode ( node . name , property . style , 'Enumerator' , property . suffix , property . prefix ) ;
298
+ checkNode ( node . name , property , 'Enumerator' ) ;
241
299
}
242
300
} ,
243
301
InputObjectTypeDefinition : node => {
244
302
if ( options . InputObjectTypeDefinition ) {
245
303
const property = normalisePropertyOption ( options . InputObjectTypeDefinition ) ;
246
- checkNode ( node . name , property . style , 'Input type' , property . suffix , property . prefix ) ;
304
+ checkNode ( node . name , property , 'Input type' ) ;
247
305
}
248
306
} ,
249
- FieldDefinition : node => {
250
- if ( options . FieldDefinition ) {
307
+ FieldDefinition : ( node : any ) => {
308
+ if ( options . QueryDefinition && isQueryType ( node . parent ) ) {
309
+ const property = normalisePropertyOption ( options . QueryDefinition ) ;
310
+ checkNode ( node . name , property , 'Query' ) ;
311
+ }
312
+
313
+ if ( options . FieldDefinition && ! isQueryType ( node . parent ) ) {
251
314
const property = normalisePropertyOption ( options . FieldDefinition ) ;
252
- checkNode ( node . name , property . style , 'Field' , property . suffix , property . prefix ) ;
315
+ checkNode ( node . name , property , 'Field' ) ;
253
316
}
254
317
} ,
255
318
EnumValueDefinition : node => {
256
319
if ( options . EnumValueDefinition ) {
257
320
const property = normalisePropertyOption ( options . EnumValueDefinition ) ;
258
- checkNode ( node . name , property . style , 'Enumeration value' , property . suffix , property . prefix ) ;
321
+ checkNode ( node . name , property , 'Enumeration value' ) ;
259
322
}
260
323
} ,
261
324
InputValueDefinition : node => {
262
325
if ( options . InputValueDefinition ) {
263
326
const property = normalisePropertyOption ( options . InputValueDefinition ) ;
264
- checkNode ( node . name , property . style , 'Input property' , property . suffix , property . prefix ) ;
327
+ checkNode ( node . name , property , 'Input property' ) ;
265
328
}
266
329
} ,
267
330
FragmentDefinition : node => {
268
331
if ( options . FragmentDefinition ) {
269
332
const property = normalisePropertyOption ( options . FragmentDefinition ) ;
270
- checkNode ( node . name , property . style , 'Fragment' , property . suffix , property . prefix ) ;
333
+ checkNode ( node . name , property , 'Fragment' ) ;
271
334
}
272
335
} ,
273
336
ScalarTypeDefinition : node => {
274
337
if ( options . ScalarTypeDefinition ) {
275
338
const property = normalisePropertyOption ( options . ScalarTypeDefinition ) ;
276
- checkNode ( node . name , property . style , 'Scalar' , property . suffix , property . prefix ) ;
339
+ checkNode ( node . name , property , 'Scalar' ) ;
277
340
}
278
341
} ,
279
342
UnionTypeDefinition : node => {
280
343
if ( options . UnionTypeDefinition ) {
281
344
const property = normalisePropertyOption ( options . UnionTypeDefinition ) ;
282
- checkNode ( node . name , property . style , 'Scalar' , property . suffix , property . prefix ) ;
345
+ checkNode ( node . name , property , 'Union' ) ;
283
346
}
284
347
} ,
285
348
} ;
0 commit comments