@elaraai/eslint-plugin-east 1.0.4
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.md +31 -0
- package/README.md +87 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +18 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/rule.d.ts +8 -0
- package/dist/src/rule.d.ts.map +1 -0
- package/dist/src/rule.js +61 -0
- package/dist/src/rule.js.map +1 -0
- package/package.json +56 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
Copyright (c) 2025 Elara AI Pty Ltd
|
|
2
|
+
|
|
3
|
+
# Dual License — AGPL-3.0 / Commercial
|
|
4
|
+
|
|
5
|
+
This software is available under two licenses. You may choose which license applies to your use:
|
|
6
|
+
|
|
7
|
+
## Option 1: AGPL-3.0 (Open Source)
|
|
8
|
+
|
|
9
|
+
You may use, modify, and distribute this software under the terms of the GNU Affero General Public License v3.0.
|
|
10
|
+
|
|
11
|
+
This requires that if you use this software in a network service, you must make your complete source code available under AGPL-3.0.
|
|
12
|
+
|
|
13
|
+
Full text: https://www.gnu.org/licenses/agpl-3.0.html
|
|
14
|
+
|
|
15
|
+
## Option 2: Commercial License
|
|
16
|
+
|
|
17
|
+
If you wish to use this software without the source code disclosure requirements of AGPL-3.0, you must obtain a commercial license from Elara AI Pty Ltd.
|
|
18
|
+
|
|
19
|
+
Contact: support@elara.ai
|
|
20
|
+
|
|
21
|
+
## Contributions
|
|
22
|
+
|
|
23
|
+
Contributions are welcome. By submitting a pull request, you agree to license your contribution under both AGPL-3.0 and our commercial license terms.
|
|
24
|
+
|
|
25
|
+
## Governing Law
|
|
26
|
+
|
|
27
|
+
This license is governed by the laws of New South Wales, Australia.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
*Elara AI Pty Ltd*
|
package/README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# ESLint Plugin East
|
|
2
|
+
|
|
3
|
+
> East idiom diagnostics for ESLint — editor and CI
|
|
4
|
+
|
|
5
|
+
[](LICENSE.md)
|
|
6
|
+
[](https://nodejs.org)
|
|
7
|
+
|
|
8
|
+
**ESLint Plugin East** surfaces the [`@elaraai/east-diagnostics`](../east-diagnostics)
|
|
9
|
+
rule set — the same East idiom checks the Claude plugin runs at write-time — in
|
|
10
|
+
the editor (via the ESLint extension) and in CI (via `eslint` / `pnpm lint`).
|
|
11
|
+
|
|
12
|
+
It is one type-aware rule, `east/east-rules`, that runs the whole set against the
|
|
13
|
+
file's TypeScript program. Native TypeScript type errors are intentionally **not**
|
|
14
|
+
reported here — those are `tsc`'s job; this plugin only surfaces the East-specific
|
|
15
|
+
idioms `tsc` can't see.
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- **One rule, every East check** - `east/east-rules` runs the full east-diagnostics set.
|
|
20
|
+
- **Type-aware** - Bridges to the TS program via typescript-eslint `parserServices`.
|
|
21
|
+
- **Editor + CI** - Shows as squiggles through the ESLint VS Code extension and fails CI through `pnpm lint`.
|
|
22
|
+
- **Configurable** - Disable individual rules by name; tune rule options.
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install -D @elaraai/eslint-plugin-east @typescript-eslint/parser eslint
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
Requires **type-aware** linting (`@typescript-eslint/parser` with a `project`).
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
// eslint.config.js
|
|
36
|
+
import east from "@elaraai/eslint-plugin-east";
|
|
37
|
+
import tsParser from "@typescript-eslint/parser";
|
|
38
|
+
|
|
39
|
+
export default [
|
|
40
|
+
{
|
|
41
|
+
files: ["**/*.ts"],
|
|
42
|
+
languageOptions: {
|
|
43
|
+
parser: tsParser,
|
|
44
|
+
parserOptions: { projectService: true },
|
|
45
|
+
},
|
|
46
|
+
plugins: { east },
|
|
47
|
+
rules: { "east/east-rules": "warn" },
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or extend the bundled config: `export default [east.configs.recommended];`
|
|
53
|
+
|
|
54
|
+
## Options
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
"east/east-rules": ["warn", {
|
|
58
|
+
disabled: ["prefer-some-none"], // turn off specific rules by name
|
|
59
|
+
preferExplicitEastType: { mode: "all-raw-values" },
|
|
60
|
+
}]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Claude Code plugin
|
|
64
|
+
|
|
65
|
+
The East ecosystem also ships a [Claude Code](https://claude.com/claude-code) plugin — East language skills, example search, and preemptive diagnostics for East code — installed separately from the `elaraai` marketplace:
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
# Inside Claude Code
|
|
69
|
+
/plugin marketplace add elaraai/east-workspace
|
|
70
|
+
/plugin install east@elaraai
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# From a terminal
|
|
75
|
+
claude plugin marketplace add elaraai/east-workspace
|
|
76
|
+
claude plugin install east@elaraai
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## License
|
|
80
|
+
|
|
81
|
+
Dual-licensed:
|
|
82
|
+
- **Open Source**: [AGPL-3.0](LICENSE.md) - Free for open source use
|
|
83
|
+
- **Commercial**: Available for proprietary use - contact support@elara.ai
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
*Developed by [Elara AI Pty Ltd](https://elaraai.com/)*
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import type { ESLint } from "eslint";
|
|
6
|
+
declare const plugin: ESLint.Plugin;
|
|
7
|
+
export default plugin;
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,MAAM,EAAgB,MAAM,QAAQ,CAAC;AASnD,QAAA,MAAM,MAAM,EAAE,MAAM,CAAC,MAGpB,CAAC;AASF,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { eastRules } from "./rule.js";
|
|
2
|
+
// typescript-eslint's RuleModule is structurally an ESLint rule; the cast bridges
|
|
3
|
+
// the two slightly different RuleModule types.
|
|
4
|
+
const rules = {
|
|
5
|
+
"east-rules": eastRules,
|
|
6
|
+
};
|
|
7
|
+
const plugin = {
|
|
8
|
+
meta: { name: "@elaraai/eslint-plugin-east", version: "1.0.4" },
|
|
9
|
+
rules,
|
|
10
|
+
};
|
|
11
|
+
plugin.configs = {
|
|
12
|
+
recommended: {
|
|
13
|
+
plugins: { east: plugin },
|
|
14
|
+
rules: { "east/east-rules": "warn" },
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
export default plugin;
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,kFAAkF;AAClF,+CAA+C;AAC/C,MAAM,KAAK,GAAoC;IAC7C,YAAY,EAAE,SAAuC;CACtD,CAAC;AAEF,MAAM,MAAM,GAAkB;IAC5B,IAAI,EAAE,EAAE,IAAI,EAAE,6BAA6B,EAAE,OAAO,EAAE,OAAO,EAAE;IAC/D,KAAK;CACN,CAAC;AAEF,MAAM,CAAC,OAAO,GAAG;IACf,WAAW,EAAE;QACX,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;QACzB,KAAK,EAAE,EAAE,iBAAiB,EAAE,MAAM,EAAE;KACb;CAC1B,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
2
|
+
import { type EastRulesOptions } from "@elaraai/east-diagnostics";
|
|
3
|
+
export type Options = [EastRulesOptions];
|
|
4
|
+
export type MessageIds = "east";
|
|
5
|
+
export declare const eastRules: ESLintUtils.RuleModule<"east", Options, unknown, ESLintUtils.RuleListener> & {
|
|
6
|
+
name: string;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../src/rule.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAEhF,MAAM,MAAM,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC;AACzC,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAShC,eAAO,MAAM,SAAS;;CAiDpB,CAAC"}
|
package/dist/src/rule.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import * as ts from "typescript";
|
|
6
|
+
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
7
|
+
import { runEastRules } from "@elaraai/east-diagnostics";
|
|
8
|
+
const createRule = ESLintUtils.RuleCreator((name) => `https://github.com/elaraai/east/tree/main/libs/eslint-plugin-east#${name}`);
|
|
9
|
+
// One rule that runs the whole east-diagnostics set against the file's TS
|
|
10
|
+
// program (obtained via typescript-eslint parser services) and reports each
|
|
11
|
+
// diagnostic. Requires type-aware linting (parserOptions.project / projectService).
|
|
12
|
+
export const eastRules = createRule({
|
|
13
|
+
name: "east-rules",
|
|
14
|
+
meta: {
|
|
15
|
+
type: "problem",
|
|
16
|
+
docs: {
|
|
17
|
+
description: "East-specific idiom diagnostics: prefer some()/none, no redundant casts, no unexecuted East expressions, etc.",
|
|
18
|
+
},
|
|
19
|
+
messages: { east: "{{message}}" },
|
|
20
|
+
schema: [
|
|
21
|
+
{
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {
|
|
24
|
+
disabled: { type: "array", items: { type: "string" } },
|
|
25
|
+
preferExplicitEastType: {
|
|
26
|
+
type: "object",
|
|
27
|
+
properties: { mode: { type: "string", enum: ["under-determined", "all-raw-values"] } },
|
|
28
|
+
additionalProperties: false,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
additionalProperties: false,
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
defaultOptions: [{}],
|
|
36
|
+
create(context, [options]) {
|
|
37
|
+
return {
|
|
38
|
+
"Program:exit"() {
|
|
39
|
+
const services = ESLintUtils.getParserServices(context);
|
|
40
|
+
const program = services.program;
|
|
41
|
+
const sourceFile = program.getSourceFile(context.filename);
|
|
42
|
+
if (sourceFile === undefined)
|
|
43
|
+
return;
|
|
44
|
+
const diagnostics = runEastRules(ts, program, sourceFile, program.getTypeChecker(), options);
|
|
45
|
+
for (const d of diagnostics) {
|
|
46
|
+
const start = sourceFile.getLineAndCharacterOfPosition(d.start);
|
|
47
|
+
const end = sourceFile.getLineAndCharacterOfPosition(d.start + d.length);
|
|
48
|
+
context.report({
|
|
49
|
+
loc: {
|
|
50
|
+
start: { line: start.line + 1, column: start.character },
|
|
51
|
+
end: { line: end.line + 1, column: end.character },
|
|
52
|
+
},
|
|
53
|
+
messageId: "east",
|
|
54
|
+
data: { message: `[${d.ruleName}] ${d.messageText}` },
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule.js","sourceRoot":"","sources":["../../src/rule.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAyB,MAAM,2BAA2B,CAAC;AAKhF,MAAM,UAAU,GAAG,WAAW,CAAC,WAAW,CACxC,CAAC,IAAI,EAAE,EAAE,CAAC,qEAAqE,IAAI,EAAE,CACtF,CAAC;AAEF,0EAA0E;AAC1E,4EAA4E;AAC5E,oFAAoF;AACpF,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CAAsB;IACvD,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EACT,+GAA+G;SAClH;QACD,QAAQ,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE;QACjC,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;oBACtD,sBAAsB,EAAE;wBACtB,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,EAAE,EAAE;wBACtF,oBAAoB,EAAE,KAAK;qBAC5B;iBACF;gBACD,oBAAoB,EAAE,KAAK;aAC5B;SACF;KACF;IACD,cAAc,EAAE,CAAC,EAAE,CAAC;IACpB,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC;QACvB,OAAO;YACL,cAAc;gBACZ,MAAM,QAAQ,GAAG,WAAW,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;gBACxD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;gBACjC,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAC3D,IAAI,UAAU,KAAK,SAAS;oBAAE,OAAO;gBAErC,MAAM,WAAW,GAAG,YAAY,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,cAAc,EAAE,EAAE,OAAO,CAAC,CAAC;gBAC7F,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;oBAC5B,MAAM,KAAK,GAAG,UAAU,CAAC,6BAA6B,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;oBAChE,MAAM,GAAG,GAAG,UAAU,CAAC,6BAA6B,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;oBACzE,OAAO,CAAC,MAAM,CAAC;wBACb,GAAG,EAAE;4BACH,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE;4BACxD,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE;yBACnD;wBACD,SAAS,EAAE,MAAM;wBACjB,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,WAAW,EAAE,EAAE;qBACtD,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@elaraai/eslint-plugin-east",
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"license": "AGPL-3.0-or-later",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "ESLint plugin surfacing East-specific idiom diagnostics (the east-diagnostics rule set) in the editor and CI.",
|
|
7
|
+
"main": "dist/src/index.js",
|
|
8
|
+
"types": "dist/src/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/src/index.d.ts",
|
|
12
|
+
"default": "./dist/src/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/src",
|
|
17
|
+
"!dist/src/**/*.spec.*",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE.md"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/elaraai/east-workspace.git",
|
|
24
|
+
"directory": "libs/eslint-plugin-east"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"east",
|
|
28
|
+
"elara",
|
|
29
|
+
"eslint",
|
|
30
|
+
"eslintplugin",
|
|
31
|
+
"lint"
|
|
32
|
+
],
|
|
33
|
+
"author": "Elara AI Pty Ltd",
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=22.0.0"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"eslint": ">=9.0.0",
|
|
39
|
+
"typescript": ">=5.0.0"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@typescript-eslint/utils": "^8.42.0",
|
|
43
|
+
"@elaraai/east-diagnostics": "1.0.4"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "^22.18.1",
|
|
47
|
+
"@typescript-eslint/parser": "^8.42.0",
|
|
48
|
+
"eslint": "^9.34.0",
|
|
49
|
+
"typescript": "~5.9.2",
|
|
50
|
+
"@elaraai/east": "1.0.4"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsc",
|
|
54
|
+
"test": "npm run build && node --enable-source-maps --test-reporter=spec --test 'dist/test/**/*.spec.js'"
|
|
55
|
+
}
|
|
56
|
+
}
|