1package stylelint
2
3import (
4 "list"
5 "net"
6)
7
8// JSON schema for the Stylelint configuration files
9#Schema: {
10 @jsonschema(schema="http://json-schema.org/draft-07/schema#")
11 @jsonschema(id="https://json.schemastore.org/stylelintrc.json")
12 "extends"?: #simpleStringOrArrayStringRule
13 "plugins"?: #simpleArrayStringRule
14
15 // Specify a custom syntax to use on your code.
16 "customSyntax"?: string
17
18 // Provide rule and behavior overrides for files that match particular glob patterns.
19 "overrides"?: [...{
20 "files"?: [...string]
21 "customSyntax"?: string
22 "rules"?: #allRules
23 ...
24 }]
25
26 // Processors are functions that hook into stylelint's pipeline, modifying code
27 // on its way into stylelint and modifying results on their way out
28 "processors"?: [...matchN(>=1, [
29 string,
30 {
31 [...]
32 [0]: string
33 [>=1]: {...}
34 }
35 ])]
36
37 // Ignore stylelint-disable (e.g. /* stylelint-disable block-no-empty */) comments.
38 "ignoreDisables"?: bool
39 "ignoreFiles"?: #simpleStringOrArrayStringRule
40
41 // The default severity level for all rules that do not have a severity
42 // specified in their secondary options
43 "defaultSeverity"?: "warning" | "error"
44 "reportDescriptionlessDisables"?: #booleanRule
45 "reportInvalidScopeDisables"?: #booleanRule
46 "reportNeedlessDisables"?: #booleanRule
47 "rules"?: #allRules
48 ...
49
50 #allRules: matchN(30, [
51 #atRule & {...},
52 #block & {...},
53 #color & {...},
54 #comment & {...},
55 #customMedia & {...},
56 #customProperty & {...},
57 #declaration & {...},
58 #declarationBlock & {...},
59 #font & {...},
60 #function & {...},
61 #generalSheet & {...},
62 #keyframeDeclaration & {...},
63 #length & {...},
64 #lightness & {...},
65 #mediaFeature & {...},
66 #mediaQuery & {...},
67 #mediaQueryList & {...},
68 #number & {...},
69 #property & {...},
70 #rootRule & {...},
71 #rule & {...},
72 #selector & {...},
73 #selectorList & {...},
74 #shorthandProperty & {...},
75 #string & {...},
76 #stylelintDisableComment & {...},
77 #time & {...},
78 #unit & {...},
79 #value & {...},
80 #valueList & {...}
81 ])
82
83 #alwaysMultiLineRule: matchN(1, [
84 null,
85 "always" | "always-multi-line",
86 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
87 ...matchN(>=1, ["always" | "always-multi-line", #coreRule & (string | {...})])
88 ]
89 ])
90
91 #alwaysNeverRule: matchN(1, [
92 null,
93 "always" | "never",
94 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
95 ...matchN(>=1, ["always" | "never", #coreRule & (string | {...})])
96 ]
97 ])
98
99 #arrayStringRule: matchN(1, [
100 null | string,
101 list.MinItems(1) & list.UniqueItems() & [
102 ...matchN(>=1, [#simpleArrayStringRule & (string | [...] | {...}), #coreRule & (string | [...] | {...})])
103 ]
104 ])
105
106 #atRule: null | bool | number | string | [...] | {
107 "at-rule-blacklist"?: #arrayStringRule
108
109 // Require or disallow an empty line before at-rules
110 "at-rule-empty-line-before"?: matchN(1, [
111 null,
112 "always" | "never",
113 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
114 "always" | "never",
115 #coreRule & {...} & {
116 "except"?: list.UniqueItems() & list.MinItems(1) & [
117 ..."all-nested" |
118 "after-same-name" |
119 "inside-block" |
120 "blockless-after-same-name-blockless" |
121 "blockless-after-blockless" |
122 "first-nested"
123 ]
124 "ignore"?: list.UniqueItems() & list.MinItems(1) & [
125 ..."after-comment" |
126 "first-nested" |
127 "inside-block" |
128 "blockless-after-same-name-blockless" |
129 "blockless-after-blockless"
130 ]
131 "ignoreAtRules"?: #simpleStringOrArrayStringRule
132 ...
133 }
134 ])]
135 ])
136 "at-rule-name-case"?: #lowerUpperRule
137 "at-rule-name-newline-after"?: #alwaysMultiLineRule
138
139 // Require a single space after at-rule names
140 "at-rule-name-space-after"?: matchN(1, [
141 null,
142 "always" | "always-single-line",
143 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
144 ...matchN(>=1, ["always" | "always-single-line", #coreRule & (string | {...})])
145 ]
146 ])
147
148 // Disallow unknown at-rules
149 "at-rule-no-unknown"?: matchN(1, [
150 null,
151 true,
152 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
153 true,
154 #coreRule & {...} & {
155 "ignoreAtRules"?: #simpleArrayStringRule
156 ...
157 }
158 ])]
159 ])
160 "at-rule-no-vendor-prefix"?: #booleanRule
161
162 // Require a newline after the semicolon of at-rules
163 "at-rule-semicolon-newline-after"?: matchN(1, [
164 null,
165 "always",
166 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
167 ...matchN(>=1, ["always", #coreRule & (string | {...})])
168 ]
169 ])
170
171 // Require a single space or disallow whitespace before the semicolons of at-rules
172 "at-rule-semicolon-space-before"?: _
173 "at-rule-whitelist"?: #arrayStringRule
174 ...
175 }
176
177 #block: null | bool | number | string | [...] | {
178 // Require or disallow an empty line before the closing brace of blocks
179 "block-closing-brace-empty-line-before"?: matchN(1, [
180 null,
181 "always-multi-line" | "never",
182 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
183 ...matchN(>=1, ["always-multi-line" | "never", #coreRule & (string | {...})])
184 ]
185 ])
186 "block-closing-brace-newline-after"?: #newlineSpaceWithIgnoreRule
187 "block-closing-brace-newline-before"?: #newlineRule
188 "block-closing-brace-space-after"?: #newlineSpaceRule
189 "block-closing-brace-space-before"?: #newlineSpaceRule
190 "block-no-empty"?: #booleanRule
191 "block-no-single-line"?: #booleanRule
192 "block-opening-brace-newline-after"?: #newlineRule
193
194 // Require a newline or disallow whitespace before the opening brace of blocks
195 "block-opening-brace-newline-before"?: matchN(1, [
196 null,
197 "always" | "always-single-line" | "never-single-line" | "always-multi-line" | "never-multi-line",
198 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
199 ...matchN(>=1, [
200 "always" | "always-single-line" | "never-single-line" | "always-multi-line" | "never-multi-line",
201 #coreRule & (string | {...})
202 ])
203 ]
204 ])
205 "block-opening-brace-space-after"?: #newlineSpaceRule
206 "block-opening-brace-space-before"?: #newlineSpaceWithIgnoreRule
207 ...
208 }
209
210 #booleanRule: matchN(1, [
211 null,
212 bool,
213 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [bool, #coreRule & (bool | {...})])]
214 ])
215
216 #color: null | bool | number | string | [...] | {
217 "color-hex-case"?: #lowerUpperRule
218
219 // Specify short or long notation for hex colors
220 "color-hex-length"?: matchN(1, [
221 null,
222 "short" | "long",
223 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
224 ...matchN(>=1, ["short" | "long", #coreRule & (string | {...})])
225 ]
226 ])
227
228 // Require (where possible) or disallow named colors
229 "color-named"?: matchN(1, [
230 null,
231 "always-where-possible" | "never",
232 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
233 "always-where-possible" | "never",
234 #coreRule & {...} & {
235 "ignore"?: #simpleArrayStringRule
236 ...
237 }
238 ])]
239 ])
240 "color-no-hex"?: #booleanRule
241 "color-no-invalid-hex"?: #booleanRule
242 ...
243 }
244
245 #comment: null | bool | number | string | [...] | {
246 // Require or disallow an empty line before comments
247 "comment-empty-line-before"?: matchN(1, [
248 null,
249 "always" | "never",
250 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
251 "always" | "never",
252 #coreRule & {...} & {
253 // Reverse the primary option for comments that are nested and the first child of their parent node
254 "except"?: list.UniqueItems() & list.MinItems(1) & [..."first-nested"]
255
256 // Don't require an empty line between comments
257 "ignore"?: list.UniqueItems() & list.MinItems(1) & [
258 ..."between-comments" | "after-comment" | "stylelint-command" | "stylelint-commands"
259 ]
260 ...
261 }
262 ])]
263 ])
264 "comment-no-empty"?: #booleanRule
265 "comment-whitespace-inside"?: #alwaysNeverRule
266 "comment-word-blacklist"?: #arrayStringRule
267 ...
268 }
269
270 #coreRule: {
271 "disableFix"?: bool
272
273 // Custom message that will be used in errors and warnings
274 "message"?: string
275 "reportDisables"?: bool
276
277 // Message status
278 "severity"?: "warning" | "error"
279 "url"?: net.AbsURL
280 ...
281 }
282
283 #customMedia: null | bool | number | string | [...] | {
284 "custom-media-pattern"?: #stringRule
285
286 // Disallow unknown custom media queries
287 "no-unknown-custom-media"?: matchN(1, [
288 matchN(1, [true, null]),
289 list.MaxItems(2) & {
290 [matchN(1, [true, null]), ...]
291 [1]: #coreRule
292 }
293 ])
294 ...
295 }
296
297 #customProperty: null | bool | number | string | [...] | {
298 // Require or disallow an empty line before custom properties
299 "custom-property-empty-line-before"?: matchN(1, [
300 null,
301 "always" | "never",
302 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
303 "always" | "never",
304 #coreRule & {...} & {
305 // Reverse the primary option for custom properties that come after a comment,
306 // custom property or first child of their parent node
307 "except"?: list.UniqueItems() & list.MinItems(1) & [
308 ..."after-comment" | "after-custom-property" | "first-nested"
309 ]
310
311 // Ignore custom properties that are preceded by comments or inside single-line blocks
312 "ignore"?: list.UniqueItems() & list.MinItems(1) & [..."after-comment" | "inside-single-line-block"]
313 ...
314 }
315 ])]
316 ])
317 "custom-property-no-outside-root"?: #booleanRule
318 "custom-property-pattern"?: #stringRule
319
320 // Disallow unknown custom properties
321 "no-unknown-custom-properties"?: matchN(1, [
322 matchN(1, [true, null]),
323 list.MaxItems(2) & {
324 [matchN(1, [true, null]), ...]
325 [1]: #coreRule
326 }
327 ])
328 ...
329 }
330
331 #declaration: null | bool | number | string | [...] | {
332 "declaration-bang-space-after"?: #alwaysNeverRule
333 "declaration-bang-space-before"?: #alwaysNeverRule
334 "declaration-colon-newline-after"?: #alwaysMultiLineRule
335
336 // Require a single space or disallow whitespace after the colon of declarations
337 "declaration-colon-space-after"?: matchN(1, [
338 null,
339 "always" | "never" | "always-single-line",
340 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
341 ...matchN(>=1, ["always" | "never" | "always-single-line", #coreRule & (string | {...})])
342 ]
343 ])
344 "declaration-colon-space-before"?: #alwaysNeverRule
345
346 // Require or disallow an empty line before declarations
347 "declaration-empty-line-before"?: matchN(1, [
348 null,
349 "always" | "never",
350 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
351 "always" | "never",
352 #coreRule & {...} & {
353 "except"?: list.MinItems(1) & list.UniqueItems() & [
354 ..."after-comment" | "after-declaration" | "first-nested"
355 ]
356 "ignore"?: list.MinItems(1) & list.UniqueItems() & [
357 ..."after-comment" | "after-declaration" | "first-nested" | "inside-single-line-block"
358 ]
359 ...
360 }
361 ])]
362 ])
363 "declaration-no-important"?: #booleanRule
364 "declaration-property-unit-blacklist"?: #objectRule
365 "declaration-property-unit-whitelist"?: #objectRule
366 "declaration-property-value-blacklist"?: #objectRule
367
368 // Disallow unknown values for properties within declarations
369 "declaration-property-value-no-unknown"?: matchN(1, [
370 matchN(1, [true, null]),
371 list.MaxItems(2) & {
372 [matchN(1, [true, null]), ...]
373 [1]: #coreRule & {...} & {
374 "ignoreProperties"?: [string]: matchN(>=1, [matchN(1, [string, [...string]]), matchN(1, [
375 matchN(1, [{...}, =~"^\\/.+\\/i?$"]), [...matchN(>=1, [{...}, =~"^\\/.+\\/i?$"])],
376 ])])
377 "propertiesSyntax"?: [string]: matchN(1, [string, [...string]])
378 "typesSyntax"?: [string]: matchN(1, [string, [...string]])
379 ...
380 }
381 }
382 ])
383 "declaration-property-value-whitelist"?: #objectRule
384 ...
385 }
386
387 #declarationBlock: null | bool | number | string | [...] | {
388 // Disallow duplicate properties within declaration blocks
389 "declaration-block-no-duplicate-properties"?: matchN(1, [
390 null,
391 true,
392 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
393 true,
394 #coreRule & {...} & {
395 "ignore"?: list.MinItems(1) & list.UniqueItems() & [
396 ..."consecutive-duplicates" |
397 "consecutive-duplicates-with-different-values" |
398 "consecutive-duplicates-with-different-syntaxes" |
399 "consecutive-duplicates-with-same-prefixless-values"
400 ]
401 "ignoreProperties"?: #simpleArrayStringRule
402 ...
403 }
404 ])]
405 ])
406 "declaration-block-no-ignored-properties"?: #booleanRule
407
408 // Disallow longhand properties that can be combined into one shorthand property
409 "declaration-block-no-redundant-longhand-properties"?: matchN(1, [
410 null,
411 true,
412 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
413 true,
414 #coreRule & {...} & {
415 "ignoreShorthands"?: #simpleArrayStringRule
416 ...
417 }
418 ])]
419 ])
420 "declaration-block-no-shorthand-property-overrides"?: #booleanRule
421
422 // Specify the order of properties within declaration blocks
423 "declaration-block-properties-order"?: matchN(1, [
424 null,
425 "alphabetical",
426 list.MinItems(1) & list.UniqueItems() & [...matchN(>=1, [
427 "alphabetical",
428 string,
429 #simpleArrayStringRule & (string | [...] | {...}),
430 #coreRule & {...} & {
431 order?: _
432 if order != _|_ {
433 "properties"!: _
434 }
435 properties?: _
436 if properties != _|_ {
437 "order"!: _
438 }
439 {}
440
441 // These options only apply if you've defined your own array of properties
442 "unspecified"?: "top" | "bottom" | "bottomAlphabetical" | "ignore"
443 "order"?: "strict" | "flexible"
444 "properties"?: #simpleArrayStringRule
445 ...
446 }
447 ])]
448 ])
449 "declaration-block-semicolon-newline-after"?: #newlineRule
450 "declaration-block-semicolon-newline-before"?: #newlineRule
451 "declaration-block-semicolon-space-after"?: #spaceRule
452 "declaration-block-semicolon-space-before"?: #spaceRule
453 "declaration-block-single-line-max-declarations"?: #integerRule
454 "declaration-block-trailing-semicolon"?: #alwaysNeverRule
455 ...
456 }
457
458 #font: null | bool | number | string | [...] | {
459 // Specify whether or not quotation marks should be used around font family names
460 "font-family-name-quotes"?: matchN(1, [
461 null,
462 "always-where-required" | "always-where-recommended" | "always-unless-keyword",
463 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
464 ...matchN(>=1, [
465 "always-where-required" | "always-where-recommended" | "always-unless-keyword",
466 #coreRule & (string | {...})
467 ])
468 ]
469 ])
470
471 // Require numeric or named (where possible) `font-weight` values. Also, when
472 // named values are expected, require only valid names
473 "font-weight-notation"?: matchN(1, [
474 null,
475 "numeric" | "named-where-possible",
476 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
477 "numeric" | "named-where-possible",
478 #coreRule & {...} & {
479 "ignore"?: list.UniqueItems() & list.MinItems(1) & [..."relative"]
480 ...
481 }
482 ])]
483 ])
484 ...
485 }
486
487 #function: null | bool | number | string | [...] | {
488 "function-blacklist"?: #arrayStringRule
489 "function-calc-no-unspaced-operator"?: #booleanRule
490 "function-comma-newline-after"?: #newlineRule
491 "function-comma-newline-before"?: #newlineRule
492 "function-comma-space-after"?: #spaceRule
493 "function-comma-space-before"?: #spaceRule
494 "function-linear-gradient-no-nonstandard-direction"?: #booleanRule
495 "function-max-empty-lines"?: #integerRule
496
497 // Specify lowercase or uppercase for function names
498 "function-name-case"?: matchN(1, [
499 null,
500 "lower" | "upper",
501 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
502 "lower" | "upper",
503 #coreRule & {...} & {
504 "ignoreFunctions"?: #simpleArrayStringRule
505 ...
506 }
507 ])]
508 ])
509 "function-parentheses-newline-inside"?: #newlineRule
510 "function-parentheses-space-inside"?: #spaceRule
511 "function-url-data-uris"?: #alwaysNeverRule
512 "function-url-no-scheme-relative"?: #booleanRule
513 "function-url-quotes"?: #alwaysNeverRule
514 "function-url-scheme-whitelist"?: #arrayStringRule
515 "function-whitelist"?: #arrayStringRule
516 "function-whitespace-after"?: #alwaysNeverRule
517 ...
518 }
519
520 #generalSheet: null | bool | number | string | [...] | {
521 // Specify indentation
522 "indentation"?: matchN(1, [
523 null | int,
524 "tab",
525 list.MinItems(1) & list.UniqueItems() & [...int],
526 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
527 int,
528 "tab",
529 #coreRule & {...} & {
530 // If `true`, the closing brace of a block (rule or at-rule) will be expected at
531 // the same indentation level as the block's inner nodes
532 "indentInsideParens"?: "twice" | "once-at-root-twice-in-block"
533
534 // Do not indent for these things
535 "except"?: list.UniqueItems() & list.MinItems(1) & [..."block" | "param" | "value"]
536
537 // Ignore the indentation inside parentheses
538 "ignore"?: list.UniqueItems() & list.MinItems(1) & [..."inside-parens" | "param" | "value"]
539 ...
540 }
541 ]) &
542 (int | string | {...})]
543 ]) &
544 (null | int | string | [...])
545
546 // Specify unix or windows linebreaks
547 "linebreaks"?: _
548 "max-empty-lines"?: #integerRule
549
550 // Limit the length of a line
551 "max-line-length"?: matchN(1, [
552 null | int,
553 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
554 int,
555 #coreRule & {...} & {
556 "ignore"?: matchN(>=1, [
557 "non-comments" | "comments",
558 list.UniqueItems() & list.MinItems(1) & [..."non-comments" | "comments"],
559 ])
560 ...
561 }
562 ]) &
563 (int | {...})]
564 ]) &
565 (null | int | [...])
566
567 // Limit the allowed nesting depth
568 "max-nesting-depth"?: matchN(1, [
569 null | int,
570 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
571 int,
572 #coreRule & {...} & {
573 "ignore"?: list.UniqueItems() & list.MinItems(1) & [
574 ..."at-rules-without-declaration-blocks" | "blockless-at-rules" | "pseudo-classes"
575 ]
576 "ignoreAtRules"?: #simpleArrayStringRule
577 ...
578 }
579 ]) &
580 (int | {...})]
581 ]) &
582 (null | int | [...])
583
584 // Disallow browser hacks that are irrelevant to the browsers you are targeting
585 "no-browser-hacks"?: matchN(1, [
586 null,
587 true,
588 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
589 true,
590 #coreRule & {...} & {
591 "browsers"?: #simpleStringOrArrayStringRule
592 ...
593 }
594 ])]
595 ])
596 "no-descending-specificity"?: #booleanRule
597 "no-duplicate-selectors"?: #booleanRule
598
599 // Disallow empty first lines
600 "no-empty-first-line"?: _
601 "no-empty-source"?: #booleanRule
602
603 // Disallow end-of-line whitespace
604 "no-eol-whitespace"?: matchN(1, [
605 null,
606 true,
607 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
608 true,
609 #coreRule & {...} & {
610 "ignore"?: list.UniqueItems() & list.MinItems(1) & [..."empty-lines"]
611 ...
612 }
613 ])]
614 ])
615 "no-extra-semicolons"?: #booleanRule
616
617 // Disallow colors that are suspiciously close to being identical
618 "no-indistinguishable-colors"?: matchN(1, [
619 null,
620 true,
621 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
622 true,
623 #coreRule & {...} & {
624 "threshold"?: int & >=0 & <=100
625 "ignore"?: #simpleArrayStringRule
626
627 // An array of color pairs to ignore. Each pair is an array with two items
628 "whitelist"?: list.UniqueItems() & list.MinItems(1) & [...#simpleArrayStringRule]
629 ...
630 }
631 ])]
632 ])
633 "no-invalid-double-slash-comments"?: #booleanRule
634 "no-missing-end-of-source-newline"?: #booleanRule
635 "no-unknown-animations"?: #booleanRule
636 "unicode-bom"?: #alwaysNeverRule
637
638 // Disallow features that are unsupported by the browsers that you are targeting
639 "no-unsupported-browser-features"?: matchN(1, [
640 null,
641 true,
642 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
643 true,
644 #coreRule & {...} & {
645 "browsers"?: string
646 "ignore"?: #simpleStringOrArrayStringRule
647 ...
648 }
649 ])]
650 ])
651 ...
652 }
653
654 #integerRule: matchN(1, [
655 null | int,
656 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...#coreRule & (number | {...}) & (int | {...})]
657 ]) &
658 (null | int | [...])
659
660 #keyframeDeclaration: null | bool | number | string | [...] | {
661 "keyframe-declaration-no-important"?: #booleanRule
662 ...
663 }
664
665 #length: null | bool | number | string | [...] | {
666 "length-zero-no-unit"?: #booleanRule
667 ...
668 }
669
670 #lightness: null | bool | number | string | [...] | {
671 // Specify number or percentage notation for lightness
672 "lightness-notation"?: matchN(1, [
673 matchN(1, ["percentage" | "number", null]),
674 list.MaxItems(2) & {
675 [matchN(1, ["percentage" | "number", null]), ...]
676 [1]: #coreRule
677 }
678 ])
679 ...
680 }
681
682 #lowerUpperRule: matchN(1, [
683 null,
684 "lower" | "upper",
685 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
686 ...matchN(>=1, ["lower" | "upper", #coreRule & (string | {...})])
687 ]
688 ])
689
690 #mediaFeature: null | bool | number | string | [...] | {
691 "media-feature-colon-space-after"?: #alwaysNeverRule
692 "media-feature-colon-space-before"?: #alwaysNeverRule
693 "media-feature-name-case"?: #lowerUpperRule
694
695 // Disallow unknown media feature names
696 "media-feature-name-no-unknown"?: matchN(1, [
697 null,
698 true,
699 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
700 true,
701 #coreRule & {...} & {
702 "ignoreMediaFeatureNames"?: #simpleArrayStringRule
703 ...
704 }
705 ])]
706 ])
707
708 // Disallow unknown values for media features
709 "media-feature-name-value-no-unknown"?: matchN(1, [
710 matchN(1, [true, null]),
711 list.MaxItems(2) & {
712 [matchN(1, [true, null]), ...]
713 [1]: #coreRule
714 }
715 ])
716 "media-feature-name-no-vendor-prefix"?: #booleanRule
717
718 // Specify a list of allowed name and unit pairs within media features
719 "media-feature-name-unit-allowed-list"?: matchN(1, [
720 matchN(1, [{[string]: matchN(1, [string, [...string]])}, null]),
721 list.MaxItems(2) & {
722 [matchN(1, [{[string]: matchN(1, [string, [...string]])}, null]), ...]
723 [1]: #coreRule
724 }
725 ])
726 "media-feature-no-missing-punctuation"?: #booleanRule
727 "media-feature-parentheses-space-inside"?: #alwaysNeverRule
728
729 // Specify context or prefix notation for media feature ranges
730 "media-feature-range-notation"?: matchN(1, [
731 matchN(1, ["prefix" | "context", null]),
732 list.MaxItems(2) & {
733 [matchN(1, ["prefix" | "context", null]), ...]
734 [1]: #coreRule
735 }
736 ])
737 "media-feature-range-operator-space-after"?: #alwaysNeverRule
738 "media-feature-range-operator-space-before"?: #alwaysNeverRule
739 ...
740 }
741
742 #mediaQuery: null | bool | number | string | [...] | {
743 // Disallow invalid media queries
744 "media-query-no-invalid"?: matchN(1, [
745 matchN(1, [true, null]),
746 list.MaxItems(2) & {
747 [matchN(1, [true, null]), ...]
748 [1]: #coreRule
749 }
750 ])
751 ...
752 }
753
754 #mediaQueryList: null | bool | number | string | [...] | {
755 "media-query-list-comma-newline-after"?: #newlineRule
756 "media-query-list-comma-newline-before"?: #newlineRule
757 "media-query-list-comma-space-after"?: #spaceRule
758 "media-query-list-comma-space-before"?: #spaceRule
759 ...
760 }
761
762 #newlineRule: matchN(1, [
763 null,
764 "always" | "always-multi-line" | "never-multi-line",
765 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
766 ...matchN(>=1, ["always" | "always-multi-line" | "never-multi-line", #coreRule & (string | {...})])
767 ]
768 ])
769
770 #newlineSpaceRule: matchN(1, [
771 null,
772 "always" | "never" | "always-single-line" | "never-single-line" | "always-multi-line" | "never-multi-line",
773 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
774 ...matchN(>=1, [
775 "always" |
776 "never" |
777 "always-single-line" |
778 "never-single-line" |
779 "always-multi-line" |
780 "never-multi-line",
781 #coreRule & (string | {...})
782 ])
783 ]
784 ])
785
786 #newlineSpaceWithIgnoreRule: matchN(1, [
787 null,
788 "always" | "never" | "always-single-line" | "never-single-line" | "always-multi-line" | "never-multi-line",
789 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
790 "always" | "always-single-line" | "never-single-line" | "always-multi-line" | "never-multi-line",
791 #coreRule & {...} & {
792 "ignoreAtRules"?: #simpleStringOrArrayStringRule
793 ...
794 }
795 ])]
796 ])
797
798 #number: null | bool | number | string | [...] | {
799 "number-leading-zero"?: #alwaysNeverRule
800 "number-max-precision"?: #integerRule
801 "number-no-trailing-zeros"?: #booleanRule
802 ...
803 }
804
805 #objectRule: matchN(1, [
806 null,
807 {[string]: #simpleStringOrArrayStringRule},
808 list.MaxItems(2) & [{[string]: #simpleStringOrArrayStringRule}, #coreRule, ...],
809 ])
810
811 #property: null | bool | number | string | [...] | {
812 "property-blacklist"?: #arrayStringRule
813 "property-case"?: #lowerUpperRule
814
815 // Disallow unknown properties
816 "property-no-unknown"?: matchN(1, [
817 null,
818 true,
819 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
820 true,
821 #coreRule & {...} & {
822 "ignoreProperties"?: #simpleArrayStringRule
823
824 // If `true`, this rule will check vendor-prefixed properties
825 "checkPrefixed"?: bool
826 ...
827 }
828 ])]
829 ])
830 "property-no-vendor-prefix"?: #booleanRule
831 "property-whitelist"?: #arrayStringRule
832 ...
833 }
834
835 #rootRule: null | bool | number | string | [...] | {
836 "root-no-standard-properties"?: #booleanRule
837 ...
838 }
839
840 #rule: null | bool | number | string | [...] | {
841 // Require or disallow an empty line before nested rules
842 "rule-nested-empty-line-before"?: matchN(1, [
843 null,
844 "always" | "never" | "always-multi-line" | "never-multi-line",
845 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
846 "always" | "never" | "always-multi-line" | "never-multi-line",
847 #coreRule & {...} & {
848 // Reverse the primary option if the rule is the first in a block
849 "except"?: list.UniqueItems() & list.MinItems(1) & [..."first-nested"]
850
851 // Ignore rules that come after a comment
852 "ignore"?: list.UniqueItems() & list.MinItems(1) & [..."after-comment"]
853 ...
854 }
855 ])]
856 ])
857
858 // Require or disallow an empty line before non-nested rules
859 "rule-non-nested-empty-line-before"?: matchN(1, [
860 null,
861 "always" | "never" | "always-multi-line" | "never-multi-line",
862 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
863 "always" | "never" | "always-multi-line" | "never-multi-line",
864 #coreRule & {...} & {
865 // Reverse the primary option if the rule is the first in a block
866 "except"?: list.UniqueItems() & list.MinItems(1) & [..."after-single-line-comment"]
867
868 // Ignore rules that come after a comment
869 "ignore"?: list.UniqueItems() & list.MinItems(1) & [..."after-comment"]
870 ...
871 }
872 ])]
873 ])
874 ...
875 }
876
877 #selector: null | bool | number | string | [...] | {
878 // Disallow unmatchable An+B selectors
879 "selector-anb-no-unmatchable"?: matchN(1, [
880 matchN(1, [true, null]),
881 list.MaxItems(2) & {
882 [matchN(1, [true, null]), ...]
883 [1]: #coreRule
884 }
885 ])
886 "selector-attribute-brackets-space-inside"?: #alwaysNeverRule
887 "selector-attribute-operator-blacklist"?: #arrayStringRule
888 "selector-attribute-operator-space-after"?: #alwaysNeverRule
889 "selector-attribute-operator-space-before"?: #alwaysNeverRule
890 "selector-attribute-operator-whitelist"?: #arrayStringRule
891 "selector-attribute-quotes"?: #alwaysNeverRule
892
893 // Specify a pattern for class selectors
894 "selector-class-pattern"?: matchN(1, [
895 null | string,
896 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
897 string,
898 #coreRule & {...} & {
899 // This option will resolve nested selectors with `&` interpolation
900 "resolveNestedSelectors"?: bool
901 ...
902 }
903 ])]
904 ])
905 "selector-combinator-space-after"?: #alwaysNeverRule
906 "selector-combinator-space-before"?: #alwaysNeverRule
907 "selector-descendant-combinator-no-non-space"?: #booleanRule
908 "selector-id-pattern"?: #stringRule
909 "selector-max-compound-selectors"?: #integerRule
910 "selector-max-specificity"?: #stringRule
911 "selector-nested-pattern"?: #stringRule
912 "selector-no-attribute"?: #booleanRule
913 "selector-no-combinator"?: #booleanRule
914 "selector-no-id"?: #booleanRule
915
916 // Disallow qualifying a selector by type
917 "selector-no-qualifying-type"?: matchN(1, [
918 null,
919 true,
920 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
921 true,
922 #coreRule & {...} & {
923 "ignore"?: list.UniqueItems() & list.MinItems(1) & [..."attribute" | "class" | "id"]
924 ...
925 }
926 ])]
927 ])
928
929 // Disallow type selectors
930 "selector-no-type"?: matchN(1, [
931 null,
932 true,
933 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
934 true,
935 #coreRule & {...} & {
936 "ignore"?: list.UniqueItems() & list.MinItems(1) & [..."compounded" | "descendant"]
937 "ignoreTypes"?: #simpleArrayStringRule
938 ...
939 }
940 ])]
941 ])
942 "selector-no-universal"?: #booleanRule
943 "selector-no-vendor-prefix"?: #booleanRule
944 "selector-pseudo-class-case"?: #lowerUpperRule
945
946 // Disallow unknown pseudo-class selectors
947 "selector-pseudo-class-no-unknown"?: matchN(1, [
948 null,
949 true,
950 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
951 true,
952 #coreRule & {...} & {
953 "ignorePseudoClasses"?: #simpleArrayStringRule
954 ...
955 }
956 ])]
957 ])
958 "selector-pseudo-class-parentheses-space-inside"?: #alwaysNeverRule
959 "selector-pseudo-class-whitelist"?: #arrayStringRule
960 "selector-pseudo-element-case"?: #lowerUpperRule
961 "selector-pseudo-element-colon-notation"?: #singleDoubleRule
962
963 // Disallow unknown pseudo-element selectors
964 "selector-pseudo-element-no-unknown"?: matchN(1, [
965 null,
966 true,
967 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
968 true,
969 #coreRule & {...} & {
970 "ignorePseudoElements"?: #simpleArrayStringRule
971 ...
972 }
973 ])]
974 ])
975 "selector-root-no-composition"?: #booleanRule
976 "selector-type-case"?: #lowerUpperRule
977
978 // Disallow unknown type selectors
979 "selector-type-no-unknown"?: matchN(1, [
980 null,
981 true,
982 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
983 true,
984 #coreRule & {...} & {
985 "ignoreTypes"?: #simpleArrayStringRule
986 ...
987 }
988 ])]
989 ])
990 "selector-max-empty-lines"?: #integerRule
991 ...
992 }
993
994 #selectorList: null | bool | number | string | [...] | {
995 "selector-list-comma-newline-after"?: #newlineRule
996 "selector-list-comma-newline-before"?: #newlineRule
997 "selector-list-comma-space-after"?: #spaceRule
998 "selector-list-comma-space-before"?: #spaceRule
999 ...
1000 }
1001
1002 #shorthandProperty: null | bool | number | string | [...] | {
1003 "shorthand-property-no-redundant-values"?: #booleanRule
1004 ...
1005 }
1006
1007 #simpleArrayStringRule: list.UniqueItems() & [...string]
1008
1009 #simpleStringOrArrayStringRule: matchN(1, [string, #simpleArrayStringRule & (string | [...])])
1010
1011 #singleDoubleRule: matchN(1, [
1012 null,
1013 "single" | "double",
1014 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
1015 ...matchN(>=1, ["single" | "double", #coreRule & (string | {...})])
1016 ]
1017 ])
1018
1019 #spaceRule: matchN(1, [
1020 null,
1021 "always" | "never" | "always-single-line" | "never-single-line",
1022 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
1023 ...matchN(>=1, [
1024 "always" | "never" | "always-single-line" | "never-single-line",
1025 #coreRule & (string | {...})
1026 ])
1027 ]
1028 ])
1029
1030 #string: null | bool | number | string | [...] | {
1031 "string-no-newline"?: #booleanRule
1032 "string-quotes"?: #singleDoubleRule
1033 ...
1034 }
1035
1036 #stringRule: matchN(1, [
1037 null | string,
1038 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
1039 ...matchN(>=1, [string, #coreRule & (string | {...})])
1040 ]
1041 ])
1042
1043 #stylelintDisableComment: null | bool | number | string | [...] | {
1044 // Require a reason comment before or after `stylelint-disable` comments
1045 "stylelint-disable-reason"?: matchN(1, [
1046 null,
1047 "always-before" | "always-after",
1048 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [
1049 ...matchN(>=1, ["always-before" | "always-after", #coreRule & (string | {...})])
1050 ]
1051 ])
1052 ...
1053 }
1054
1055 #time: null | bool | number | string | [...] | {
1056 "time-no-imperceptible"?: #booleanRule
1057 ...
1058 }
1059
1060 #unit: null | bool | number | string | [...] | {
1061 "unit-blacklist"?: #unitRule
1062 "unit-case"?: #lowerUpperRule
1063
1064 // Disallow unknown units
1065 "unit-no-unknown"?: matchN(1, [
1066 null,
1067 true,
1068 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
1069 true,
1070 #coreRule & {...} & {
1071 "ignoreUnits"?: #simpleArrayStringRule
1072 ...
1073 }
1074 ])]
1075 ])
1076 "unit-whitelist"?: #unitRule
1077 ...
1078 }
1079
1080 #unitRule: matchN(1, [
1081 null,
1082 "em" |
1083 "ex" |
1084 "px" |
1085 "%" |
1086 "rem" |
1087 "vw" |
1088 "vh" |
1089 "vm" |
1090 "vmin" |
1091 "vmax" |
1092 "ch" |
1093 "in" |
1094 "cm" |
1095 "mm" |
1096 "q" |
1097 "pt" |
1098 "pc" |
1099 "deg" |
1100 "grad" |
1101 "rad" |
1102 "turn" |
1103 "ms" |
1104 "s" |
1105 "Hz" |
1106 "kHz" |
1107 "dpi" |
1108 "dpcm" |
1109 "dppx" |
1110 "fr",
1111 list.MinItems(1) & list.UniqueItems() & [...matchN(>=1, [
1112 "em" |
1113 "ex" |
1114 "px" |
1115 "%" |
1116 "rem" |
1117 "vw" |
1118 "vh" |
1119 "vm" |
1120 "vmin" |
1121 "vmax" |
1122 "ch" |
1123 "in" |
1124 "cm" |
1125 "mm" |
1126 "q" |
1127 "pt" |
1128 "pc" |
1129 "deg" |
1130 "grad" |
1131 "rad" |
1132 "turn" |
1133 "ms" |
1134 "s" |
1135 "Hz" |
1136 "kHz" |
1137 "dpi" |
1138 "dpcm" |
1139 "dppx" |
1140 "fr",
1141 list.UniqueItems() & list.MinItems(1) & [
1142 ..."em" |
1143 "ex" |
1144 "px" |
1145 "%" |
1146 "rem" |
1147 "vw" |
1148 "vh" |
1149 "vm" |
1150 "vmin" |
1151 "vmax" |
1152 "ch" |
1153 "in" |
1154 "cm" |
1155 "mm" |
1156 "q" |
1157 "pt" |
1158 "pc" |
1159 "deg" |
1160 "grad" |
1161 "rad" |
1162 "turn" |
1163 "ms" |
1164 "s" |
1165 "Hz" |
1166 "kHz" |
1167 "dpi" |
1168 "dpcm" |
1169 "dppx" |
1170 "fr"
1171 ],
1172 #coreRule & {...} & {
1173 // Ignore units in the values of declarations with the specified properties
1174 "ignoreProperties"?: {
1175 {[=~"(em|ex|ch|vw|vh|cm|mm|in|pt|pc|px|rem|vmin|vmax|%)"]: #simpleArrayStringRule}
1176 ...
1177 }
1178 ...
1179 }
1180 ])]
1181 ])
1182
1183 #value: null | bool | number | string | [...] | {
1184 // Specify lowercase or uppercase for keywords values
1185 "value-keyword-case"?: matchN(1, [
1186 null,
1187 "lower" | "upper",
1188 list.MinItems(2) & list.MaxItems(2) & list.UniqueItems() & [...matchN(>=1, [
1189 "lower" | "upper",
1190 #coreRule & {...} & {
1191 "ignoreKeywords"?: #simpleArrayStringRule
1192 ...
1193 }
1194 ])]
1195 ])
1196 "value-no-vendor-prefix"?: #booleanRule
1197 ...
1198 }
1199
1200 #valueList: null | bool | number | string | [...] | {
1201 "value-list-comma-newline-after"?: #newlineRule
1202 "value-list-comma-newline-before"?: #newlineRule
1203 "value-list-comma-space-after"?: #spaceRule
1204 "value-list-comma-space-before"?: #spaceRule
1205 "value-list-max-empty-lines"?: #integerRule
1206 ...
1207 }
1208}