@sister.software/oxlint-config 9.2.0 → 10.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.
- package/README.md +102 -10
- package/out/constant-doc-plugin.d.ts +26 -0
- package/out/constant-doc-plugin.d.ts.map +1 -0
- package/out/constant-doc-plugin.js +87 -0
- package/out/constant-doc-plugin.js.map +1 -0
- package/out/headers-plugin.js +1 -1
- package/out/headers-plugin.js.map +1 -1
- package/out/index.d.ts +75 -1
- package/out/index.d.ts.map +1 -1
- package/out/index.js +286 -6
- package/out/index.js.map +1 -1
- package/out/length-truthiness-plugin.d.ts +18 -0
- package/out/length-truthiness-plugin.d.ts.map +1 -0
- package/out/length-truthiness-plugin.js +113 -0
- package/out/length-truthiness-plugin.js.map +1 -0
- package/out/plugin-types.d.ts +23 -0
- package/out/plugin-types.d.ts.map +1 -1
- package/out/plugin.d.ts.map +1 -1
- package/out/plugin.js +8 -0
- package/out/plugin.js.map +1 -1
- package/out/process-globals-plugin.d.ts +13 -0
- package/out/process-globals-plugin.d.ts.map +1 -0
- package/out/process-globals-plugin.js +48 -0
- package/out/process-globals-plugin.js.map +1 -0
- package/out/threshold-plugin.d.ts +21 -0
- package/out/threshold-plugin.d.ts.map +1 -0
- package/out/threshold-plugin.js +72 -0
- package/out/threshold-plugin.js.map +1 -0
- package/package.json +2 -2
- package/src/constant-doc-plugin.ts +114 -0
- package/src/headers-plugin.ts +1 -1
- package/src/index.ts +354 -5
- package/src/length-truthiness-plugin.ts +132 -0
- package/src/plugin-types.ts +23 -0
- package/src/plugin.ts +8 -0
- package/src/process-globals-plugin.ts +68 -0
- package/src/threshold-plugin.ts +93 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
* @file A no-unnamed-threshold rule, authored as an oxlint JS plugin (ESLint v9-compatible API). It
|
|
6
|
+
* flags a numeric literal used as a threshold — an operand of a comparison — and nothing else.
|
|
7
|
+
* Numbers inside array and object literals are left alone, because a bounding box or a codepoint
|
|
8
|
+
* table is data rather than a tuning knob. That distinction is why this exists instead of
|
|
9
|
+
* `no-magic-numbers`, which cannot express it.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { AstNode, Rule } from "./plugin-types.js"
|
|
13
|
+
|
|
14
|
+
/** Operators whose operands read as thresholds. */
|
|
15
|
+
const COMPARISON_OPERATORS = new Set(["<", ">", "<=", ">=", "===", "!==", "==", "!="])
|
|
16
|
+
|
|
17
|
+
/** Numbers so conventional that naming them costs more clarity than it buys. */
|
|
18
|
+
const DEFAULT_IGNORE = [-1, 0, 1, 2, 0.5, 10, 100, 1000]
|
|
19
|
+
|
|
20
|
+
/** Radix-prefixed literals: `0x1f`, `0b1010`, `0o777`. */
|
|
21
|
+
const RADIX_PREFIXED = /^0[xXbBoO]/
|
|
22
|
+
|
|
23
|
+
/** Options accepted by {@link noUnnamedThresholdRule}. */
|
|
24
|
+
export interface ThresholdOptions {
|
|
25
|
+
/** Values that may appear unnamed. Replaces the default list rather than extending it. */
|
|
26
|
+
ignore?: number[]
|
|
27
|
+
/** Exempt radix-prefixed literals, which already read as codepoints or bit masks. */
|
|
28
|
+
allowHex?: boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const noUnnamedThresholdRule: Rule = {
|
|
32
|
+
meta: {
|
|
33
|
+
name: "no-unnamed-threshold",
|
|
34
|
+
type: "suggestion",
|
|
35
|
+
schema: [{ type: "object", additionalProperties: true }],
|
|
36
|
+
},
|
|
37
|
+
create(context) {
|
|
38
|
+
const options = (context.options[0] ?? {}) as ThresholdOptions
|
|
39
|
+
const ignore = new Set(options.ignore ?? DEFAULT_IGNORE)
|
|
40
|
+
const allowHex = options.allowHex ?? true
|
|
41
|
+
|
|
42
|
+
function check(operand: AstNode | undefined) {
|
|
43
|
+
if (!operand) return
|
|
44
|
+
|
|
45
|
+
let literal = operand
|
|
46
|
+
let sign = 1
|
|
47
|
+
|
|
48
|
+
// `x < -273.15` parses as a unary minus wrapping the literal.
|
|
49
|
+
if (operand.type === "UnaryExpression") {
|
|
50
|
+
if (operand.operator !== "-" && operand.operator !== "+") return
|
|
51
|
+
|
|
52
|
+
if (!operand.argument) return
|
|
53
|
+
|
|
54
|
+
sign = operand.operator === "-" ? -1 : 1
|
|
55
|
+
literal = operand.argument
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// oxlint's AST uses ESTree `Literal` in some positions and Babel-style `NumericLiteral` in
|
|
59
|
+
// others, so both are accepted.
|
|
60
|
+
if (literal.type !== "Literal" && literal.type !== "NumericLiteral") return
|
|
61
|
+
|
|
62
|
+
if (typeof literal.value !== "number") return
|
|
63
|
+
|
|
64
|
+
const raw = literal.raw ?? String(literal.value)
|
|
65
|
+
|
|
66
|
+
// `cp >= 0x3040` already reads as a codepoint boundary; a name adds nothing.
|
|
67
|
+
if (allowHex && RADIX_PREFIXED.test(raw)) return
|
|
68
|
+
|
|
69
|
+
if (ignore.has(sign * literal.value)) return
|
|
70
|
+
|
|
71
|
+
// `raw` is the literal's own text, so a negated value reads as `273.15` without this.
|
|
72
|
+
const shown = sign === -1 ? `-${raw}` : raw
|
|
73
|
+
|
|
74
|
+
context.report({
|
|
75
|
+
node: literal,
|
|
76
|
+
message:
|
|
77
|
+
`Unnamed threshold \`${shown}\` — extract it to a documented named constant so a reader can tell ` +
|
|
78
|
+
`what it means and where the value came from.`,
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
BinaryExpression(node) {
|
|
84
|
+
if (!node.operator || !COMPARISON_OPERATORS.has(node.operator)) return
|
|
85
|
+
|
|
86
|
+
check(node.left)
|
|
87
|
+
check(node.right)
|
|
88
|
+
},
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export default noUnnamedThresholdRule
|