eslint-cdk-plugin 0.3.2 → 1.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/CONTRIBUTING.md +105 -0
- package/README.md +51 -6
- package/VERSIONING_POLICY.md +34 -0
- package/assets/logo.png +0 -0
- package/dist/index.d.mts +31 -0
- package/dist/index.mjs +9 -2
- package/dist/index.mjs.map +1 -0
- package/dist/no-class-in-interface-props.d.mts +2 -0
- package/dist/{no-class-in-interface.mjs → no-class-in-interface-props.mjs} +13 -14
- package/dist/no-class-in-interface-props.mjs.map +1 -0
- package/dist/no-construct-stack-suffix.d.mts +2 -0
- package/dist/no-construct-stack-suffix.mjs +20 -148
- package/dist/no-construct-stack-suffix.mjs.map +1 -0
- package/dist/no-import-private.d.mts +2 -0
- package/dist/no-import-private.mjs +18 -24
- package/dist/no-import-private.mjs.map +1 -0
- package/dist/no-mutable-props-interface.d.mts +2 -0
- package/dist/no-mutable-props-interface.mjs +14 -19
- package/dist/no-mutable-props-interface.mjs.map +1 -0
- package/dist/no-mutable-public-fields.d.mts +2 -0
- package/dist/no-mutable-public-fields.mjs +26 -25
- package/dist/no-mutable-public-fields.mjs.map +1 -0
- package/dist/no-parent-name-construct-id-match.d.mts +2 -0
- package/dist/no-parent-name-construct-id-match.mjs +101 -140
- package/dist/no-parent-name-construct-id-match.mjs.map +1 -0
- package/dist/no-public-class-fields.d.mts +2 -0
- package/dist/no-public-class-fields.mjs +40 -46
- package/dist/no-public-class-fields.mjs.map +1 -0
- package/dist/no-variable-construct-id.d.mts +2 -0
- package/dist/no-variable-construct-id.mjs +63 -0
- package/dist/no-variable-construct-id.mjs.map +1 -0
- package/dist/pascal-case-construct-id.d.mts +2 -0
- package/dist/pascal-case-construct-id.mjs +40 -47
- package/dist/pascal-case-construct-id.mjs.map +1 -0
- package/dist/require-passing-this.d.mts +2 -0
- package/dist/require-passing-this.mjs +39 -0
- package/dist/require-passing-this.mjs.map +1 -0
- package/dist/utils/convertString.d.mts +1 -0
- package/dist/utils/convertString.mjs +4 -9
- package/dist/utils/convertString.mjs.map +1 -0
- package/dist/utils/typeCheck.d.mts +3 -0
- package/dist/utils/typeCheck.mjs +16 -0
- package/dist/utils/typeCheck.mjs.map +1 -0
- package/package.json +6 -3
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Contributing to eslint-cdk-plugin
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to eslint-cdk-plugin!
|
|
4
|
+
This document provides guidelines and steps for contributing.
|
|
5
|
+
|
|
6
|
+
## Code of Conduct
|
|
7
|
+
|
|
8
|
+
By participating in this project, you are expected to uphold our Code of Conduct.
|
|
9
|
+
Please report unacceptable behavior to `@ren-yamanashi`.
|
|
10
|
+
|
|
11
|
+
## How to Contribute
|
|
12
|
+
|
|
13
|
+
### Create Bugs Issue
|
|
14
|
+
|
|
15
|
+
Before creating issue, please check the existing issues to avoid duplicates.
|
|
16
|
+
When you create a bug issue, include as following content:
|
|
17
|
+
|
|
18
|
+
- A clear and descriptive title
|
|
19
|
+
- Steps to reproduce the behavior
|
|
20
|
+
- Expected behavior
|
|
21
|
+
- Actual behavior
|
|
22
|
+
- Code samples if applicable
|
|
23
|
+
- Version information (Node.js, ESLint)
|
|
24
|
+
|
|
25
|
+
### Create Feature Request Issue
|
|
26
|
+
|
|
27
|
+
We welcome suggestions for new rules!
|
|
28
|
+
When proposing a new rule:
|
|
29
|
+
|
|
30
|
+
1. First, check existing rules and issues to avoid duplicates
|
|
31
|
+
2. Create an issue with the following information:
|
|
32
|
+
- Rule name
|
|
33
|
+
- Description of the problem the rule solves
|
|
34
|
+
- Examples of code that should pass/fail
|
|
35
|
+
- References to AWS CDK best practices if applicable
|
|
36
|
+
|
|
37
|
+
### Pull Requests
|
|
38
|
+
|
|
39
|
+
1. Fork the repo and create your branch from `main`
|
|
40
|
+
2. Implement the rules
|
|
41
|
+
3. Implement the test for the rule and make sure it passes. (Tests are run in CI)
|
|
42
|
+
4. Update the documentation
|
|
43
|
+
5. Create a pull request
|
|
44
|
+
|
|
45
|
+
#### Development Setup
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Clone your fork
|
|
49
|
+
https://github.com/ren-yamanashi/eslint-cdk-plugin.git
|
|
50
|
+
|
|
51
|
+
# Install dependencies
|
|
52
|
+
pnpm install
|
|
53
|
+
|
|
54
|
+
# Run tests
|
|
55
|
+
pnpm test
|
|
56
|
+
|
|
57
|
+
# Run linter
|
|
58
|
+
pnpm lint
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
#### Creating a New Rule
|
|
62
|
+
|
|
63
|
+
1. Create a new file in `src`(file name should same rule name)
|
|
64
|
+
2. Create corresponding test file in `src/__tests__`
|
|
65
|
+
3. Add rule to `src/index.ts`
|
|
66
|
+
4. Add documentation in `docs`
|
|
67
|
+
|
|
68
|
+
Note: Writing the document is optional (because it is written using Vitepress and is not yet ready to accept contributions)
|
|
69
|
+
|
|
70
|
+
Example rule structure:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
74
|
+
|
|
75
|
+
export const newRule = ESLintUtils.RuleCreator.withoutDocs({
|
|
76
|
+
meta: {
|
|
77
|
+
type: "problem",
|
|
78
|
+
docs: {
|
|
79
|
+
description: "Rule description",
|
|
80
|
+
},
|
|
81
|
+
messages: {
|
|
82
|
+
ruleError: "Error message with {{ placeholder }}",
|
|
83
|
+
},
|
|
84
|
+
schema: [],
|
|
85
|
+
},
|
|
86
|
+
defaultOptions: [],
|
|
87
|
+
create(context) {
|
|
88
|
+
// Rule implementation
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Merge Process
|
|
94
|
+
|
|
95
|
+
1. Changes are merged to `main`
|
|
96
|
+
2. Maintainers will review and merge
|
|
97
|
+
3. Publish to npm according to Milestone
|
|
98
|
+
|
|
99
|
+
## Questions?
|
|
100
|
+
|
|
101
|
+
Feel free to create an issue for any questions about contributing!
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
By contributing, you agree that your contributions will be licensed under the project's MIT License.
|
package/README.md
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img width="160px" height="160px" src="./assets/logo.png" alt="ESLint plugin for AWS CDK logo">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">eslint-cdk-plugin</h1>
|
|
6
|
+
<p align="center">ESLint plugin for AWS CDK</p>
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/eslint-cdk-plugin">
|
|
9
|
+
<img src="https://img.shields.io/npm/v/eslint-cdk-plugin.svg" alt="NPM">
|
|
10
|
+
</a>
|
|
11
|
+
</p>
|
|
4
12
|
|
|
5
|
-
##
|
|
13
|
+
## 📔 Documentation
|
|
14
|
+
|
|
15
|
+
Please refer to the [website](https://eslint-cdk-plugin.dev/).
|
|
16
|
+
|
|
17
|
+
## 📦 Installation
|
|
6
18
|
|
|
7
19
|
```bash
|
|
8
20
|
# npm
|
|
@@ -15,9 +27,9 @@ yarn add -D eslint-cdk-plugin
|
|
|
15
27
|
pnpm install -D eslint-cdk-plugin
|
|
16
28
|
```
|
|
17
29
|
|
|
18
|
-
## Usage
|
|
30
|
+
## 🚀 Usage
|
|
19
31
|
|
|
20
|
-
|
|
32
|
+
#### Use recommended config
|
|
21
33
|
|
|
22
34
|
```js
|
|
23
35
|
// eslint.config.mjs
|
|
@@ -34,4 +46,37 @@ export default [
|
|
|
34
46
|
];
|
|
35
47
|
```
|
|
36
48
|
|
|
37
|
-
|
|
49
|
+
#### Use custom config
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
// eslint.config.mjs
|
|
53
|
+
import eslintCdkPlugin from "eslint-cdk-plugin";
|
|
54
|
+
export default [
|
|
55
|
+
{
|
|
56
|
+
plugins: {
|
|
57
|
+
cdk: eslintCdkPlugin,
|
|
58
|
+
},
|
|
59
|
+
rules: {
|
|
60
|
+
"cdk/no-class-in-interface": "error",
|
|
61
|
+
"cdk/no-construct-stack-suffix": "error",
|
|
62
|
+
"cdk/no-parent-name-construct-id-match": "error",
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## ❗ Issue
|
|
69
|
+
|
|
70
|
+
If you have any questions or suggestions, please open an [issue](https://github.com/ren-yamanashi/eslint-cdk-plugin/issues).
|
|
71
|
+
|
|
72
|
+
## 💪 Contribution
|
|
73
|
+
|
|
74
|
+
Contributions are welcome! Please see [Contribution Guide](./CONTRIBUTING.md) for more details.
|
|
75
|
+
|
|
76
|
+
## ⚓ Versioning Policy
|
|
77
|
+
|
|
78
|
+
Please see [Versioning Policy](./VERSIONING_POLICY.md).
|
|
79
|
+
|
|
80
|
+
## ©️ License
|
|
81
|
+
|
|
82
|
+
[MIT](http://opensource.org/licenses/MIT)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
## Semantic Versioning Policy
|
|
2
|
+
|
|
3
|
+
eslint-cdk-plugin follows semantic versioning. To clarify when a minor or major version bump occurs, we've defined the following semantic versioning policy:
|
|
4
|
+
|
|
5
|
+
### Patch Release (intended to not break your lint build)
|
|
6
|
+
|
|
7
|
+
- A bug fix in a rule that results in fewer linting errors
|
|
8
|
+
- A bug fix to the core functionality
|
|
9
|
+
- Improvements to documentation
|
|
10
|
+
- Non-user-facing changes such as refactoring code, adding/modifying tests, and increasing test coverage
|
|
11
|
+
- Re-releasing after a failed release
|
|
12
|
+
|
|
13
|
+
### Minor Release (might break your lint build)
|
|
14
|
+
|
|
15
|
+
- A bug fix in a rule that results in more linting errors
|
|
16
|
+
- A new rule is added (disabled by default)
|
|
17
|
+
- A new option to an existing rule that does not result in more linting errors by default
|
|
18
|
+
- An existing rule is deprecated
|
|
19
|
+
|
|
20
|
+
### Major Release (likely to break your lint build)
|
|
21
|
+
|
|
22
|
+
- `recommended` config is updated and may result in new linting errors
|
|
23
|
+
- A new rule is added (enabled by default)
|
|
24
|
+
- Removing deprecated rules or functionality
|
|
25
|
+
- Changes that require a new minimum version of Node.js or ESLint
|
|
26
|
+
|
|
27
|
+
### Version Pinning Recommendations
|
|
28
|
+
|
|
29
|
+
We recommend using one of the following approaches in your `package.json`:
|
|
30
|
+
|
|
31
|
+
- Use tilde (`~`) to allow only patch releases: `"eslint-cdk-plugin": "~1.1.0"`
|
|
32
|
+
- Use caret (`^`) if you're comfortable with minor updates: `"eslint-cdk-plugin": "^1.1.0"`
|
|
33
|
+
|
|
34
|
+
Note that minor updates may report more linting errors than the previous release, so using tilde is recommended for more stable builds.
|
package/assets/logo.png
ADDED
|
Binary file
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
declare const plugin: {
|
|
2
|
+
rules: {
|
|
3
|
+
"no-class-in-interface": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noClassInInterfaceProps", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
4
|
+
"no-construct-stack-suffix": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noConstructStackSuffix", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
|
+
"no-import-private": import("eslint").Rule.RuleModule;
|
|
6
|
+
"no-parent-name-construct-id-match": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noParentNameConstructIdMatch", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
7
|
+
"no-public-class-fields": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noPublicClassFields", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
8
|
+
"pascal-case-construct-id": import("@typescript-eslint/utils/ts-eslint").RuleModule<"pascalCaseConstructId", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
9
|
+
"no-mutable-public-fields": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noMutablePublicFields", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
10
|
+
"no-mutable-props-interface": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noMutablePropsInterface", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
11
|
+
"require-passing-this": import("@typescript-eslint/utils/ts-eslint").RuleModule<"requirePassingThis", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
12
|
+
"no-variable-construct-id": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noVariableConstructId", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
13
|
+
};
|
|
14
|
+
configs: {
|
|
15
|
+
recommended: {
|
|
16
|
+
plugins: string[];
|
|
17
|
+
rules: {
|
|
18
|
+
"cdk/no-class-in-interface": string;
|
|
19
|
+
"cdk/no-construct-stack-suffix": string;
|
|
20
|
+
"cdk/no-parent-name-construct-id-match": string;
|
|
21
|
+
"cdk/no-public-class-fields": string;
|
|
22
|
+
"cdk/pascal-case-construct-id": string;
|
|
23
|
+
"cdk/require-passing-this": string;
|
|
24
|
+
"cdk/no-variable-construct-id": string;
|
|
25
|
+
"cdk/no-mutable-public-fields": string;
|
|
26
|
+
"cdk/no-mutable-props-interface": string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export default plugin;
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { noClassInInterfaceProps } from "./no-class-in-interface.mjs";
|
|
1
|
+
import { noClassInInterfaceProps } from "./no-class-in-interface-props.mjs";
|
|
2
2
|
import { noConstructStackSuffix } from "./no-construct-stack-suffix.mjs";
|
|
3
3
|
import { noImportPrivate } from "./no-import-private.mjs";
|
|
4
4
|
import { noMutablePropsInterface } from "./no-mutable-props-interface.mjs";
|
|
5
5
|
import { noMutablePublicFields } from "./no-mutable-public-fields.mjs";
|
|
6
6
|
import { noParentNameConstructIdMatch } from "./no-parent-name-construct-id-match.mjs";
|
|
7
7
|
import { noPublicClassFields } from "./no-public-class-fields.mjs";
|
|
8
|
+
import { noVariableConstructId } from "./no-variable-construct-id.mjs";
|
|
8
9
|
import { pascalCaseConstructId } from "./pascal-case-construct-id.mjs";
|
|
9
|
-
|
|
10
|
+
import { requirePassingThis } from "./require-passing-this.mjs";
|
|
11
|
+
const plugin = {
|
|
10
12
|
rules: {
|
|
11
13
|
"no-class-in-interface": noClassInInterfaceProps,
|
|
12
14
|
"no-construct-stack-suffix": noConstructStackSuffix,
|
|
@@ -16,6 +18,8 @@ var plugin = {
|
|
|
16
18
|
"pascal-case-construct-id": pascalCaseConstructId,
|
|
17
19
|
"no-mutable-public-fields": noMutablePublicFields,
|
|
18
20
|
"no-mutable-props-interface": noMutablePropsInterface,
|
|
21
|
+
"require-passing-this": requirePassingThis,
|
|
22
|
+
"no-variable-construct-id": noVariableConstructId,
|
|
19
23
|
},
|
|
20
24
|
configs: {
|
|
21
25
|
recommended: {
|
|
@@ -26,6 +30,8 @@ var plugin = {
|
|
|
26
30
|
"cdk/no-parent-name-construct-id-match": "error",
|
|
27
31
|
"cdk/no-public-class-fields": "error",
|
|
28
32
|
"cdk/pascal-case-construct-id": "error",
|
|
33
|
+
"cdk/require-passing-this": "error",
|
|
34
|
+
"cdk/no-variable-construct-id": "error",
|
|
29
35
|
"cdk/no-mutable-public-fields": "warn",
|
|
30
36
|
"cdk/no-mutable-props-interface": "warn",
|
|
31
37
|
},
|
|
@@ -33,3 +39,4 @@ var plugin = {
|
|
|
33
39
|
},
|
|
34
40
|
};
|
|
35
41
|
export default plugin;
|
|
42
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,4BAA4B,EAAE,MAAM,yCAAyC,CAAC;AACvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,MAAM,MAAM,GAAG;IACb,KAAK,EAAE;QACL,uBAAuB,EAAE,uBAAuB;QAChD,2BAA2B,EAAE,sBAAsB;QACnD,mBAAmB,EAAE,eAAe;QACpC,mCAAmC,EAAE,4BAA4B;QACjE,wBAAwB,EAAE,mBAAmB;QAC7C,0BAA0B,EAAE,qBAAqB;QACjD,0BAA0B,EAAE,qBAAqB;QACjD,4BAA4B,EAAE,uBAAuB;QACrD,sBAAsB,EAAE,kBAAkB;QAC1C,0BAA0B,EAAE,qBAAqB;KAClD;IACD,OAAO,EAAE;QACP,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,KAAK,CAAC;YAChB,KAAK,EAAE;gBACL,2BAA2B,EAAE,OAAO;gBACpC,+BAA+B,EAAE,OAAO;gBACxC,uCAAuC,EAAE,OAAO;gBAChD,4BAA4B,EAAE,OAAO;gBACrC,8BAA8B,EAAE,OAAO;gBACvC,0BAA0B,EAAE,OAAO;gBACnC,8BAA8B,EAAE,OAAO;gBACvC,8BAA8B,EAAE,MAAM;gBACtC,gCAAgC,EAAE,MAAM;aACzC;SACF;KACF;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
1
|
+
import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
|
|
2
2
|
import { SymbolFlags } from "typescript";
|
|
3
|
-
export
|
|
3
|
+
export const noClassInInterfaceProps = ESLintUtils.RuleCreator.withoutDocs({
|
|
4
4
|
meta: {
|
|
5
5
|
type: "problem",
|
|
6
6
|
docs: {
|
|
@@ -12,23 +12,21 @@ export var noClassInInterfaceProps = ESLintUtils.RuleCreator.withoutDocs({
|
|
|
12
12
|
schema: [],
|
|
13
13
|
},
|
|
14
14
|
defaultOptions: [],
|
|
15
|
-
create
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
create(context) {
|
|
16
|
+
const parserServices = ESLintUtils.getParserServices(context);
|
|
17
|
+
const typeChecker = parserServices.program.getTypeChecker();
|
|
18
18
|
return {
|
|
19
|
-
TSInterfaceDeclaration
|
|
20
|
-
for (
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
property.key.type !== "Identifier") {
|
|
19
|
+
TSInterfaceDeclaration(node) {
|
|
20
|
+
for (const property of node.body.body) {
|
|
21
|
+
if (property.type !== AST_NODE_TYPES.TSPropertySignature ||
|
|
22
|
+
property.key.type !== AST_NODE_TYPES.Identifier) {
|
|
24
23
|
continue;
|
|
25
24
|
}
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(property);
|
|
26
|
+
const type = typeChecker.getTypeAtLocation(tsNode);
|
|
28
27
|
if (!type.symbol)
|
|
29
28
|
continue;
|
|
30
|
-
|
|
31
|
-
var isClass = type.symbol.flags === SymbolFlags.Class;
|
|
29
|
+
const isClass = type.symbol.flags === SymbolFlags.Class;
|
|
32
30
|
if (!isClass)
|
|
33
31
|
continue;
|
|
34
32
|
context.report({
|
|
@@ -44,3 +42,4 @@ export var noClassInInterfaceProps = ESLintUtils.RuleCreator.withoutDocs({
|
|
|
44
42
|
};
|
|
45
43
|
},
|
|
46
44
|
});
|
|
45
|
+
//# sourceMappingURL=no-class-in-interface-props.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-class-in-interface-props.mjs","sourceRoot":"","sources":["../src/no-class-in-interface-props.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAQzC,MAAM,CAAC,MAAM,uBAAuB,GAAG,WAAW,CAAC,WAAW,CAAC,WAAW,CAAC;IACzE,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,8CAA8C;SAC5D;QACD,QAAQ,EAAE;YACR,uBAAuB,EACrB,wIAAwI;SAC3I;QACD,MAAM,EAAE,EAAE;KACX;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,MAAM,cAAc,GAAG,WAAW,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC9D,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC5D,OAAO;YACL,sBAAsB,CAAC,IAAI;gBACzB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;oBAEtC,IACE,QAAQ,CAAC,IAAI,KAAK,cAAc,CAAC,mBAAmB;wBACpD,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU,EAC/C,CAAC;wBACD,SAAS;oBACX,CAAC;oBAED,MAAM,MAAM,GAAG,cAAc,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;oBAClE,MAAM,IAAI,GAAG,WAAW,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;oBACnD,IAAI,CAAC,IAAI,CAAC,MAAM;wBAAE,SAAS;oBAG3B,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,WAAW,CAAC,KAAK,CAAC;oBACxD,IAAI,CAAC,OAAO;wBAAE,SAAS;oBAEvB,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI,EAAE,QAAQ;wBACd,SAAS,EAAE,yBAAyB;wBACpC,IAAI,EAAE;4BACJ,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI;4BAC/B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;yBAC3B;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
1
|
+
import { AST_NODE_TYPES, ESLintUtils, } from "@typescript-eslint/utils";
|
|
2
2
|
import { toPascalCase } from "./utils/convertString.mjs";
|
|
3
|
-
|
|
3
|
+
import { isConstructOrStackType } from "./utils/typeCheck.mjs";
|
|
4
|
+
export const noConstructStackSuffix = ESLintUtils.RuleCreator.withoutDocs({
|
|
4
5
|
meta: {
|
|
5
6
|
type: "problem",
|
|
6
7
|
docs: {
|
|
@@ -12,164 +13,34 @@ export var noConstructStackSuffix = ESLintUtils.RuleCreator.withoutDocs({
|
|
|
12
13
|
schema: [],
|
|
13
14
|
},
|
|
14
15
|
defaultOptions: [],
|
|
15
|
-
create
|
|
16
|
+
create(context) {
|
|
17
|
+
const parserServices = ESLintUtils.getParserServices(context);
|
|
18
|
+
const typeChecker = parserServices.program.getTypeChecker();
|
|
16
19
|
return {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if ((parent === null || parent === void 0 ? void 0 : parent.type) !== "ClassDeclaration")
|
|
20
|
+
NewExpression(node) {
|
|
21
|
+
const type = typeChecker.getTypeAtLocation(parserServices.esTreeNodeToTSNodeMap.get(node));
|
|
22
|
+
if (!isConstructOrStackType(type)) {
|
|
21
23
|
return;
|
|
22
|
-
var className = (_a = parent.id) === null || _a === void 0 ? void 0 : _a.name;
|
|
23
|
-
if (!className)
|
|
24
|
-
return;
|
|
25
|
-
for (var _i = 0, _b = node.body; _i < _b.length; _i++) {
|
|
26
|
-
var body = _b[_i];
|
|
27
|
-
if (body.type !== "MethodDefinition" ||
|
|
28
|
-
!["method", "constructor"].includes(body.kind) ||
|
|
29
|
-
body.value.type !== "FunctionExpression") {
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
validateConstructorBody(node, body.value, context);
|
|
33
24
|
}
|
|
25
|
+
if (node.arguments.length < 2)
|
|
26
|
+
return;
|
|
27
|
+
validateConstructId(node, context, node);
|
|
34
28
|
},
|
|
35
29
|
};
|
|
36
30
|
},
|
|
37
31
|
});
|
|
38
|
-
|
|
39
|
-
* Validate the constructor body for the parent class
|
|
40
|
-
* - validate each statement in the constructor body
|
|
41
|
-
*/
|
|
42
|
-
var validateConstructorBody = function (node, expression, context) {
|
|
43
|
-
var _a;
|
|
44
|
-
for (var _i = 0, _b = expression.body.body; _i < _b.length; _i++) {
|
|
45
|
-
var statement = _b[_i];
|
|
46
|
-
switch (statement.type) {
|
|
47
|
-
case "VariableDeclaration": {
|
|
48
|
-
var newExpression = statement.declarations[0].init;
|
|
49
|
-
if ((newExpression === null || newExpression === void 0 ? void 0 : newExpression.type) !== "NewExpression")
|
|
50
|
-
continue;
|
|
51
|
-
validateConstructId(node, context, newExpression);
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
case "ExpressionStatement": {
|
|
55
|
-
if (((_a = statement.expression) === null || _a === void 0 ? void 0 : _a.type) !== "NewExpression")
|
|
56
|
-
break;
|
|
57
|
-
validateStatement(node, statement, context);
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
60
|
-
case "IfStatement": {
|
|
61
|
-
traverseStatements(node, statement.consequent, context);
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
case "SwitchStatement": {
|
|
65
|
-
for (var _c = 0, _d = statement.cases; _c < _d.length; _c++) {
|
|
66
|
-
var switchCase = _d[_c];
|
|
67
|
-
for (var _e = 0, _f = switchCase.consequent; _e < _f.length; _e++) {
|
|
68
|
-
var statement_1 = _f[_e];
|
|
69
|
-
traverseStatements(node, statement_1, context);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
/**
|
|
78
|
-
* Recursively traverse and validate statements in the AST
|
|
79
|
-
* - Handles BlockStatement, ExpressionStatement, and VariableDeclaration
|
|
80
|
-
* - Validates construct IDs
|
|
81
|
-
*/
|
|
82
|
-
var traverseStatements = function (node, statement, context) {
|
|
83
|
-
switch (statement.type) {
|
|
84
|
-
case "BlockStatement": {
|
|
85
|
-
for (var _i = 0, _a = statement.body; _i < _a.length; _i++) {
|
|
86
|
-
var body = _a[_i];
|
|
87
|
-
validateStatement(node, body, context);
|
|
88
|
-
}
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
case "ExpressionStatement": {
|
|
92
|
-
var newExpression = statement.expression;
|
|
93
|
-
if ((newExpression === null || newExpression === void 0 ? void 0 : newExpression.type) !== "NewExpression")
|
|
94
|
-
break;
|
|
95
|
-
validateStatement(node, statement, context);
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
|
-
case "VariableDeclaration": {
|
|
99
|
-
var newExpression = statement.declarations[0].init;
|
|
100
|
-
if ((newExpression === null || newExpression === void 0 ? void 0 : newExpression.type) !== "NewExpression")
|
|
101
|
-
break;
|
|
102
|
-
validateConstructId(node, context, newExpression);
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
/**
|
|
108
|
-
* Validate a single statement in the AST
|
|
109
|
-
* - Handles different types of statements (Variable, Expression, If, Switch)
|
|
110
|
-
* - Extracts and validates construct IDs from new expressions
|
|
111
|
-
*/
|
|
112
|
-
var validateStatement = function (node, body, context) {
|
|
113
|
-
switch (body.type) {
|
|
114
|
-
case "VariableDeclaration": {
|
|
115
|
-
var newExpression = body.declarations[0].init;
|
|
116
|
-
if ((newExpression === null || newExpression === void 0 ? void 0 : newExpression.type) !== "NewExpression")
|
|
117
|
-
break;
|
|
118
|
-
validateConstructId(node, context, newExpression);
|
|
119
|
-
break;
|
|
120
|
-
}
|
|
121
|
-
case "ExpressionStatement": {
|
|
122
|
-
var newExpression = body.expression;
|
|
123
|
-
if ((newExpression === null || newExpression === void 0 ? void 0 : newExpression.type) !== "NewExpression")
|
|
124
|
-
break;
|
|
125
|
-
validateConstructId(node, context, newExpression);
|
|
126
|
-
break;
|
|
127
|
-
}
|
|
128
|
-
case "IfStatement": {
|
|
129
|
-
validateIfStatement(node, body, context);
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
case "SwitchStatement": {
|
|
133
|
-
validateSwitchStatement(node, body, context);
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
/**
|
|
139
|
-
* Validate the `if` statement
|
|
140
|
-
* - Validate recursively if `if` statements are nested
|
|
141
|
-
*/
|
|
142
|
-
var validateIfStatement = function (node, ifStatement, context) {
|
|
143
|
-
traverseStatements(node, ifStatement.consequent, context);
|
|
144
|
-
};
|
|
145
|
-
/**
|
|
146
|
-
* Validate the `switch` statement
|
|
147
|
-
* - Validate recursively if `switch` statements are nested
|
|
148
|
-
*/
|
|
149
|
-
var validateSwitchStatement = function (node, switchStatement, context) {
|
|
150
|
-
for (var _i = 0, _a = switchStatement.cases; _i < _a.length; _i++) {
|
|
151
|
-
var statement = _a[_i];
|
|
152
|
-
for (var _b = 0, _c = statement.consequent; _b < _c.length; _b++) {
|
|
153
|
-
var _consequent = _c[_b];
|
|
154
|
-
traverseStatements(node, _consequent, context);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
/**
|
|
159
|
-
* Validate that construct ID does not end with "Construct" or "Stack"
|
|
160
|
-
*/
|
|
161
|
-
var validateConstructId = function (node, context, expression) {
|
|
32
|
+
const validateConstructId = (node, context, expression) => {
|
|
162
33
|
if (expression.arguments.length < 2)
|
|
163
34
|
return;
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
35
|
+
const secondArg = expression.arguments[1];
|
|
36
|
+
if (secondArg.type !== AST_NODE_TYPES.Literal ||
|
|
37
|
+
typeof secondArg.value !== "string") {
|
|
167
38
|
return;
|
|
168
39
|
}
|
|
169
|
-
|
|
40
|
+
const formattedConstructId = toPascalCase(secondArg.value);
|
|
170
41
|
if (formattedConstructId.endsWith("Construct")) {
|
|
171
42
|
context.report({
|
|
172
|
-
node
|
|
43
|
+
node,
|
|
173
44
|
messageId: "noConstructStackSuffix",
|
|
174
45
|
data: {
|
|
175
46
|
classType: "Construct",
|
|
@@ -180,7 +51,7 @@ var validateConstructId = function (node, context, expression) {
|
|
|
180
51
|
}
|
|
181
52
|
else if (formattedConstructId.endsWith("Stack")) {
|
|
182
53
|
context.report({
|
|
183
|
-
node
|
|
54
|
+
node,
|
|
184
55
|
messageId: "noConstructStackSuffix",
|
|
185
56
|
data: {
|
|
186
57
|
classType: "Stack",
|
|
@@ -190,3 +61,4 @@ var validateConstructId = function (node, context, expression) {
|
|
|
190
61
|
});
|
|
191
62
|
}
|
|
192
63
|
};
|
|
64
|
+
//# sourceMappingURL=no-construct-stack-suffix.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-construct-stack-suffix.mjs","sourceRoot":"","sources":["../src/no-construct-stack-suffix.mts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,WAAW,GAGZ,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAU/D,MAAM,CAAC,MAAM,sBAAsB,GAAG,WAAW,CAAC,WAAW,CAAC,WAAW,CAAC;IACxE,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EACT,uEAAuE;SAC1E;QACD,QAAQ,EAAE;YACR,sBAAsB,EACpB,uEAAuE;SAC1E;QACD,MAAM,EAAE,EAAE;KACX;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,MAAM,cAAc,GAAG,WAAW,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC9D,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC5D,OAAO;YACL,aAAa,CAAC,IAAI;gBAChB,MAAM,IAAI,GAAG,WAAW,CAAC,iBAAiB,CACxC,cAAc,CAAC,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,CAC/C,CAAC;gBACF,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClC,OAAO;gBACT,CAAC;gBAED,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;oBAAE,OAAO;gBAEtC,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YAC3C,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC;AAKH,MAAM,mBAAmB,GAAG,CAC1B,IAAmB,EACnB,OAAgB,EAChB,UAAkC,EAC5B,EAAE;IACR,IAAI,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO;IAG5C,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC1C,IACE,SAAS,CAAC,IAAI,KAAK,cAAc,CAAC,OAAO;QACzC,OAAO,SAAS,CAAC,KAAK,KAAK,QAAQ,EACnC,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,oBAAoB,GAAG,YAAY,CAAC,SAAS,CAAC,KAAe,CAAC,CAAC;IAErE,IAAI,oBAAoB,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/C,OAAO,CAAC,MAAM,CAAC;YACb,IAAI;YACJ,SAAS,EAAE,wBAAwB;YACnC,IAAI,EAAE;gBACJ,SAAS,EAAE,WAAW;gBACtB,EAAE,EAAE,SAAS,CAAC,KAAK;gBACnB,MAAM,EAAE,WAAW;aACpB;SACF,CAAC,CAAC;IACL,CAAC;SAAM,IAAI,oBAAoB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAClD,OAAO,CAAC,MAAM,CAAC;YACb,IAAI;YACJ,SAAS,EAAE,wBAAwB;YACnC,IAAI,EAAE;gBACJ,SAAS,EAAE,OAAO;gBAClB,EAAE,EAAE,SAAS,CAAC,KAAK;gBACnB,MAAM,EAAE,OAAO;aAChB;SACF,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
import * as path from "path";
|
|
2
|
-
|
|
3
|
-
* Split the directory path into segments (split at `/`)
|
|
4
|
-
* @param dirPath - The directory path to split
|
|
5
|
-
* @returns The segments of the directory path
|
|
6
|
-
*/
|
|
7
|
-
var getDirSegments = function (dirPath) {
|
|
8
|
-
return dirPath.split(path.sep).filter(function (segment) { return segment !== ""; });
|
|
9
|
-
};
|
|
10
|
-
export var noImportPrivate = {
|
|
2
|
+
export const noImportPrivate = {
|
|
11
3
|
meta: {
|
|
12
4
|
type: "problem",
|
|
13
5
|
docs: {
|
|
@@ -18,26 +10,28 @@ export var noImportPrivate = {
|
|
|
18
10
|
},
|
|
19
11
|
schema: [],
|
|
20
12
|
},
|
|
21
|
-
create
|
|
13
|
+
create(context) {
|
|
22
14
|
return {
|
|
23
|
-
ImportDeclaration
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
var currentDirPath = path.dirname(currentFilePath);
|
|
15
|
+
ImportDeclaration(node) {
|
|
16
|
+
const importPath = node.source.value?.toString() ?? "";
|
|
17
|
+
const currentFilePath = context.filename;
|
|
18
|
+
const currentDirPath = path.dirname(currentFilePath);
|
|
28
19
|
if (importPath.includes("/private")) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
context.report({ node: node, messageId: "noImportPrivate" });
|
|
20
|
+
const absoluteCurrentDirPath = path.resolve(currentDirPath);
|
|
21
|
+
const absoluteImportPath = path.resolve(currentDirPath, importPath);
|
|
22
|
+
const importDirBeforePrivate = absoluteImportPath.split("/private")[0];
|
|
23
|
+
const currentDirSegments = getDirSegments(absoluteCurrentDirPath);
|
|
24
|
+
const importDirSegments = getDirSegments(importDirBeforePrivate);
|
|
25
|
+
if (currentDirSegments.length !== importDirSegments.length ||
|
|
26
|
+
currentDirSegments.some((segment, index) => segment !== importDirSegments[index])) {
|
|
27
|
+
context.report({ node, messageId: "noImportPrivate" });
|
|
38
28
|
}
|
|
39
29
|
}
|
|
40
30
|
},
|
|
41
31
|
};
|
|
42
32
|
},
|
|
43
33
|
};
|
|
34
|
+
const getDirSegments = (dirPath) => {
|
|
35
|
+
return dirPath.split(path.sep).filter((segment) => segment !== "");
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=no-import-private.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-import-private.mjs","sourceRoot":"","sources":["../src/no-import-private.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAU7B,MAAM,CAAC,MAAM,eAAe,GAAoB;IAC9C,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EACT,8EAA8E;SACjF;QACD,QAAQ,EAAE;YACR,eAAe,EACb,8EAA8E;SACjF;QACD,MAAM,EAAE,EAAE;KACX;IACD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,iBAAiB,CAAC,IAAI;gBACpB,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;gBACvD,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;gBACzC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;gBAErD,IAAI,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBACpC,MAAM,sBAAsB,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;oBAC5D,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;oBAGpE,MAAM,sBAAsB,GAC1B,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;oBAE1C,MAAM,kBAAkB,GAAG,cAAc,CAAC,sBAAsB,CAAC,CAAC;oBAClE,MAAM,iBAAiB,GAAG,cAAc,CAAC,sBAAsB,CAAC,CAAC;oBACjE,IACE,kBAAkB,CAAC,MAAM,KAAK,iBAAiB,CAAC,MAAM;wBACtD,kBAAkB,CAAC,IAAI,CACrB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,iBAAiB,CAAC,KAAK,CAAC,CACzD,EACD,CAAC;wBACD,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC,CAAC;oBACzD,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAOF,MAAM,cAAc,GAAG,CAAC,OAAe,EAAY,EAAE;IACnD,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC;AACrE,CAAC,CAAC"}
|