@@ -22,9 +22,20 @@ interface CheckNameFormatParams {
2222 trailingUnderscore : 'allow' | 'forbid' ;
2323 prefix : string ;
2424 suffix : string ;
25+ forbiddenPrefixes : string [ ] ;
26+ forbiddenSuffixes : string [ ] ;
2527}
2628function 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 ;
2839 let name = value ;
2940 if ( leadingUnderscore === 'allow' ) {
3041 [ , name ] = name . match ( / ^ _ * ( .* ) $ / ) ;
@@ -46,6 +57,22 @@ function checkNameFormat(params: CheckNameFormatParams): { ok: false; errorMessa
4657 ) } `,
4758 } ;
4859 }
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+
4976 if ( ! formats [ style ] ) {
5077 return { ok : true } ;
5178 }
@@ -64,12 +91,15 @@ interface PropertySchema {
6491 style ?: ValidNaming ;
6592 suffix ?: string ;
6693 prefix ?: string ;
94+ forbiddenPrefixes ?: string [ ] ;
95+ forbiddenSuffixes ?: string [ ] ;
6796}
6897
6998type NamingConventionRuleConfig = [
7099 {
71100 leadingUnderscore ?: 'allow' | 'forbid' ;
72101 trailingUnderscore ?: 'allow' | 'forbid' ;
102+ QueryDefinition ?: ValidNaming | PropertySchema ;
73103 [ Kind . FIELD_DEFINITION ] ?: ValidNaming | PropertySchema ;
74104 [ Kind . ENUM_VALUE_DEFINITION ] ?: ValidNaming | PropertySchema ;
75105 [ Kind . INPUT_VALUE_DEFINITION ] ?: ValidNaming | PropertySchema ;
@@ -135,6 +165,22 @@ const rule: GraphQLESLintRule<NamingConventionRuleConfig> = {
135165 suffix : {
136166 type : 'string' ,
137167 } ,
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+ } ,
138184 } ,
139185 } ,
140186 } ,
@@ -154,6 +200,7 @@ const rule: GraphQLESLintRule<NamingConventionRuleConfig> = {
154200 [ Kind . SCALAR_TYPE_DEFINITION as string ] : schemaOption ,
155201 [ Kind . OPERATION_DEFINITION as string ] : schemaOption ,
156202 [ Kind . FRAGMENT_DEFINITION as string ] : schemaOption ,
203+ QueryDefinition : schemaOption ,
157204 leadingUnderscore : {
158205 type : 'string' ,
159206 enum : [ 'allow' , 'forbid' ] ,
@@ -175,14 +222,17 @@ const rule: GraphQLESLintRule<NamingConventionRuleConfig> = {
175222 ...( context . options [ 0 ] || { } ) ,
176223 } ;
177224
178- const checkNode = ( node , style , nodeType , suffix = '' , prefix = '' ) => {
225+ const checkNode = ( node , property : PropertySchema , nodeType : string ) => {
226+ const { style, suffix = '' , prefix = '' , forbiddenPrefixes = [ ] , forbiddenSuffixes = [ ] } = property ;
179227 const result = checkNameFormat ( {
180228 value : node . value ,
181229 style,
182230 leadingUnderscore : options . leadingUnderscore ,
183231 trailingUnderscore : options . trailingUnderscore ,
184232 prefix : prefix ,
185233 suffix : suffix ,
234+ forbiddenPrefixes : forbiddenPrefixes ,
235+ forbiddenSuffixes : forbiddenSuffixes ,
186236 } ) ;
187237 if ( result . ok === false ) {
188238 context . report ( {
@@ -192,6 +242,8 @@ const rule: GraphQLESLintRule<NamingConventionRuleConfig> = {
192242 prefix : prefix ,
193243 suffix : suffix ,
194244 format : style ,
245+ forbiddenPrefixes : forbiddenPrefixes . join ( ', ' ) ,
246+ forbiddenSuffixes : forbiddenSuffixes . join ( ', ' ) ,
195247 nodeType,
196248 nodeName : node . value ,
197249 } ,
@@ -210,6 +262,12 @@ const rule: GraphQLESLintRule<NamingConventionRuleConfig> = {
210262 } ;
211263 } ;
212264
265+ const isQueryType = ( node ) : boolean => {
266+ return (
267+ ( node . type === 'ObjectTypeDefinition' || node . type === 'ObjectTypeExtension' ) && node . name . value === 'Query'
268+ ) ;
269+ } ;
270+
213271 return {
214272 Name : node => {
215273 if ( node . value . startsWith ( '_' ) && options . leadingUnderscore === 'forbid' ) {
@@ -225,61 +283,66 @@ const rule: GraphQLESLintRule<NamingConventionRuleConfig> = {
225283 ObjectTypeDefinition : node => {
226284 if ( options . ObjectTypeDefinition ) {
227285 const property = normalisePropertyOption ( options . ObjectTypeDefinition ) ;
228- checkNode ( node . name , property . style , 'Type' , property . suffix , property . prefix ) ;
286+ checkNode ( node . name , property , 'Type' ) ;
229287 }
230288 } ,
231289 InterfaceTypeDefinition : node => {
232290 if ( options . InterfaceTypeDefinition ) {
233291 const property = normalisePropertyOption ( options . InterfaceTypeDefinition ) ;
234- checkNode ( node . name , property . style , 'Interface' , property . suffix , property . prefix ) ;
292+ checkNode ( node . name , property , 'Interface' ) ;
235293 }
236294 } ,
237295 EnumTypeDefinition : node => {
238296 if ( options . EnumTypeDefinition ) {
239297 const property = normalisePropertyOption ( options . EnumTypeDefinition ) ;
240- checkNode ( node . name , property . style , 'Enumerator' , property . suffix , property . prefix ) ;
298+ checkNode ( node . name , property , 'Enumerator' ) ;
241299 }
242300 } ,
243301 InputObjectTypeDefinition : node => {
244302 if ( options . InputObjectTypeDefinition ) {
245303 const property = normalisePropertyOption ( options . InputObjectTypeDefinition ) ;
246- checkNode ( node . name , property . style , 'Input type' , property . suffix , property . prefix ) ;
304+ checkNode ( node . name , property , 'Input type' ) ;
247305 }
248306 } ,
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 ) ) {
251314 const property = normalisePropertyOption ( options . FieldDefinition ) ;
252- checkNode ( node . name , property . style , 'Field' , property . suffix , property . prefix ) ;
315+ checkNode ( node . name , property , 'Field' ) ;
253316 }
254317 } ,
255318 EnumValueDefinition : node => {
256319 if ( options . EnumValueDefinition ) {
257320 const property = normalisePropertyOption ( options . EnumValueDefinition ) ;
258- checkNode ( node . name , property . style , 'Enumeration value' , property . suffix , property . prefix ) ;
321+ checkNode ( node . name , property , 'Enumeration value' ) ;
259322 }
260323 } ,
261324 InputValueDefinition : node => {
262325 if ( options . InputValueDefinition ) {
263326 const property = normalisePropertyOption ( options . InputValueDefinition ) ;
264- checkNode ( node . name , property . style , 'Input property' , property . suffix , property . prefix ) ;
327+ checkNode ( node . name , property , 'Input property' ) ;
265328 }
266329 } ,
267330 FragmentDefinition : node => {
268331 if ( options . FragmentDefinition ) {
269332 const property = normalisePropertyOption ( options . FragmentDefinition ) ;
270- checkNode ( node . name , property . style , 'Fragment' , property . suffix , property . prefix ) ;
333+ checkNode ( node . name , property , 'Fragment' ) ;
271334 }
272335 } ,
273336 ScalarTypeDefinition : node => {
274337 if ( options . ScalarTypeDefinition ) {
275338 const property = normalisePropertyOption ( options . ScalarTypeDefinition ) ;
276- checkNode ( node . name , property . style , 'Scalar' , property . suffix , property . prefix ) ;
339+ checkNode ( node . name , property , 'Scalar' ) ;
277340 }
278341 } ,
279342 UnionTypeDefinition : node => {
280343 if ( options . UnionTypeDefinition ) {
281344 const property = normalisePropertyOption ( options . UnionTypeDefinition ) ;
282- checkNode ( node . name , property . style , 'Scalar' , property . suffix , property . prefix ) ;
345+ checkNode ( node . name , property , 'Union' ) ;
283346 }
284347 } ,
285348 } ;
0 commit comments