@sister.software/oxlint-config 9.3.0 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +198 -10
  2. package/out/browser-globals.d.ts +15 -0
  3. package/out/browser-globals.d.ts.map +1 -0
  4. package/out/browser-globals.js +76 -0
  5. package/out/browser-globals.js.map +1 -0
  6. package/out/console-padding-plugin.d.ts +16 -0
  7. package/out/console-padding-plugin.d.ts.map +1 -0
  8. package/out/console-padding-plugin.js +68 -0
  9. package/out/console-padding-plugin.js.map +1 -0
  10. package/out/constant-doc-plugin.d.ts +32 -0
  11. package/out/constant-doc-plugin.d.ts.map +1 -0
  12. package/out/constant-doc-plugin.js +91 -0
  13. package/out/constant-doc-plugin.js.map +1 -0
  14. package/out/headers-plugin.d.ts +6 -2
  15. package/out/headers-plugin.d.ts.map +1 -1
  16. package/out/headers-plugin.js +4 -2
  17. package/out/headers-plugin.js.map +1 -1
  18. package/out/index.d.ts +166 -13
  19. package/out/index.d.ts.map +1 -1
  20. package/out/index.js +332 -6
  21. package/out/index.js.map +1 -1
  22. package/out/jsdoc-plugin.d.ts +16 -0
  23. package/out/jsdoc-plugin.d.ts.map +1 -0
  24. package/out/jsdoc-plugin.js +68 -0
  25. package/out/jsdoc-plugin.js.map +1 -0
  26. package/out/length-truthiness-plugin.d.ts +18 -0
  27. package/out/length-truthiness-plugin.d.ts.map +1 -0
  28. package/out/length-truthiness-plugin.js +123 -0
  29. package/out/length-truthiness-plugin.js.map +1 -0
  30. package/out/multiline-statement-plugin.d.ts +18 -0
  31. package/out/multiline-statement-plugin.d.ts.map +1 -0
  32. package/out/multiline-statement-plugin.js +93 -0
  33. package/out/multiline-statement-plugin.js.map +1 -0
  34. package/out/padding-plugin.d.ts +4 -3
  35. package/out/padding-plugin.d.ts.map +1 -1
  36. package/out/padding-plugin.js +44 -27
  37. package/out/padding-plugin.js.map +1 -1
  38. package/out/padding-utils.d.ts +34 -0
  39. package/out/padding-utils.d.ts.map +1 -0
  40. package/out/padding-utils.js +50 -0
  41. package/out/padding-utils.js.map +1 -0
  42. package/out/plugin-types.d.ts +68 -3
  43. package/out/plugin-types.d.ts.map +1 -1
  44. package/out/plugin.d.ts.map +1 -1
  45. package/out/plugin.js +17 -0
  46. package/out/plugin.js.map +1 -1
  47. package/out/process-globals-plugin.d.ts.map +1 -1
  48. package/out/process-globals-plugin.js +6 -2
  49. package/out/process-globals-plugin.js.map +1 -1
  50. package/out/restrictions.d.ts +9 -3
  51. package/out/restrictions.d.ts.map +1 -1
  52. package/out/restrictions.js +4 -70
  53. package/out/restrictions.js.map +1 -1
  54. package/out/section-marker-plugin.d.ts +25 -0
  55. package/out/section-marker-plugin.d.ts.map +1 -0
  56. package/out/section-marker-plugin.js +234 -0
  57. package/out/section-marker-plugin.js.map +1 -0
  58. package/out/threshold-plugin.d.ts +27 -0
  59. package/out/threshold-plugin.d.ts.map +1 -0
  60. package/out/threshold-plugin.js +78 -0
  61. package/out/threshold-plugin.js.map +1 -0
  62. package/package.json +2 -2
  63. package/src/browser-globals.ts +77 -0
  64. package/src/console-padding-plugin.ts +76 -0
  65. package/src/constant-doc-plugin.ts +124 -0
  66. package/src/headers-plugin.ts +7 -3
  67. package/src/index.ts +490 -17
  68. package/src/jsdoc-plugin.ts +75 -0
  69. package/src/length-truthiness-plugin.ts +142 -0
  70. package/src/multiline-statement-plugin.ts +104 -0
  71. package/src/padding-plugin.ts +44 -29
  72. package/src/padding-utils.ts +70 -0
  73. package/src/plugin-types.ts +68 -3
  74. package/src/plugin.ts +22 -0
  75. package/src/process-globals-plugin.ts +6 -2
  76. package/src/restrictions.ts +16 -77
  77. package/src/section-marker-plugin.ts +306 -0
  78. package/src/threshold-plugin.ts +105 -0
