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 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.
@@ -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
+ }