@utilfirst/eslint-plugin 0.1.1 → 0.2.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/LICENSE CHANGED
@@ -19,3 +19,30 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
+
23
+ Third-party notices
24
+
25
+ The files under `src/rules/` other than `consistent-blank-lines.ts` and the
26
+ files under `src/shared/` include adapted work from anti-slop:
27
+
28
+ MIT License
29
+
30
+ Copyright (c) 2026 Dillon Mulroy
31
+
32
+ Permission is hereby granted, free of charge, to any person obtaining a copy
33
+ of this software and associated documentation files (the "Software"), to deal
34
+ in the Software without restriction, including without limitation the rights
35
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
+ copies of the Software, and to permit persons to whom the Software is
37
+ furnished to do so, subject to the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be included in all
40
+ copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
48
+ SOFTWARE.
package/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # @utilfirst/eslint-plugin
2
2
 
3
- Shared ESLint rules for utilfirst projects. Flat config only, ESLint v9 / v10.
3
+ Shared rules for ESLint 10 and Oxlint.
4
+
5
+ ## Policy
6
+
7
+ Every exported rule must express universal project policy. The recommended config enables the complete registry at error severity, and the test suite rejects registry entries that are absent from that config. A rule that cannot justify universal error severity must be redesigned or removed rather than moved to an optional preset. Rule options adapt repository ownership or boundary conventions without disabling the rule.
4
8
 
5
9
  ## Install
6
10
 
@@ -20,37 +24,129 @@ export default [
20
24
  ];
21
25
  ```
22
26
 
23
- Or wire rules individually:
27
+ ## Configure
24
28
 
25
- ```js
26
- import utilfirst from "@utilfirst/eslint-plugin";
29
+ Rules with repository-specific ownership or boundary conventions accept options in either runtime. Apply option overrides after the recommended config so the rule stays enabled.
27
30
 
31
+ ```js
28
32
  export default [
33
+ utilfirst.configs.recommended,
29
34
  {
30
- plugins: { utilfirst },
31
35
  rules: {
32
- "utilfirst/consistent-blank-lines": "error",
36
+ "utilfirst/no-module-mocking": [
37
+ "error",
38
+ { internalModulePrefixes: ["@workspace/"] },
39
+ ],
40
+ "utilfirst/no-positional-boolean-parameters": [
41
+ "error",
42
+ { allowFunctionNames: ["protocolCallback"] },
43
+ ],
44
+ "utilfirst/no-unknown-parameters": [
45
+ "error",
46
+ { allowParameterNames: ["externalPayload"] },
47
+ ],
48
+ "utilfirst/prefer-options-parameter": [
49
+ "error",
50
+ { allowFunctionNames: ["protocolCallback"] },
51
+ ],
33
52
  },
34
53
  },
35
54
  ];
36
55
  ```
37
56
 
57
+ - `internalModulePrefixes` marks package-style import prefixes as repository-owned for `no-module-mocking`.
58
+ - `allowFunctionNames` preserves named functions whose positional boolean or multi-input signature is fixed by an external protocol.
59
+ - `allowParameterNames` preserves `unknown` parameters whose names identify an externally fixed callback or interface signature.
60
+
61
+ ```jsonc
62
+ // .oxlintrc.json
63
+ {
64
+ "jsPlugins": [
65
+ {
66
+ "name": "utilfirst",
67
+ "specifier": "@utilfirst/eslint-plugin",
68
+ },
69
+ ],
70
+ "rules": {
71
+ "utilfirst/consistent-blank-lines": "error",
72
+ "utilfirst/no-chained-type-assertions": "error",
73
+ "utilfirst/no-conditional-undefined-properties": "error",
74
+ "utilfirst/no-enum-declarations": "error",
75
+ "utilfirst/no-known-value-widening": "error",
76
+ "utilfirst/no-module-mocking": [
77
+ "error",
78
+ { "internalModulePrefixes": ["@workspace/"] },
79
+ ],
80
+ "utilfirst/no-object-parameters": "error",
81
+ "utilfirst/no-positional-boolean-parameters": [
82
+ "error",
83
+ { "allowFunctionNames": ["protocolCallback"] },
84
+ ],
85
+ "utilfirst/no-reflect-apply": "error",
86
+ "utilfirst/no-reflect-get": "error",
87
+ "utilfirst/no-unknown-parameters": [
88
+ "error",
89
+ { "allowParameterNames": ["externalPayload"] },
90
+ ],
91
+ "utilfirst/no-unknown-returns": "error",
92
+ "utilfirst/no-unknown-type-aliases": "error",
93
+ "utilfirst/no-unsafe-dictionary-type": "error",
94
+ "utilfirst/no-unhandled-detached-promises": "error",
95
+ "utilfirst/no-widen-then-assert": "error",
96
+ "utilfirst/prefer-options-parameter": [
97
+ "error",
98
+ { "allowFunctionNames": ["protocolCallback"] },
99
+ ],
100
+ "utilfirst/prefer-switch-discriminator-chain": "error",
101
+ "utilfirst/prefer-top-level-function-declarations": "error",
102
+ "utilfirst/require-lint-suppression-reason": "error",
103
+ "utilfirst/require-safety-comment-for-type-assertion": "error",
104
+ },
105
+ }
106
+ ```
107
+
38
108
  ## Rules
39
109
 