@@ -0,0 +1,142 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ * @file A prefer-length-truthiness rule, authored as an oxlint JS plugin (ESLint v9-compatible API).
6
+ * It is the house counterpart to `unicorn/explicit-length-check`, which enforces the opposite
7
+ * convention and is therefore off: `if (items.length)` reads better here than
8
+ * `if (items.length > 0)`.
9
+ *
10
+ * The rule only fires where the value is ALREADY coerced to a boolean — a condition, a ternary
11
+ * test, or the operand of `!` — including through `&&`/`||` nested inside one. Outside those
12
+ * positions the comparison is the value itself, and rewriting `const hasItems = items.length > 0`
13
+ * would silently change its type from boolean to number.
14
+ */
15
+
16
+ import type { AstNode, Fixer, Rule, RuleContext } from "./plugin-types.js"
17
+
18
+ /**
19
+ * Comparisons meaning "non-empty", which become the bare length.
20
+ */
21
+ const TRUTHY_FORMS = new Set(["> 0", "!== 0", "!= 0", ">= 1"])
22
+
23
+ /**
24
+ * Comparisons meaning "empty", which become a negated length.
25
+ */
26
+ const FALSY_FORMS = new Set(["=== 0", "== 0", "< 1"])
27
+
28
+ /**
29
+ * Members whose length-ness the rule understands.
30
+ */
31
+ const LENGTH_PROPERTIES = new Set(["length", "size"])
32
+
33
+ /**
34
+ * The comparison rendered as `<operator> <literal>`, or null when it is not a length comparison.
35
+ */
36
+ function classify(node: AstNode): { member: AstNode; negate: boolean } | null {
37
+ if (node.type !== "BinaryExpression" || !node.operator || !node.left || !node.right) return null
38
+
39
+ // Accept both `x.length > 0` and the flipped `0 < x.length`.
40
+ const flipped: Record<string, string> = { "<": ">", ">": "<", "<=": ">=", ">=": "<=" }
41
+ let { left, right, operator } = { left: node.left, right: node.right, operator: node.operator }
42
+
43
+ if (left.type === "Literal" || left.type === "NumericLiteral") {
44
+ ;[left, right] = [right, left]
45
+ operator = flipped[operator] ?? operator
46
+ }
47
+
48
+ if (left.type !== "MemberExpression" && left.type !== "StaticMemberExpression") return null
49
+
50
+ const property = (left as AstNode & { property?: AstNode }).property
51
+
52
+ if (!property || property.type !== "Identifier" || !LENGTH_PROPERTIES.has(property.name ?? "")) return null
53
+
54
+ if (right.type !== "Literal" && right.type !== "NumericLiteral") return null
55
+
56
+ if (typeof right.value !== "number") return null
57
+
58
+ const form = `${operator} ${right.value}`
59
+
60
+ if (TRUTHY_FORMS.has(form)) return { member: left, negate: false }
61
+
62
+ if (FALSY_FORMS.has(form)) return { member: left, negate: true }
63
+
64
+ return null
65
+ }
66
+
67
+ export const preferLengthTruthinessRule: Rule = {
68
+ meta: {
69
+ name: "prefer-length-truthiness",
70
+ type: "suggestion",
71
+ fixable: "code",
72
+ schema: [{ type: "object", additionalProperties: true }],
73
+ },
74
+ create(context: RuleContext) {
75
+ const sourceCode = context.sourceCode ?? context.getSourceCode!()
76
+ const text = sourceCode.getText()
77
+
78
+ function report(node: AstNode) {
79
+ const hit = classify(node)
80
+
81
+ if (!hit) return
82
+
83
+ const member = text.slice(hit.member.range[0], hit.member.range[1])
84
+ const replacement = hit.negate ? `!${member}` : member
85
+
86
+ context.report({
87
+ node,
88
+ message: `Prefer \`${replacement}\` over an explicit length comparison — the house convention is truthiness.`,
89
+ fix(fixer: Fixer) {
90
+ return fixer.replaceTextRange(node.range, replacement)
91
+ },
92
+ })
93
+ }
94
+
95
+ /**
96
+ * Walk into a boolean context: logical operands and `!` arguments stay boolean.
97
+ */
98
+ function visitCondition(node: AstNode | null | undefined) {
99
+ if (!node) return
100
+
101
+ if (node.type === "LogicalExpression") {
102
+ visitCondition(node.left)
103
+ visitCondition(node.right)
104
+
105
+ return
106
+ }
107
+
108
+ if (node.type === "UnaryExpression" && node.operator === "!") {
109
+ visitCondition(node.argument)
110
+
111
+ return
112
+ }
113
+
114
+ report(node)
115
+ }
116
+
117
+ return {
118
+ IfStatement(node) {
119
+ visitCondition(node.test)
120
+ },
121
+ WhileStatement(node) {
122
+ visitCondition(node.test)
123
+ },
124
+ DoWhileStatement(node) {
125
+ visitCondition(node.test)
126
+ },
127
+ ForStatement(node) {
128
+ visitCondition(node.test)
129
+ },
130
+ ConditionalExpression(node) {
131
+ visitCondition(node.test)
132
+ },
133
+ UnaryExpression(node) {
134
+ if (node.operator === "!") {
135
+ visitCondition(node.argument)
136
+ }
137
+ },
138
+ }
139
+ },
140
+ }
141
+
142
+ export default preferLengthTruthinessRule
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ * @file The `sister-software/multiline-statement-padding` rule: a statement that spans lines gets a
6
+ * blank line on each side, so a reader can see where it starts and stops without matching brackets.
7
+ *
8
+ * One rule covers what look like two habits — a big object literal jammed against the next
9
+ * declaration, and a multi-line call jammed against the counter after it. Both are the same thing:
10
+ * a statement tall enough to read as a block, sitting flush against its neighbour.
11
+ *
12
+ * Neither edge is required at a block boundary, where the brace already separates. `console.*` calls
13
+ * are left to `console-padding`, which groups consecutive ones — this rule would split a run that
14
+ * happens to contain a tall call, and a run of output is one thing.
15
+ */
16
+
17
+ import { createPaddingHelpers } from "./padding-utils.js"
18
+ import type { AstNode, Rule } from "./plugin-types.js"
19
+
20
+ /**
21
+ * The object whose calls belong to `console-padding` rather than to this rule.
22
+ */
23
+ const CONSOLE_OBJECT = "console"
24
+
25
+ /**
26
+ * Does this statement's own source span more than one line?
27
+ */
28
+ function isMultiline(node: AstNode, text: string): boolean {
29
+ return text.slice(node.range[0], node.range[1]).includes("\n")
30
+ }
31
+
32
+ /**
33
+ * Is this statement a bare `console.<method>(…)` call, which `console-padding` owns?
34
+ */
35
+ function isConsoleStatement(node: AstNode | undefined): boolean {
36
+ if (node?.type !== "ExpressionStatement") return false
37
+ const callee = node.expression?.type === "CallExpression" ? node.expression.callee : undefined
38
+
39
+ return callee?.type === "MemberExpression" && callee.object?.name === CONSOLE_OBJECT
40
+ }
41
+
42
+ export const multilineStatementPaddingRule: Rule = {
43
+ meta: {
44
+ name: "multiline-statement-padding",
45
+ type: "layout",
46
+ fixable: "whitespace",
47
+ schema: [{ type: "object", additionalProperties: true }],
48
+ },
49
+ create(context) {
50
+ const sourceCode = context.sourceCode ?? context.getSourceCode!()
51
+ const text = sourceCode.getText()
52
+ const { requirePadding } = createPaddingHelpers(context)
53
+
54
+ function check(node: AstNode): void {
55
+ const parent = node.parent
56
+
57
+ if (!parent || !Array.isArray(parent.body)) return
58
+
59
+ if (!isMultiline(node, text) || isConsoleStatement(node)) return
60
+ const body = parent.body
61
+ const index = body.indexOf(node)
62
+
63
+ if (index === -1) return
64
+ const previous = body[index - 1]
65
+ const next = body[index + 1]
66
+
67
+ if (previous && !isConsoleStatement(previous)) {
68
+ requirePadding(previous, node, node, "Expected a blank line before this multi-line statement.")
69
+ }
70
+
71
+ if (next && !isConsoleStatement(next)) {
72
+ requirePadding(node, next, node, "Expected a blank line after this multi-line statement.")
73
+ }
74
+ }
75
+
76
+ // Every statement type that can stand in a statement list and span lines. Block-like statements are
77
+ // already padded from the front by `padding-lines`; this adds their trailing edge.
78
+ return Object.fromEntries(
79
+ [
80
+ "VariableDeclaration",
81
+ "ExpressionStatement",
82
+ "IfStatement",
83
+ "ForStatement",
84
+ "ForInStatement",
85
+ "ForOfStatement",
86
+ "WhileStatement",
87
+ "DoWhileStatement",
88
+ "SwitchStatement",
89
+ "TryStatement",
90
+ "FunctionDeclaration",
91
+ "ClassDeclaration",
92
+ "ReturnStatement",
93
+ "TSInterfaceDeclaration",
94
+ "TSTypeAliasDeclaration",
95
+ "TSEnumDeclaration",
96
+ "TSModuleDeclaration",
97
+ // An exported declaration arrives wrapped, and the wrapper spans the same lines as what it
98
+ // wraps — so matching the wrapper is enough. Without these, every `export` was invisible here.
99
+ "ExportNamedDeclaration",
100
+ "ExportDefaultDeclaration",
101
+ ].map((type) => [type, check])
102
+ )
103
+ },
104
+ }
@@ -3,19 +3,23 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  * @file A padding-lines rule, authored as an oxlint JS plugin (ESLint v9-compatible API). It
6
- * requires a blank line before `return` and block-like statements (the equivalent of ESLint's
7
- * `padding-line-between-statements` with `{ blankLine: "always", prev: "*", next: "return" | "block-like" }`),
8
- * and autofixes by inserting the missing blank line (before any leading comments).
6
+ * requires a blank line before the statements that END a path or a step — `return`, `continue`,
7
+ * `break`, a bare `x++`/`x--` and before block-like statements. Roughly ESLint's
8
+ * `padding-line-between-statements` with `{ blankLine: "always", prev: "*", next: "return" | "block-like" }`,
9
+ * widened to the rest of that family. Autofixes by inserting the blank line before any leading comments.
9
10
  */
