@@ -12,11 +12,14 @@ import { Immutability } from "is-immutable-type";
12
12
13
13
import {
14
14
type IgnoreClassesOption ,
15
+ type OverridableOptions ,
16
+ getCoreOptions ,
15
17
ignoreClassesOptionSchema ,
16
18
shouldIgnoreClasses ,
17
19
shouldIgnoreInFunction ,
18
20
shouldIgnorePattern ,
19
21
} from "#eslint-plugin-functional/options" ;
22
+ import { typeSpecifiersSchema } from "#eslint-plugin-functional/utils/common-schemas" ;
20
23
import { ruleNameScope } from "#eslint-plugin-functional/utils/misc" ;
21
24
import { type ESFunctionType } from "#eslint-plugin-functional/utils/node-types" ;
22
25
import {
@@ -55,7 +58,8 @@ export const fullName = `${ruleNameScope}/${name}`;
55
58
type RawEnforcement =
56
59
| Exclude < Immutability | keyof typeof Immutability , "Unknown" | "Mutable" >
57
60
| "None"
58
- | false ;
61
+ | false
62
+ | undefined ;
59
63
60
64
type Option = IgnoreClassesOption & {
61
65
enforcement : RawEnforcement ;
@@ -64,6 +68,20 @@ type Option = IgnoreClassesOption & {
64
68
ignoreTypePattern ?: string [ ] | string ;
65
69
} ;
66
70
71
+ type CoreOptions = Option & {
72
+ parameters ?: Partial < Option > | RawEnforcement ;
73
+ returnTypes ?: Partial < Option > | RawEnforcement ;
74
+ variables ?:
75
+ | Partial <
76
+ Option & {
77
+ ignoreInFunctions ?: boolean ;
78
+ }
79
+ >
80
+ | RawEnforcement ;
81
+ fixer ?: FixerConfigRawMap ;
82
+ suggestions ?: SuggestionConfigRawMap ;
83
+ } ;
84
+
67
85
type FixerConfigRaw = {
68
86
pattern : string ;
69
87
replace : string ;
@@ -93,21 +111,7 @@ type SuggestionsConfig = FixerConfig[];
93
111
/**
94
112
* The options this rule can take.
95
113
*/
96
- type Options = [
97
- Option & {
98
- parameters ?: Partial < Option > | RawEnforcement ;
99
- returnTypes ?: Partial < Option > | RawEnforcement ;
100
- variables ?:
101
- | Partial <
102
- Option & {
103
- ignoreInFunctions ?: boolean ;
104
- }
105
- >
106
- | RawEnforcement ;
107
- fixer ?: FixerConfigRawMap ;
108
- suggestions ?: SuggestionConfigRawMap ;
109
- } ,
110
- ] ;
114
+ type Options = [ OverridableOptions < CoreOptions > ] ;
111
115
112
116
/**
113
117
* The enum options for the level of enforcement.
@@ -211,51 +215,75 @@ const suggestionsSchema: JSONSchema4 = {
211
215
} ,
212
216
} ;
213
217
218
+ const coreOptionsPropertiesSchema : JSONSchema4ObjectSchema [ "properties" ] = {
219
+ parameters : optionSchema ,
220
+ returnTypes : optionSchema ,
221
+ variables : {
222
+ oneOf : [
223
+ {
224
+ type : "object" ,
225
+ properties : deepmerge ( optionExpandedSchema , {
226
+ ignoreInFunctions : {
227
+ type : "boolean" ,
228
+ } ,
229
+ } ) ,
230
+ additionalProperties : false ,
231
+ } ,
232
+ {
233
+ type : [ "string" , "number" , "boolean" ] ,
234
+ enum : enforcementEnumOptions ,
235
+ } ,
236
+ ] ,
237
+ } ,
238
+ fixer : {
239
+ type : "object" ,
240
+ properties : {
241
+ ReadonlyShallow : fixerSchema ,
242
+ ReadonlyDeep : fixerSchema ,
243
+ Immutable : fixerSchema ,
244
+ } ,
245
+ additionalProperties : false ,
246
+ } ,
247
+ suggestions : {
248
+ type : "object" ,
249
+ properties : {
250
+ ReadonlyShallow : suggestionsSchema ,
251
+ ReadonlyDeep : suggestionsSchema ,
252
+ Immutable : suggestionsSchema ,
253
+ } ,
254
+ additionalProperties : false ,
255
+ } ,
256
+ } ;
257
+
214
258
/**
215
259
* The schema for the rule options.
216
260
*/
217
261
const schema : JSONSchema4 [ ] = [
218
262
{
219
263
type : "object" ,
220
- properties : deepmerge ( optionExpandedSchema , {
221
- parameters : optionSchema ,
222
- returnTypes : optionSchema ,
223
- variables : {
224
- oneOf : [
225
- {
226
- type : "object" ,
227
- properties : deepmerge ( optionExpandedSchema , {
228
- ignoreInFunctions : {
229
- type : "boolean" ,
230
- } ,
231
- } ) ,
232
- additionalProperties : false ,
233
- } ,
234
- {
235
- type : [ "string" , "number" , "boolean" ] ,
236
- enum : enforcementEnumOptions ,
264
+ properties : deepmerge ( optionExpandedSchema , coreOptionsPropertiesSchema , {
265
+ overrides : {
266
+ type : "array" ,
267
+ items : {
268
+ type : "object" ,
269
+ properties : {
270
+ specifiers : typeSpecifiersSchema ,
271
+ options : {
272
+ type : "object" ,
273
+ properties : deepmerge (
274
+ optionExpandedSchema ,
275
+ coreOptionsPropertiesSchema ,
276
+ ) ,
277
+ additionalProperties : false ,
278
+ } ,
279
+ disable : {
280
+ type : "boolean" ,
281
+ } ,
237
282
} ,
238
- ] ,
239
- } ,
240
- fixer : {
241
- type : "object" ,
242
- properties : {
243
- ReadonlyShallow : fixerSchema ,
244
- ReadonlyDeep : fixerSchema ,
245
- Immutable : fixerSchema ,
246
- } ,
247
- additionalProperties : false ,
248
- } ,
249
- suggestions : {
250
- type : "object" ,
251
- properties : {
252
- ReadonlyShallow : suggestionsSchema ,
253
- ReadonlyDeep : suggestionsSchema ,
254
- Immutable : suggestionsSchema ,
283
+ additionalProperties : false ,
255
284
} ,
256
- additionalProperties : false ,
257
285
} ,
258
- } ) ,
286
+ } satisfies JSONSchema4ObjectSchema [ "properties" ] ) ,
259
287
additionalProperties : false ,
260
288
} ,
261
289
] ;
@@ -398,7 +426,7 @@ function getConfiguredSuggestionFixers(
398
426
* Get the level of enforcement from the raw value given.
399
427
*/
400
428
function parseEnforcement ( rawEnforcement : RawEnforcement ) {
401
- return rawEnforcement === "None"
429
+ return rawEnforcement === "None" || rawEnforcement === undefined
402
430
? false
403
431
: typeof rawEnforcement === "string"
404
432
? Immutability [ rawEnforcement ]
@@ -454,35 +482,32 @@ function parseSuggestionsConfigs(
454
482
function getParameterTypeViolations (
455
483
node : ESFunctionType ,
456
484
context : Readonly < RuleContext < keyof typeof errorMessages , Options > > ,
457
- options : Readonly < Options > ,
485
+ options : Readonly < CoreOptions > ,
458
486
) : Descriptor [ ] {
459
- const [ optionsObject ] = options ;
460
487
const {
461
488
parameters : rawOption ,
462
489
fixer : rawFixerConfig ,
463
490
suggestions : rawSuggestionsConfigs ,
464
- } = optionsObject ;
491
+ } = options ;
465
492
const {
466
493
enforcement : rawEnforcement ,
467
494
ignoreInferredTypes,
468
495
ignoreClasses,
469
496
ignoreNamePattern,
470
497
ignoreTypePattern,
471
498
} = {
472
- ignoreInferredTypes : optionsObject . ignoreInferredTypes ,
473
- ignoreClasses : optionsObject . ignoreClasses ,
474
- ignoreNamePattern : optionsObject . ignoreNamePattern ,
475
- ignoreTypePattern : optionsObject . ignoreTypePattern ,
499
+ ignoreInferredTypes : options . ignoreInferredTypes ,
500
+ ignoreClasses : options . ignoreClasses ,
501
+ ignoreNamePattern : options . ignoreNamePattern ,
502
+ ignoreTypePattern : options . ignoreTypePattern ,
476
503
...( typeof rawOption === "object"
477
504
? rawOption
478
505
: {
479
506
enforcement : rawOption ,
480
507
} ) ,
481
508
} ;
482
509
483
- const enforcement = parseEnforcement (
484
- rawEnforcement ?? optionsObject . enforcement ,
485
- ) ;
510
+ const enforcement = parseEnforcement ( rawEnforcement ?? options . enforcement ) ;
486
511
if (
487
512
enforcement === false ||
488
513
shouldIgnoreClasses ( node , context , ignoreClasses )
@@ -592,31 +617,28 @@ function getParameterTypeViolations(
592
617
function getReturnTypeViolations (
593
618
node : ESFunctionType ,
594
619
context : Readonly < RuleContext < keyof typeof errorMessages , Options > > ,
595
- options : Readonly < Options > ,
620
+ options : Readonly < CoreOptions > ,
596
621
) : Descriptor [ ] {
597
- const [ optionsObject ] = options ;
598
622
const {
599
623
returnTypes : rawOption ,
600
624
fixer : rawFixerConfig ,
601
625
suggestions : rawSuggestionsConfigs ,
602
- } = optionsObject ;
626
+ } = options ;
603
627
const {
604
628
enforcement : rawEnforcement ,
605
629
ignoreInferredTypes,
606
630
ignoreClasses,
607
631
ignoreNamePattern,
608
632
ignoreTypePattern,
609
633
} = {
610
- ignoreInferredTypes : optionsObject . ignoreInferredTypes ,
611
- ignoreClasses : optionsObject . ignoreClasses ,
612
- ignoreNamePattern : optionsObject . ignoreNamePattern ,
613
- ignoreTypePattern : optionsObject . ignoreTypePattern ,
634
+ ignoreInferredTypes : options . ignoreInferredTypes ,
635
+ ignoreClasses : options . ignoreClasses ,
636
+ ignoreNamePattern : options . ignoreNamePattern ,
637
+ ignoreTypePattern : options . ignoreTypePattern ,
614
638
...( typeof rawOption === "object" ? rawOption : { enforcement : rawOption } ) ,
615
639
} ;
616
640
617
- const enforcement = parseEnforcement (
618
- rawEnforcement ?? optionsObject . enforcement ,
619
- ) ;
641
+ const enforcement = parseEnforcement ( rawEnforcement ?? options . enforcement ) ;
620
642
621
643
if (
622
644
enforcement === false ||
@@ -743,10 +765,19 @@ function checkFunction(
743
765
context : Readonly < RuleContext < keyof typeof errorMessages , Options > > ,
744
766
options : Readonly < Options > ,
745
767
) : RuleResult < keyof typeof errorMessages , Options > {
746
- const descriptors = [
747
- ...getParameterTypeViolations ( node , context , options ) ,
748
- ...getReturnTypeViolations ( node , context , options ) ,
749
- ] ;
768
+ const optionsToUse = getCoreOptions < CoreOptions , Options > (
769
+ node ,
770
+ context ,
771
+ options ,
772
+ ) ;
773
+
774
+ const descriptors =
775
+ optionsToUse === null
776
+ ? [ ]
777
+ : [
778
+ ...getParameterTypeViolations ( node , context , optionsToUse ) ,
779
+ ...getReturnTypeViolations ( node , context , optionsToUse ) ,
780
+ ] ;
750
781
751
782
return {
752
783
context,
@@ -762,13 +793,24 @@ function checkVariable(
762
793
context : Readonly < RuleContext < keyof typeof errorMessages , Options > > ,
763
794
options : Readonly < Options > ,
764
795
) : RuleResult < keyof typeof errorMessages , Options > {
765
- const [ optionsObject ] = options ;
796
+ const optionsToUse = getCoreOptions < CoreOptions , Options > (
797
+ node ,
798
+ context ,
799
+ options ,
800
+ ) ;
801
+
802
+ if ( optionsToUse === null ) {
803
+ return {
804
+ context,
805
+ descriptors : [ ] ,
806
+ } ;
807
+ }
766
808
767
809
const {
768
810
variables : rawOption ,
769
811
fixer : rawFixerConfig ,
770
812
suggestions : rawSuggestionsConfigs ,
771
- } = optionsObject ;
813
+ } = optionsToUse ;
772
814
const {
773
815
enforcement : rawEnforcement ,
774
816
ignoreInferredTypes,
@@ -777,16 +819,16 @@ function checkVariable(
777
819
ignoreTypePattern,
778
820
ignoreInFunctions,
779
821
} = {
780
- ignoreInferredTypes : optionsObject . ignoreInferredTypes ,
781
- ignoreClasses : optionsObject . ignoreClasses ,
782
- ignoreNamePattern : optionsObject . ignoreNamePattern ,
783
- ignoreTypePattern : optionsObject . ignoreTypePattern ,
822
+ ignoreInferredTypes : optionsToUse . ignoreInferredTypes ,
823
+ ignoreClasses : optionsToUse . ignoreClasses ,
824
+ ignoreNamePattern : optionsToUse . ignoreNamePattern ,
825
+ ignoreTypePattern : optionsToUse . ignoreTypePattern ,
784
826
ignoreInFunctions : false ,
785
827
...( typeof rawOption === "object" ? rawOption : { enforcement : rawOption } ) ,
786
828
} ;
787
829
788
830
const enforcement = parseEnforcement (
789
- rawEnforcement ?? optionsObject . enforcement ,
831
+ rawEnforcement ?? optionsToUse . enforcement ,
790
832
) ;
791
833
792
834
if (
0 commit comments