40
- | Rule | Description | Fixable |
41
- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------- | ------- |
42
- | [`consistent-blank-lines`](./docs/rules/consistent-blank-lines.md) | Insert blank lines between statement-list and JSXChild items that start a new thought | yes |
110
+ [`docs/rules.md`](./docs/rules.md) explains the policy boundary and expected replacement for every rule. The implementations and colocated tests remain the executable behavior owners.
111
+
112
+ | Rule | Description |
113
+ | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
114
+ | [`consistent-blank-lines`](./docs/rules/consistent-blank-lines.md) | Insert blank lines between statement-list and JSXChild items that start a new thought |
115
+ | [`no-chained-type-assertions`](./docs/rules.md#type-evidence) | Reject chained TypeScript assertions |
116
+ | [`no-conditional-undefined-properties`](./docs/rules.md#object-and-api-construction) | Reject conditional undefined object properties |
117
+ | [`no-enum-declarations`](./docs/rules.md#object-and-api-construction) | Reject repository-owned enums other than ambient declarations |
118
+ | [`no-known-value-widening`](./docs/rules.md#type-evidence) | Reject known values widened into broad target types |
119
+ | [`no-module-mocking`](./docs/rules.md#ownership-and-tests) | Reject Vitest and Jest mocking of repository-owned modules |
120
+ | [`no-object-parameters`](./docs/rules.md#boundary-contracts) | Reject `object` function parameters |
121
+ | [`no-positional-boolean-parameters`](./docs/rules.md#object-and-api-construction) | Reject positional boolean flags on named functions and methods |
122
+ | [`no-reflect-apply`](./docs/rules.md#object-and-api-construction) | Reject `Reflect.apply` |
123
+ | [`no-reflect-get`](./docs/rules.md#object-and-api-construction) | Reject `Reflect.get` |
124
+ | [`no-unknown-parameters`](./docs/rules.md#boundary-contracts) | Keep explicit `unknown` parameters at decoding boundaries |
125
+ | [`no-unknown-returns`](./docs/rules.md#boundary-contracts) | Reject `unknown` return contracts |
126
+ | [`no-unknown-type-aliases`](./docs/rules.md#boundary-contracts) | Reject type aliases that resolve to `unknown` |
127
+ | [`no-unsafe-dictionary-type`](./docs/rules.md#boundary-contracts) | Reject dictionary contracts with broad value types |
128
+ | [`no-unhandled-detached-promises`](./docs/rules.md#async-errors) | Require rejection handling on `void`-marked detached call chains |
129
+ | [`no-widen-then-assert`](./docs/rules.md#type-evidence) | Reject const flows that widen a known value before narrowing it |
130
+ | [`prefer-options-parameter`](./docs/rules.md#object-and-api-construction) | Require options objects for named functions and methods with three or more inputs |
131
+ | [`prefer-switch-discriminator-chain`](./docs/rules.md#object-and-api-construction) | Require a switch for four or more equality branches on one discriminator |
132
+ | [`prefer-top-level-function-declarations`](./docs/rules.md#object-and-api-construction) | Require declarations for direct top-level function bindings and default exports |
133
+ | [`require-lint-suppression-reason`](./docs/rules.md#lint-policy) | Require a forcing reason on lint disable directives |
134
+ | [`require-safety-comment-for-type-assertion`](./docs/rules.md#type-evidence) | Require one `SAFETY:` comment for each outermost non-const assertion |
135
+
136
+ ## Attribution
137
+
138
+ The rules other than `consistent-blank-lines`, `no-conditional-undefined-properties`, `no-enum-declarations`, `no-positional-boolean-parameters`, `no-unhandled-detached-promises`, `prefer-options-parameter`, and `require-lint-suppression-reason`, along with their helpers, are adapted from [dmmulroy/anti-slop](https://github.com/dmmulroy/anti-slop/) under the MIT License. The package's [LICENSE](./LICENSE) retains the copyright and permission notice.
43
139
 
44
140
  ## Develop
45
141
 
46
142
  ```sh
47
143
  pnpm install
48
144
  pnpm run setup-hooks # one-time: wire pre-commit via simple-git-hooks
49
- pnpm test # vitest + @typescript-eslint/rule-tester
145
+ pnpm test # unit, dual-runtime, and packed-artifact tests
50
146
  pnpm run build # tsdown → dist/
51
- pnpm run lint # eslint + prettier + publint + tsc
147
+ pnpm run lint # oxlint + prettier + publint
52
148
  ```
53
149
 
54
150
  ## License
55
151
 
56
- MIT
152
+ MIT. The package includes third-party code under the same license.
package/dist/index.d.ts CHANGED
@@ -1,17 +1,18 @@
1
1
  import { TSESLint } from "@typescript-eslint/utils";
2
2
 
3
3
  //#region src/index.d.ts
4
- declare const plugin: {
5
- meta: {
6
- readonly name: "@utilfirst/eslint-plugin";
7
- readonly version: string;
8
- };
9
- rules: {
10
- "consistent-blank-lines": TSESLint.RuleModule<"extra" | "missing", [], unknown, TSESLint.RuleListener>;
11
- };
4
+ declare const meta: {
5
+ readonly name: "@utilfirst/eslint-plugin";
6
+ readonly version: string;
7
+ };
8
+ type RuleRegistry = Record<string, TSESLint.RuleModule<string>>;
9
+ type UtilfirstPlugin = {
10
+ meta: typeof meta;
11
+ rules: RuleRegistry;
12
12
  configs: {
13
13
  recommended: TSESLint.FlatConfig.Config;
14
14
  };
15
15
  };
16
+ declare const plugin: UtilfirstPlugin;
16
17
  //#endregion
17
18
  export { plugin as default };