10
11
 
12
+ import { createPaddingHelpers } from "./padding-utils.js"
11
13
  import type { AstNode, Rule } from "./plugin-types.js"
12
14
 
13
15
  /**
14
- * Statement node types that require a preceding blank line: `return` plus all "block-like" statements (matching
16
+ * Statement node types that require a preceding blank line: the path-enders plus all "block-like" statements (matching
15
17
  * ESLint's `block-like` selector).
16
18
  */
17
19
  const PADDED_STATEMENT_TYPES = [
18
20
  "ReturnStatement",
21
+ "ContinueStatement",
22
+ "BreakStatement",
19
23
  "BlockStatement",
20
24
  "IfStatement",
21
25
  "ForStatement",
@@ -25,8 +29,21 @@ const PADDED_STATEMENT_TYPES = [
25
29
  "DoWhileStatement",
26
30
  "SwitchStatement",
27
31
  "TryStatement",
32
+ // An interface or a type alias with a body reads as a block too — same braces, same weight on the
33
+ // page — so it wants the same separation from whatever precedes it.
34
+ "TSInterfaceDeclaration",
35
+ "TSTypeAliasDeclaration",
36
+ "TSEnumDeclaration",
37
+ "TSModuleDeclaration",
28
38
  ] as const
29
39
 
40
+ /**
41
+ * Does this node type require a preceding blank line?
42
+ */
43
+ function isPaddedType(type: string | undefined): boolean {
44
+ return !!type && (PADDED_STATEMENT_TYPES as readonly string[]).includes(type)
45
+ }
46
+
30
47
  export const paddingRule: Rule = {
31
48
  meta: {
32
49
  name: "padding-lines",
@@ -35,9 +52,7 @@ export const paddingRule: Rule = {
35
52
  schema: [{ type: "object", additionalProperties: true }],
36
53
  },
37
54
  create(context) {
38
- const sourceCode = context.sourceCode ?? context.getSourceCode!()
39
- const text = sourceCode.getText()
40
- const comments = sourceCode.getAllComments()
55
+ const { requirePadding } = createPaddingHelpers(context)
41
56
 
42
57
  function check(node: AstNode) {
43
58
  const parent = node.parent
@@ -49,32 +64,32 @@ export const paddingRule: Rule = {
49
64
  const index = parent.body.indexOf(node)
50
65
 
51
66
  if (index <= 0) return // first statement in the block — nothing to pad against.
52
- const previous = parent.body[index - 1]!
53
67
 
54
- // A blank line should sit before the statement's own leading comments, so measure the gap
55
- // up to the earliest comment between the previous statement and this one.
56
- let start = node.range[0]
68
+ requirePadding(parent.body[index - 1]!, node, node, "Expected a blank line before this statement.")
69
+ }
57
70
 
58
- for (const comment of comments) {
59
- if (comment.range[0] >= previous.range[1] && comment.range[1] <= node.range[0]) {
60
- start = Math.min(start, comment.range[0])
71
+ return {
72
+ ...Object.fromEntries(PADDED_STATEMENT_TYPES.map((type) => [type, check])),
73
+ // A bare `x++` / `x--` is a counter step, and reads like one only when it stands apart. It
74
+ // arrives as an ExpressionStatement, so it cannot be matched by node type alone.
75
+ ExpressionStatement(node: AstNode) {
76
+ if (node.expression?.type === "UpdateExpression") {
77
+ check(node)
61
78
  }
62
- }
63
-
64
- const gap = text.slice(previous.range[1], start)
65
-
66
- if ((gap.match(/\n/g) ?? []).length >= 2) return // already a blank line.
67
-
68
- context.report({
69
- node,
70
- message: "Expected a blank line before this statement.",
71
- fix(fixer) {
72
- return fixer.insertTextAfterRange([previous.range[1], previous.range[1]], "\n")
73
- },
74
- })
79
+ },
80
+ // An exported declaration arrives wrapped. Look through the wrapper so `export interface Foo {}`
81
+ // is padded exactly like the unexported form.
82
+ ExportNamedDeclaration(node: AstNode) {
83
+ if (isPaddedType(node.declaration?.type)) {
84
+ check(node)
85
+ }
86
+ },
87
+ ExportDefaultDeclaration(node: AstNode) {
88
+ if (isPaddedType(node.declaration?.type)) {
89
+ check(node)
90
+ }
91
+ },
75
92
  }
76
-
77
- return Object.fromEntries(PADDED_STATEMENT_TYPES.map((type) => [type, check]))
78
93
  },
79
94
  }
80
95
 
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ * @file The blank-line machinery the three padding rules share: how to tell whether two statements are
6
+ * already separated, and how to ask for the separation when they are not.
7
+ *
8
+ * All three anchor their fix to the END of the earlier statement. That is deliberate: when two rules
9
+ * want the same blank line — a console call before a `return`, say — they emit the identical edit, so
10
+ * one is applied and the other is a no-op, instead of each inserting a newline and producing a gap of
11
+ * two.
12
+ */
13
+
14
+ import type { AstNode, Fixer, RuleContext, SourceCode } from "./plugin-types.js"
15
+
16
+ /**
17
+ * What a padding rule needs from its context, resolved once per `create`.
18
+ */
19
+ export interface PaddingHelpers {
20
+ /**
21
+ * Is there already a blank line between these two statements?
22
+ */
23
+ isPadded(from: AstNode, to: AstNode): boolean
24
+ /**
25
+ * Report and fix a missing blank line between `from` and `to`, unless one is impossible or present.
26
+ */
27
+ requirePadding(from: AstNode, to: AstNode, node: AstNode, message: string): void
28
+ }
29
+
30
+ /**
31
+ * Build the helpers for one rule invocation.
32
+ *
33
+ * A gap is measured to the earliest comment that leads the later statement, so the blank line lands above a statement's
34
+ * own comments rather than between them and their subject.
35
+ */
36
+ export function createPaddingHelpers(context: RuleContext): PaddingHelpers {
37
+ const sourceCode: SourceCode = context.sourceCode ?? context.getSourceCode!()
38
+ const text = sourceCode.getText()
39
+ const comments = sourceCode.getAllComments()
40
+
41
+ function isPadded(from: AstNode, to: AstNode): boolean {
42
+ // Two statements with no newline between them cannot be separated by a blank line. This is the
43
+ // `;(expr)` ASI guard: the semicolon terminates the PREVIOUS statement, so the gap here is zero
44
+ // characters wide. Asking for padding there is asking for the impossible.
45
+ if (!text.slice(from.range[1], to.range[0]).includes("\n")) return true
46
+ let start = to.range[0]
47
+
48
+ for (const comment of comments) {
49
+ if (comment.range[0] >= from.range[1] && comment.range[1] <= to.range[0]) {
50
+ start = Math.min(start, comment.range[0])
51
+ }
52
+ }
53
+
54
+ return (text.slice(from.range[1], start).match(/\n/g) ?? []).length >= 2
55
+ }
56
+
57
+ function requirePadding(from: AstNode, to: AstNode, node: AstNode, message: string): void {
58
+ if (isPadded(from, to)) return
59
+
60
+ context.report({
61
+ node,
62
+ message,
63
+ fix(fixer: Fixer) {
64
+ return fixer.insertTextAfterRange([from.range[1], from.range[1]], "\n")
65
+ },
66
+ })
67
+ }
68
+
69
+ return { isPadded, requirePadding }
70
+ }
@@ -12,16 +12,81 @@ export interface Comment {
12
12
  range: [number, number]
13
13
  }
14
14
 
15
- /** A loosely-typed AST node — only the fields the bundled rules read. */
15
+ /**
16
+ * A loosely-typed AST node — only the fields the bundled rules read.
17
+ */
16
18
  export interface AstNode {
17
19
  type: string
18
20
  range: [number, number]
19
21
  parent?: AstNode
20
- /** A statement-list body (block/program) is an array; a loop body is a single statement. */
22
+ /**
23
+ * A statement-list body (block/program) is an array; a loop body is a single statement.
24
+ */
21
25
  body?: AstNode[] | AstNode
22
- /** `if`/`else` branches, for the require-braces rule. */
26
+ /**
27
+ * `if`/`else` branches, for the require-braces rule.
28
+ */
23
29
  consequent?: AstNode
24
30
  alternate?: AstNode | null
31
+ /**
32
+ * Binary/unary operator text, for the threshold rule.
33
+ */
34
+ operator?: string
35
+ /**
36
+ * Binary-expression operands.
37
+ */
38
+ left?: AstNode
39
+ right?: AstNode
40
+ /**
41
+ * Unary-expression operand.
42
+ */
43
+ argument?: AstNode
44
+ /**
45
+ * A literal's value, and its verbatim source text (`raw` preserves a `0x` prefix).
46
+ */
47
+ value?: unknown
48
+ raw?: string
49
+ /**
50
+ * `const` / `let` / `var`, for the constant-doc rule.
51
+ */
52
+ kind?: string
53
+ /**
54
+ * Declarators of a variable declaration.
55
+ */
56
+ declarations?: AstNode[]
57
+ /**
58
+ * A declarator's binding identifier and initializer.
59
+ */
60
+ id?: AstNode
61
+ init?: AstNode | null
62
+ /**
63
+ * An identifier's name.
64
+ */
65
+ name?: string
66
+ /**
67
+ * The condition of an `if`/`while`/`for`/ternary, for the length-truthiness rule.
68
+ */
69
+ test?: AstNode | null
70
+ /**
71
+ * A member expression's accessed property.
72
+ */
73
+ property?: AstNode
74
+ /**
75
+ * An expression statement's expression, for the console-padding rule.
76
+ */
77
+ expression?: AstNode
78
+ /**
79
+ * An export statement's inner declaration, for the padding rules.
80
+ */
81
+ declaration?: AstNode | null
82
+ /**
83
+ * A call expression's callee.
84
+ */
85
+ callee?: AstNode
86
+ /**
87
+ * A member expression's object.
88
+ */
89
+ object?: AstNode
25
90
  }
26
91
 
27
92
  export interface SourceCode {
package/src/plugin.ts CHANGED
@@ -7,18 +7,40 @@
7
7
  */
8
8
 
9
9
  import { bracesRule } from "./braces-plugin.js"
10
+ import { consolePaddingRule } from "./console-padding-plugin.js"
11
+ import { requireConstantDocRule } from "./constant-doc-plugin.js"
10
12
  import { headerRule } from "./headers-plugin.js"
13
+ import { multilineJSDocRule } from "./jsdoc-plugin.js"
14
+ import { preferLengthTruthinessRule } from "./length-truthiness-plugin.js"
15
+ import { multilineStatementPaddingRule } from "./multiline-statement-plugin.js"
11
16
  import { paddingRule } from "./padding-plugin.js"
12
17
  import type { Plugin } from "./plugin-types.js"
13
18
  import { noProcessGlobalsRule } from "./process-globals-plugin.js"
19
+ import {
20
+ conciseSectionMarkerRule,
21
+ maxRegionsRule,
22
+ preferMarkCommentRule,
23
+ preferRegionOverMarksRule,
24
+ } from "./section-marker-plugin.js"
25
+ import { noUnnamedThresholdRule } from "./threshold-plugin.js"
14
26
 
15
27
  const sisterSoftwarePlugin: Plugin = {
16
28
  meta: { name: "sister-software" },
17
29
  rules: {
18
30
  "require-file-header": headerRule,
19
31
  "padding-lines": paddingRule,
32
+ "console-padding": consolePaddingRule,
33
+ "multiline-statement-padding": multilineStatementPaddingRule,
20
34
  "require-braces": bracesRule,
21
35
  "no-process-globals": noProcessGlobalsRule,
36
+ "no-unnamed-threshold": noUnnamedThresholdRule,
37
+ "require-constant-doc": requireConstantDocRule,
38
+ "prefer-length-truthiness": preferLengthTruthinessRule,
39
+ "multiline-jsdoc": multilineJSDocRule,
40
+ "prefer-mark-comment": preferMarkCommentRule,
41
+ "concise-section-marker": conciseSectionMarkerRule,
42
+ "prefer-region-over-marks": preferRegionOverMarksRule,
43
+ "max-regions": maxRegionsRule,
22
44
  },
23
45
  }
24
46
 
@@ -10,7 +10,9 @@
10
10
 
11
11
  import type { AstNode, Rule } from "./plugin-types.js"
12
12
 
13
- /** `process` members that must be reached through a blessed helper, not accessed directly. */
13
+ /**
14
+ * `process` members that must be reached through a blessed helper, not accessed directly.
15
+ */
14
16
  const RESTRICTED_MEMBERS = new Set(["env", "argv"])
15
17
 
16
18
  interface Identifierish extends AstNode {
@@ -24,7 +26,9 @@ interface MemberNode extends AstNode {
24
26
  computed?: boolean
25
27
  }
26
28
 
27
- /** The accessed member name for `process.env` (identifier) or `process["env"]` (string literal). */
29
+ /**
30
+ * The accessed member name for `process.env` (identifier) or `process["env"]` (string literal).
31
+ */
28
32
  function accessedMember(node: MemberNode): string | null {
29
33
  const property = node.property
30
34