eslint-plugin-legion 0.1.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/CHANGELOG.md +12 -0
- package/LICENSE +21 -0
- package/README.md +104 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/package.json +73 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# eslint-plugin-legion
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ecc18df: Initial release: nine grade A rules with tolerance levels, the oxlint/ESLint plugin, the audit CLI with the `directives` subcommand, the Prettier and TypeScript configs, and the umbrella package.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [ecc18df]
|
|
12
|
+
- legion-rules@0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Veracium LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# eslint-plugin-legion
|
|
2
|
+
|
|
3
|
+
[LEGION-STANDARDS](https://github.com/Kprince1101/legion-toolkit#readme) as a
|
|
4
|
+
lint plugin. One package, two runtimes: it is an ESLint v9+ plugin, and
|
|
5
|
+
oxlint's `jsPlugins` runs ESLint plugins as-is, so the same rules with the
|
|
6
|
+
same diagnostics run under either. CI on this repo proves the two agree on
|
|
7
|
+
every fixture.
|
|
8
|
+
|
|
9
|
+
What it enforces: components that render and never think (no state,
|
|
10
|
+
effects, fetching, handler bodies or projections in a component), zero
|
|
11
|
+
comments, no `React.FC`, no `enum`, no ternaries, no `function` keyword,
|
|
12
|
+
guarded context hooks, hydration-safe `useState`, server-first
|
|
13
|
+
`page`/`layout` files, no literal conditions in JSX, no manual memoization
|
|
14
|
+
when the React Compiler is on, no service-role client in browser code, a 180-line
|
|
15
|
+
component cap, `any` only on declared boundary paths, and lint bypasses
|
|
16
|
+
that are scoped, named, explained, and impossible for locked rules. See
|
|
17
|
+
[`legion-rules`](https://www.npmjs.com/package/legion-rules) for the rule
|
|
18
|
+
table and the tolerance levels.
|
|
19
|
+
|
|
20
|
+
## oxlint
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
yarn add -D eslint-plugin-legion oxlint
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```jsonc
|
|
27
|
+
// .oxlintrc.json
|
|
28
|
+
{
|
|
29
|
+
"jsPlugins": ["eslint-plugin-legion"],
|
|
30
|
+
"rules": {
|
|
31
|
+
"legion/no-narrative-comments": "error",
|
|
32
|
+
"legion/no-enum": "error",
|
|
33
|
+
},
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
To get a full preset instead of listing rules, generate the config from
|
|
38
|
+
`legion-rules`:
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
// scripts/sync-oxlintrc.ts
|
|
42
|
+
import { writeFileSync } from 'node:fs';
|
|
43
|
+
import { strict } from 'legion-rules';
|
|
44
|
+
|
|
45
|
+
writeFileSync('.oxlintrc.json', JSON.stringify(strict.oxlint, null, 2));
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## ESLint
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
yarn add -D eslint-plugin-legion eslint @typescript-eslint/parser
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
// eslint.config.mjs
|
|
56
|
+
import legion from 'eslint-plugin-legion';
|
|
57
|
+
import * as tsParser from '@typescript-eslint/parser';
|
|
58
|
+
|
|
59
|
+
export default [
|
|
60
|
+
{
|
|
61
|
+
files: ['**/*.ts', '**/*.tsx'],
|
|
62
|
+
languageOptions: {
|
|
63
|
+
parser: tsParser,
|
|
64
|
+
parserOptions: { ecmaFeatures: { jsx: true } },
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
...legion.configs.strict,
|
|
68
|
+
];
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`legion.configs.recommended` is the softer preset. For your own levels:
|
|
72
|
+
|
|
73
|
+
```js
|
|
74
|
+
import { legionEslintConfig } from 'eslint-plugin-legion';
|
|
75
|
+
|
|
76
|
+
export default [
|
|
77
|
+
...legionEslintConfig({ rules: { 'no-enum': 3 }, noTernary: 2 }),
|
|
78
|
+
];
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Pass `{ typescriptEslint: tsPlugin }` as the second argument to also wire
|
|
82
|
+
`@typescript-eslint/no-explicit-any` with the boundary overrides.
|
|
83
|
+
|
|
84
|
+
## The bypass
|
|
85
|
+
|
|
86
|
+
A rule at level 2 can be bypassed on one line, and only like this:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
// oxlint-disable-next-line legion/no-enum -- generated by the API client
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
File-wide disables, unnamed disables, disables without a reason, and any
|
|
93
|
+
disable of a rule at level 3 fail lint through `legion/scoped-disables`. The
|
|
94
|
+
one shape no lint rule can see, a bare `/* eslint-disable */` at the top of a
|
|
95
|
+
file, is caught by
|
|
96
|
+
[`legion-audit directives`](https://www.npmjs.com/package/legion-audit); put
|
|
97
|
+
it in front of your linter in the `lint` script.
|
|
98
|
+
|
|
99
|
+
## Requirements
|
|
100
|
+
|
|
101
|
+
Node 22 or newer. Peer: `oxlint >= 1.53` (JS plugins) or `eslint >= 9`, both
|
|
102
|
+
optional. No runtime dependencies beyond `legion-rules`.
|
|
103
|
+
|
|
104
|
+
MIT, Copyright (c) 2026 Veracium LLC.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { recommended as recommendedConfig, rules, strict as strictConfig } from 'legion-rules';
|
|
2
|
+
import type { EslintExtras, EslintFlatConfig, LegionConfig, LegionConfigInput } from 'legion-rules';
|
|
3
|
+
export interface LegionPlugin {
|
|
4
|
+
meta: {
|
|
5
|
+
name: string;
|
|
6
|
+
version: string;
|
|
7
|
+
};
|
|
8
|
+
rules: typeof rules;
|
|
9
|
+
configs: {
|
|
10
|
+
recommended: EslintFlatConfig[];
|
|
11
|
+
strict: EslintFlatConfig[];
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
declare const plugin: LegionPlugin;
|
|
15
|
+
export declare const legionEslintConfig: (config: LegionConfig | LegionConfigInput, extras?: EslintExtras) => EslintFlatConfig[];
|
|
16
|
+
export declare const legionOxlintConfig: (config: LegionConfigInput) => import("legion-rules").OxlintConfig;
|
|
17
|
+
export { recommendedConfig as recommended, strictConfig as strict, rules };
|
|
18
|
+
export default plugin;
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,WAAW,IAAI,iBAAiB,EAChC,KAAK,EACL,MAAM,IAAI,YAAY,EACvB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EAClB,MAAM,cAAc,CAAC;AAKtB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,OAAO,EAAE;QACP,WAAW,EAAE,gBAAgB,EAAE,CAAC;QAChC,MAAM,EAAE,gBAAgB,EAAE,CAAC;KAC5B,CAAC;CACH;AAED,QAAA,MAAM,MAAM,EAAE,YAIb,CAAC;AAKF,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,YAAY,GAAG,iBAAiB,EACxC,SAAS,YAAY,KACpB,gBAAgB,EAKlB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,QAAQ,iBAAiB,wCACzB,CAAC;AAEpC,OAAO,EAAE,iBAAiB,IAAI,WAAW,EAAE,YAAY,IAAI,MAAM,EAAE,KAAK,EAAE,CAAC;AAE3E,eAAe,MAAM,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { defineLegionConfig, recommended as recommendedConfig, rules, strict as strictConfig, } from 'legion-rules';
|
|
3
|
+
const require = createRequire(import.meta.url);
|
|
4
|
+
const { version } = require('../package.json');
|
|
5
|
+
const plugin = {
|
|
6
|
+
meta: { name: 'legion', version },
|
|
7
|
+
rules,
|
|
8
|
+
configs: { recommended: [], strict: [] },
|
|
9
|
+
};
|
|
10
|
+
plugin.configs.recommended = recommendedConfig.eslint(plugin);
|
|
11
|
+
plugin.configs.strict = strictConfig.eslint(plugin);
|
|
12
|
+
export const legionEslintConfig = (config, extras) => {
|
|
13
|
+
if ('eslint' in config && typeof config.eslint === 'function') {
|
|
14
|
+
return config.eslint(plugin, extras);
|
|
15
|
+
}
|
|
16
|
+
return defineLegionConfig(config).eslint(plugin, extras);
|
|
17
|
+
};
|
|
18
|
+
export const legionOxlintConfig = (config) => defineLegionConfig(config).oxlint;
|
|
19
|
+
export { recommendedConfig as recommended, strictConfig as strict, rules };
|
|
20
|
+
export default plugin;
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,kBAAkB,EAClB,WAAW,IAAI,iBAAiB,EAChC,KAAK,EACL,MAAM,IAAI,YAAY,GACvB,MAAM,cAAc,CAAC;AAQtB,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAWtE,MAAM,MAAM,GAAiB;IAC3B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE;IACjC,KAAK;IACL,OAAO,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;CACzC,CAAC;AAEF,MAAM,CAAC,OAAO,CAAC,WAAW,GAAG,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC9D,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAEpD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,MAAwC,EACxC,MAAqB,EACD,EAAE;IACtB,IAAI,QAAQ,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QAC9D,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,kBAAkB,CAAC,MAA2B,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAChF,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAyB,EAAE,EAAE,CAC9D,kBAAkB,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AAEpC,OAAO,EAAE,iBAAiB,IAAI,WAAW,EAAE,YAAY,IAAI,MAAM,EAAE,KAAK,EAAE,CAAC;AAE3E,eAAe,MAAM,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "eslint-plugin-legion",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "LEGION-STANDARDS as a lint plugin. Runs under oxlint (jsPlugins) and ESLint v9+. Zero comments, no React.FC, no enum, no ternaries, no function keyword, guarded context hooks, hydration-safe state, server-first pages, scoped lint bypasses.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Veracium LLC",
|
|
7
|
+
"homepage": "https://github.com/Kprince1101/legion-toolkit/tree/main/packages/eslint-plugin#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/Kprince1101/legion-toolkit.git",
|
|
11
|
+
"directory": "packages/eslint-plugin"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/Kprince1101/legion-toolkit/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"eslint",
|
|
18
|
+
"eslintplugin",
|
|
19
|
+
"eslint-plugin",
|
|
20
|
+
"oxlint",
|
|
21
|
+
"oxlint-plugin",
|
|
22
|
+
"react",
|
|
23
|
+
"nextjs",
|
|
24
|
+
"react-native",
|
|
25
|
+
"legion"
|
|
26
|
+
],
|
|
27
|
+
"type": "module",
|
|
28
|
+
"main": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"default": "./dist/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./package.json": "./package.json"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"!dist/**/*.test.*",
|
|
40
|
+
"!dist/**/__tests__",
|
|
41
|
+
"LICENSE",
|
|
42
|
+
"README.md"
|
|
43
|
+
],
|
|
44
|
+
"sideEffects": false,
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public",
|
|
47
|
+
"registry": "https://registry.npmjs.org/"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"legion-rules": "^0.1.0"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"eslint": ">=9",
|
|
54
|
+
"oxlint": ">=1.53"
|
|
55
|
+
},
|
|
56
|
+
"peerDependenciesMeta": {
|
|
57
|
+
"eslint": {
|
|
58
|
+
"optional": true
|
|
59
|
+
},
|
|
60
|
+
"oxlint": {
|
|
61
|
+
"optional": true
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"scripts": {
|
|
65
|
+
"build": "node ../../scripts/copy-license.ts && tsc -p tsconfig.build.json",
|
|
66
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true}); require('node:fs').rmSync('LICENSE',{force:true})\"",
|
|
67
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
68
|
+
"prepublishOnly": "node ../../scripts/require-ci.ts"
|
|
69
|
+
},
|
|
70
|
+
"engines": {
|
|
71
|
+
"node": ">=22"
|
|
72
|
+
}
|
|
73
|
+
}
|