@blumintinc/eslint-plugin-blumint 1.0.2 → 1.0.3

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.
Files changed (71) hide show
  1. package/README.md +62 -281
  2. package/lib/index.d.ts +1 -0
  3. package/lib/index.js +69 -0
  4. package/lib/rules/array-methods-this-context.d.ts +3 -0
  5. package/lib/rules/array-methods-this-context.js +64 -0
  6. package/lib/rules/class-methods-read-top-to-bottom.d.ts +2 -0
  7. package/lib/rules/class-methods-read-top-to-bottom.js +72 -0
  8. package/lib/rules/dynamic-https-errors.d.ts +2 -0
  9. package/lib/rules/dynamic-https-errors.js +57 -0
  10. package/lib/rules/export-if-in-doubt.d.ts +2 -0
  11. package/lib/rules/export-if-in-doubt.js +69 -0
  12. package/lib/rules/extract-global-constants.d.ts +2 -0
  13. package/lib/rules/extract-global-constants.js +63 -0
  14. package/lib/rules/generic-starts-with-t.d.ts +2 -0
  15. package/lib/rules/generic-starts-with-t.js +35 -0
  16. package/lib/rules/no-async-array-filter.d.ts +2 -0
  17. package/lib/rules/no-async-array-filter.js +40 -0
  18. package/lib/rules/no-async-foreach.d.ts +2 -0
  19. package/lib/rules/no-async-foreach.js +37 -0
  20. package/lib/rules/no-conditional-literals-in-jsx.d.ts +2 -0
  21. package/lib/rules/no-conditional-literals-in-jsx.js +61 -0
  22. package/lib/rules/no-filter-without-return.d.ts +2 -0
  23. package/lib/rules/no-filter-without-return.js +41 -0
  24. package/lib/rules/no-misused-switch-case.d.ts +2 -0
  25. package/lib/rules/no-misused-switch-case.js +35 -0
  26. package/lib/rules/no-unpinned-dependencies.d.ts +2 -0
  27. package/lib/rules/no-unpinned-dependencies.js +65 -0
  28. package/lib/rules/no-useless-fragment.d.ts +2 -0
  29. package/lib/rules/no-useless-fragment.js +46 -0
  30. package/lib/rules/prefer-fragment-shorthand.d.ts +3 -0
  31. package/lib/rules/prefer-fragment-shorthand.js +40 -0
  32. package/lib/rules/prefer-type-over-interface.d.ts +2 -0
  33. package/lib/rules/prefer-type-over-interface.js +45 -0
  34. package/lib/rules/require-memo.d.ts +6 -0
  35. package/lib/rules/require-memo.js +166 -0
  36. package/lib/utils/ASTHelpers.d.ts +12 -0
  37. package/lib/utils/ASTHelpers.js +336 -0
  38. package/lib/utils/createRule.d.ts +2 -0
  39. package/lib/utils/createRule.js +6 -0
  40. package/lib/utils/graph/ClassGraphBuilder.d.ts +29 -0
  41. package/lib/utils/graph/ClassGraphBuilder.js +80 -0
  42. package/lib/utils/graph/ClassGraphSorter.d.ts +7 -0
  43. package/lib/utils/graph/ClassGraphSorter.js +10 -0
  44. package/lib/utils/graph/ClassGraphSorterReadability.d.ts +16 -0
  45. package/lib/utils/graph/ClassGraphSorterReadability.js +94 -0
  46. package/lib/utils/ruleTester.d.ts +5 -0
  47. package/lib/utils/ruleTester.js +23 -0
  48. package/package.json +33 -13
  49. package/CHANGELOG.md +0 -63
  50. package/assets/logo.svg +0 -26
  51. package/jest.config.js +0 -13
  52. package/plugin/README.md +0 -80
  53. package/plugin/docs/rules/array-methods-this-context.md +0 -30
  54. package/plugin/docs/rules/class-methods-read-top-to-bottom.md +0 -46
  55. package/plugin/docs/rules/dynamic-https-errors.md +0 -23
  56. package/plugin/docs/rules/export-if-in-doubt.md +0 -26
  57. package/plugin/docs/rules/extract-global-constants.md +0 -33
  58. package/plugin/docs/rules/generic-starts-with-t.md +0 -33
  59. package/plugin/docs/rules/no-async-array-filter.md +0 -32
  60. package/plugin/docs/rules/no-async-foreach.md +0 -41
  61. package/plugin/docs/rules/no-conditional-literals-in-jsx.md +0 -27
  62. package/plugin/docs/rules/no-filter-without-return.md +0 -43
  63. package/plugin/docs/rules/no-misused-switch-case.md +0 -38
  64. package/plugin/docs/rules/no-unpinned-dependencies.md +0 -34
  65. package/plugin/docs/rules/no-useless-fragment.md +0 -25
  66. package/plugin/docs/rules/prefer-fragment-shorthand.md +0 -25
  67. package/plugin/docs/rules/prefer-type-over-interface.md +0 -25
  68. package/plugin/docs/rules/require-memo.md +0 -36
  69. package/plugin/package-lock.json +0 -7662
  70. package/plugin/package.json +0 -45
  71. package/tsconfig.json +0 -79
package/README.md CHANGED
@@ -1,299 +1,80 @@
1
- <!-- Project shields -->
1
+ # @blumintinc/eslint-plugin-blumint
2
2
 
3
- [![Setup Automated][gitpod-shield]][gitpod-url]
3
+ Custom eslint rules for use at BluMint
4
4
 
5
- <!-- Header -->
6
- <br />
7
- <p align="center">
8
- <!---TODO: Update below with repository URL -->
9
- <a href="https://github.com/BluMintInc/template-gitpod">
10
- <img src="assets/logo.svg" alt="Logo" height=100>
11
- </a>
12
- <p align="center">
13
- <!---TODO: Update below with repository name -->
14
- TEMPLATE
15
- <br />
16
- <!---TODO: Update below with repository URL -->
17
- <a href="https://github.com/BluMintInc/template-gitpod/issues">Report Bug</a>
18
- ·
19
- <!---TODO: Update below with repository URL -->
20
- <a href="https://github.com/BluMintInc/template-gitpod/issues">Request Feature</a>
21
- </p>
22
- </p>
23
- <br />
5
+ ## Installation
24
6
 
25
- ## Table of Contents
7
+ You'll first need to install [ESLint](https://eslint.org/):
26
8
 
27
- - [About this Project](#about-this-project)
28
- - [Built With](#built-with)
29
- - [Environment Dependencies](#environment-dependencies)
30
- - [Recommended Browser Extensions](#recommended-browser-extensions)
31
- - [Getting Started](#getting-started)
32
- - [Zero-Installation Development](#zero-installation-development)
33
- - [Docker Installation](#docker-installation)
34
- - [Contributing](#contributing)
35
- - [Agile Development](#agile-development)
36
- - [Testing](#testing)
37
- - [Gitflow](#gitflow)
38
- - [Commitizen](#commitizen)
39
- - [Diagramming](#diagramming)
40
- - [Workflow Automation](#workflow-automation)
41
- - [CI](#ci)
42
- - [CD](#cd)
43
- - [Dependency Management](#dependency-management)
44
- - [Static Code Analysis](#static-code-analysis)
45
- - [License](#license)
46
-
47
- <br />
48
-
49
- ## About this Project
50
-
51
- This repository is a template repository for Gitpod-based development of a service.
52
-
53
- ### Built with
54
-
55
- - [Typescript](https://www.typescriptlang.org/)
56
- - [Jest](https://mochajs.org/)
57
-
58
- ### Environment Dependencies
59
-
60
- - [NodeJS](https://nodejs.org) (16 with npm ^8.16.0)
61
-
62
- ### Recommended Browser Extensions
63
-
64
- It is recommended that you install the following browser extensions for the best experience
65
- interacting with this repository:
66
-
67
- 1. [Gitpod Browser Extension](https://www.gitpod.io/docs/browser-extension/)
68
-
69
- <br />
70
-
71
- ## Getting Started
72
-
73
- ### Zero-Installation Development
74
-
75
- <!---TODO: Update below with repository URL -->
76
-
77
- [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/BluMintInc/template-gitpod)
78
-
79
- It is highly recommended to conduct development of this repository
80
- via [Gitpod's online IDE](https://www.gitpod.io/docs/ide/). Click the following to
81
- get started with zero installation requirements:
82
-
83
- <p>
84
- <!---TODO: Update below with repository URL -->
85
- <a href="https://gitpod.io/#https://github.com/BluMintInc/template-gitpod" target="_blank" rel="nofollow noopener noreferrer">
86
- <img src="https://gitpod.io/button/open-in-gitpod.svg" alt="Open in Gitpod">
87
- </a>
88
- </p>
89
-
90
- Gitpod is a one-click online IDE for Cloud-based development. The following video
91
- provides a very effective introduction to Gitpod: [https://www.youtube.com/watch?v=qLv6-Uop0yc](https://www.youtube.com/watch?v=qLv6-Uop0yc).
92
-
93
- <br />
94
-
95
- ### Docker Installation
96
-
97
- Alternatively, this repo supports [VS Code Remote Container Development](https://code.visualstudio.com/docs/remote/containers#_quick-start-open-a-git-repository-or-github-pr-in-an-isolated-container-volume) for Dockerized development inside VSCode.
98
-
99
- **Step #1**: To get started, first make sure to install the followin prerequisites:
100
-
101
- 1. Visual Studio Code
102
-
103
- - Manual installation: https://code.visualstudio.com/download
104
- - Windows (via [Chocolately](https://chocolatey.org/)):
105
- ```bash
106
- choco install vscode
107
- ```
108
- - Mac or Linux (via [Homebrew](https://brew.sh/)):
109
- ```sh
110
- brew update
111
- brew tap homebrew/cask-cask
112
- brew cask search visual-studio-code
113
- brew cask install visual-studio-code
114
- ```
115
-
116
- 2. [Visual Studio Code Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)
117
- extension pack, which can be installed into VS Code with [this manual installation link](vscode:extension/ms-vscode-remote.vscode-remote-extensionpack).
118
-
119
- 3. [Docker Desktop](https://www.docker.com/products/docker-desktop)
120
- - Manual installation: https://www.docker.com/products/docker-desktop for Widows / Mac
121
- - Windows (via [Chocolately](https://chocolatey.org/)):
122
- ```bash
123
- choco install docker-desktop
124
- ```
125
- and follow
126
- - Mac or Linux (via [Homebrew](https://brew.sh/)):
127
- ```sh
128
- brew cask install docker
129
- ```
130
- - Linux (Ubuntu, Debian):
131
- ```sh
132
- sudo apt-get update
133
- sudo apt-get remove docker docker-engine docker.io
134
- sudo apt install docker.io
135
- sudo systemctl start docker
136
- sudo systemctl enable docker
137
- ```
138
-
139
- **Step #2**: Start the Docker daemon if it has already not started automatially after the
140
- installation finishes (run the Docker Desktop application). To ensure docker is running,
141
- attempt the following commands:
142
-
143
- ```bash
144
- docker version
145
- docker run hello-world
9
+ ```sh
10
+ npm i eslint --save-dev
146
11
  ```
147
12
 
148
- **Step #3**: Start VS Code and press _F1_ to run
149
- **Remote-Containers: Clone Repository in Container Volume..** from the Command Palette.
150
-
151
- <!---TODO: Update below with repository URL -->
152
-
153
- **Step #4**: Enter this repository's Git URI: https://github.com/BluMintInc/template-gitpod.git.
154
- VS Code will install all required dependencies and set up the environment from the Dockerfile configuration.
13
+ Next, install `@blumintinc/eslint-plugin-blumint`:
155
14
 
156
- <br />
157
-
158
- ## Contributing
159
-
160
- ### [Agile Development](https://agilemanifesto.org/)
161
-
162
- We are uncovering better ways of developing
163
- software by doing it and helping others do it.
164
-
165
- Through this work we have come to value:
166
-
167
- - **Individuals and interactions** over _processes and tools_
168
- - **Working software** over _comprehensive documentation_
169
- - **Customer collaboration** over _contract negotiation_
170
- - **Responding to change** over _following a plan_
171
-
172
- That is, while there is value in the items on
173
- _the right_, we value the items **on the left** more.
174
-
175
- Furthermore, we value these principles:
176
-
177
- 1. Our highest priority is to satisfy the customer
178
- through early and continuous delivery
179
- of valuable software.
180
- 2. Welcome changing requirements, even late in
181
- development. Agile processes harness change for
182
- the customer's competitive advantage.
183
- 3. Deliver working software frequently, from a
184
- couple of weeks to a couple of months, with a
185
- preference to the shorter timescale.
186
- 4. Business people and developers must work
187
- together daily throughout the project.
188
- 5. Build projects around motivated individuals.
189
- Give them the environment and support they need,
190
- and trust them to get the job done.
191
- 6. The most efficient and effective method of
192
- conveying information to and within a development
193
- team is face-to-face conversation.
194
- 7. Working software is the primary measure of progress.
195
- 8. Agile processes promote sustainable development.
196
- The sponsors, developers, and users should be able
197
- to maintain a constant pace indefinitely.
198
- 9. Continuous attention to technical excellence
199
- and good design enhances agility.
200
- 10. Simplicity--the art of maximizing the amount
201
- of work not done--is essential.
202
- 11. The best architectures, requirements, and designs
203
- emerge from self-organizing teams.
204
- 12. At regular intervals, the team reflects on how
205
- to become more effective, then tunes and adjusts
206
- its behavior accordingly.
207
-
208
- ### Testing
209
-
210
- Each contributor to this repository is obligated to provide sufficient test coverage over their contributions.
211
- We use the [Jest](https://jestjs.io/) test framework.
212
-
213
- ### [Gitflow](https://nvie.com/posts/a-successful-git-branching-model/)
214
-
215
- Version control with git on this repo is in strict adherence to
216
- the [Gitflow Workflow](https://nvie.com/posts/a-successful-git-branching-model/).
217
- Gitflow was architectured by Vincent Driesssen in 2010 and since has been adopted with massive
218
- popularity as a very effective development workflow under distributed version control.
219
-
220
- This project makes use of the [git-flow](https://github.com/nvie/gitflow) integration setup in
221
- the Docker container, which lets you execute `git flow` commands on the terminal rather than
222
- `git` commands directly.
223
-
224
- The project also utilizes [githooks](https://git-scm.com/docs/githooks/en) to enforce gitflow and
225
- prevent users from accidently pushing to the main branch.
226
-
227
- Plase read the following article for a sufficient introduction to the Gitflow
228
- Workflow: https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow.
229
-
230
- ### [Commitizen](https://commitizen-tools.github.io/commitizen/)
231
-
232
- This project uses [githooks](https://git-scm.com/docs/githooks/en) to enforce standarized commits
233
- according to the [Commitizen](https://commitizen-tools.github.io/commitizen/) style. Running
234
- `git commit` on the command line instigates a series of prompts guiding you through the standard.
235
-
236
- ### Diagramming
237
-
238
- All diagrams should be included on the repository to which they pertain. We use
239
- [PlantUML](https://plantuml.com/) to build all of our diagrams. PlantUML has a Domain Specific
240
- Language (DSL) for declaratively building [various types of diagrams](https://plantuml.com/).
241
- You can write a .wsd, .pu, .puml, .plantuml, or .iuml file containing PlantUML DSL and the
242
- [PlantUML Extension](https://marketplace.visualstudio.com/items?itemName=jebbs.plantuml)
243
- will enable you to render that diagram in a live preview by pressing Alt + D.
244
-
245
- <br />
246
- <br />
247
-
248
- ## Workflow Automation
249
-
250
- This repository uses [Github Actions](https://docs.github.com/en/actions) for several workflow
251
- automations as well as several organizational [Github Integrations](https://github.com/integrations).
252
-
253
- ### CI
254
-
255
- Pre-commit [githooks](https://git-scm.com/docs/githooks/en) lint the codebase and then run all the
256
- project's [Jest](https://jestjs.io/) tests to prevent regressions from even being checked into
257
- the codebase. On top of this, the
258
- [Test](https://github.com/BluMintInc/template-gitpod/blob/master/.github/workflows/test-report.yml)
259
- Action runs the project's [Jest](https://jestjs.io/) tests to check PRs before they are merged.
260
-
261
- ### CD
262
- <!---TODO: Update below paragraph with repository URLs -->
263
- The [Release](https://github.com/BluMintInc/template-gitpod/blob/master/.github/workflows/semantic-release.yml)
264
- Action triggers on commits to the main branch utilzing the repository's
265
- [Commitizen](https://commitizen-tools.github.io/commitizen/) commit style to automatically version published
266
- code according to [SemVar](https://semver.org/). The
267
- [Release](https://github.com/BluMintInc/template-gitpod/blob/master/.github/workflows/semantic-release.yml)
268
- Action also publishes the project to our private npmjs repository scoped under [@blumint](https://www.npmjs.com/settings/minimap-inc/packages).
15
+ ```sh
16
+ npm install @blumintinc/eslint-plugin-blumint --save-dev
17
+ ```
269
18
 
270
- This repository also makes use of the [Semantic Pull Probot](https://github.com/zeke/semantic-pull-requests) to
271
- vet and squash the commits of merged PRs onto the main branch. For more information, see
272
- [Semantic Release](https://github.com/semantic-release/semantic-release).
19
+ ## Usage
273
20
 
274
- ### Dependency Management
21
+ Add `@blumintinc/blumint` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
275
22
 
276
- The [Dependabot](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-supply-chain-security#what-is-dependabot) integration will periodically
277
- make PRs suggesting modifications to the dependecy structure to eliminiate vulnerabilities, update depricated
278
- dependencies, and perform other miscellenous tasks.
23
+ ```json
24
+ {
25
+ "plugins": [
26
+ "@blumintinc/blumint"
27
+ ]
28
+ }
29
+ ```
279
30
 
280
- ### Static Code Analysis
281
31
 
282
- The [Accuracies](https://github.com/marketplace/accurics) integration analyzes the codebase for policy violations and
283
- vulnerabilities with the use of Cloud infrastructure (AWS, GCP, etc.) and makes PRs to corrct any detected
284
- issues before they become a problem.
32
+ Then configure the rules you want to use under the rules section.
285
33
 
286
- The [Codacy](https://app.codacy.com/) bot will scan PRs and the repository as a whole to detect security vulnerabilities, code smells, performance inefficiencies, compatibility issues, unnecessarily complex code, missing documentation, and unused code.
34
+ ```json
35
+ {
36
+ "rules": {
37
+ "blumint/rule-name": "error"
38
+ }
39
+ }
40
+ ```
287
41
 
288
- <br />
289
- <br />
42
+ Or use the recommended config:
290
43
 
291
- ## License
44
+ ```json
45
+ {
46
+ "extends": ["some-other-plugin", "plugin:@blumintinc/blumint/recommended"]
47
+ }
48
+ ```
292
49
 
293
- No license is included, as all work is proprietary.
50
+ ## Rules
51
+
52
+ <!-- begin auto-generated rules list -->
53
+
54
+ 💼 Configurations enabled in.\
55
+ ⚠️ Configurations set to warn in.\
56
+ ✅ Set in the `recommended` configuration.\
57
+ 🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).
58
+
59
+ | Name                             | Description | 💼 | ⚠️ | 🔧 |
60
+ | :--------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | :- | :- | :- |
61
+ | [array-methods-this-context](docs/rules/array-methods-this-context.md) | Prevent misuse of Array methods in OOP | | ✅ | |
62
+ | [class-methods-read-top-to-bottom](docs/rules/class-methods-read-top-to-bottom.md) | Ensures classes read linearly from top to bottom. | | ✅ | 🔧 |
63
+ | [dynamic-https-errors](docs/rules/dynamic-https-errors.md) | Dynamic error details should only be in the third argument of the HttpsError constructor. The second argument is hashed to produce a unique id. | | ✅ | |
64
+ | [export-if-in-doubt](docs/rules/export-if-in-doubt.md) | All top-level const definitions, type definitions, and functions should be exported | | | |
65
+ | [extract-global-constants](docs/rules/extract-global-constants.md) | Extract constants/functions to the global scope when possible | | | |
66
+ | [generic-starts-with-t](docs/rules/generic-starts-with-t.md) | Enforce TypeScript generic types to start with T | | ✅ | |
67
+ | [no-async-array-filter](docs/rules/no-async-array-filter.md) | Disallow async callbacks for Array.filter | ✅ | | |
68
+ | [no-async-foreach](docs/rules/no-async-foreach.md) | Disallow Array.forEach with an async callback function | ✅ | | |
69
+ | [no-conditional-literals-in-jsx](docs/rules/no-conditional-literals-in-jsx.md) | Disallow use of conditional literals in JSX code | ✅ | | |
70
+ | [no-filter-without-return](docs/rules/no-filter-without-return.md) | Disallow Array.filter callbacks without an explicit return (if part of a block statement) | ✅ | | |
71
+ | [no-misused-switch-case](docs/rules/no-misused-switch-case.md) | Prevent misuse of logical OR in switch case statements | ✅ | | |
72
+ | [no-unpinned-dependencies](docs/rules/no-unpinned-dependencies.md) | Enforces pinned dependencies | ✅ | | 🔧 |
73
+ | [no-useless-fragment](docs/rules/no-useless-fragment.md) | Prevent unnecessary use of React fragments | | ✅ | 🔧 |
74
+ | [prefer-fragment-shorthand](docs/rules/prefer-fragment-shorthand.md) | Prefer <> shorthand for <React.Fragment> | | ✅ | 🔧 |
75
+ | [prefer-type-over-interface](docs/rules/prefer-type-over-interface.md) | Prefer using type alias over interface | | ✅ | 🔧 |
76
+ | [require-memo](docs/rules/require-memo.md) | React components must be memoized | ✅ | | 🔧 |
77
+
78
+ <!-- end auto-generated rules list -->
294
79
 
295
- <!-- Markdown links & images -->
296
80
 
297
- [gitpod-shield]: https://img.shields.io/badge/setup-automated-blue?logo=gitpod
298
- <!---TODO: Update below with repository URL -->
299
- [gitpod-url]: https://gitpod.io/#https://github.com/BluMintInc/template-gitpod
package/lib/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/lib/index.js ADDED
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const array_methods_this_context_1 = require("./rules/array-methods-this-context");
4
+ const class_methods_read_top_to_bottom_1 = require("./rules/class-methods-read-top-to-bottom");
5
+ const dynamic_https_errors_1 = require("./rules/dynamic-https-errors");
6
+ const export_if_in_doubt_1 = require("./rules/export-if-in-doubt");
7
+ const extract_global_constants_1 = require("./rules/extract-global-constants");
8
+ const generic_starts_with_t_1 = require("./rules/generic-starts-with-t");
9
+ const no_async_array_filter_1 = require("./rules/no-async-array-filter");
10
+ const no_async_foreach_1 = require("./rules/no-async-foreach");
11
+ const no_conditional_literals_in_jsx_1 = require("./rules/no-conditional-literals-in-jsx");
12
+ const no_filter_without_return_1 = require("./rules/no-filter-without-return");
13
+ const no_misused_switch_case_1 = require("./rules/no-misused-switch-case");
14
+ const no_unpinned_dependencies_1 = require("./rules/no-unpinned-dependencies");
15
+ const no_useless_fragment_1 = require("./rules/no-useless-fragment");
16
+ const prefer_fragment_shorthand_1 = require("./rules/prefer-fragment-shorthand");
17
+ const prefer_type_over_interface_1 = require("./rules/prefer-type-over-interface");
18
+ const require_memo_1 = require("./rules/require-memo");
19
+ module.exports = {
20
+ meta: {
21
+ name: '@blumintinc/eslint-plugin-blumint',
22
+ version: '1.0.3',
23
+ },
24
+ parseOptions: {
25
+ ecmaVersion: 2020,
26
+ },
27
+ configs: {
28
+ recommended: {
29
+ plugins: ['@blumintinc/blumint'],
30
+ rules: {
31
+ '@blumintinc/blumint/array-methods-this-context': 'warn',
32
+ '@blumintinc/blumint/class-methods-read-top-to-bottom': 'warn',
33
+ '@blumintinc/blumint/dynamic-https-errors': 'warn',
34
+ // '@blumintinc/blumint/export-if-in-doubt': 'warn',
35
+ // '@blumintinc/blumint/extract-global-constants': 'warn',
36
+ '@blumintinc/blumint/generic-starts-with-t': 'warn',
37
+ '@blumintinc/blumint/no-async-array-filter': 'error',
38
+ '@blumintinc/blumint/no-async-foreach': 'error',
39
+ '@blumintinc/blumint/no-conditional-literals-in-jsx': 'error',
40
+ '@blumintinc/blumint/no-filter-without-return': 'error',
41
+ '@blumintinc/blumint/no-misused-switch-case': 'error',
42
+ '@blumintinc/blumint/no-unpinned-dependencies': 'error',
43
+ '@blumintinc/blumint/no-useless-fragment': 'warn',
44
+ '@blumintinc/blumint/prefer-fragment-shorthand': 'warn',
45
+ '@blumintinc/blumint/prefer-type-over-interface': 'warn',
46
+ '@blumintinc/blumint/require-memo': 'error',
47
+ },
48
+ },
49
+ },
50
+ rules: {
51
+ 'array-methods-this-context': array_methods_this_context_1.arrayMethodsThisContext,
52
+ 'class-methods-read-top-to-bottom': class_methods_read_top_to_bottom_1.classMethodsReadTopToBottom,
53
+ 'dynamic-https-errors': dynamic_https_errors_1.dynamicHttpsErrors,
54
+ 'export-if-in-doubt': export_if_in_doubt_1.exportIfInDoubt,
55
+ 'extract-global-constants': extract_global_constants_1.extractGlobalConstants,
56
+ 'generic-starts-with-t': generic_starts_with_t_1.genericStartsWithT,
57
+ 'no-async-array-filter': no_async_array_filter_1.noAsyncArrayFilter,
58
+ 'no-async-foreach': no_async_foreach_1.noAsyncForEach,
59
+ 'no-conditional-literals-in-jsx': no_conditional_literals_in_jsx_1.noConditionalLiteralsInJsx,
60
+ 'no-filter-without-return': no_filter_without_return_1.noFilterWithoutReturn,
61
+ 'no-misused-switch-case': no_misused_switch_case_1.noMisusedSwitchCase,
62
+ 'no-unpinned-dependencies': no_unpinned_dependencies_1.noUnpinnedDependencies,
63
+ 'no-useless-fragment': no_useless_fragment_1.noUselessFragment,
64
+ 'prefer-fragment-shorthand': prefer_fragment_shorthand_1.preferFragmentShorthand,
65
+ 'prefer-type-over-interface': prefer_type_over_interface_1.preferTypeOverInterface,
66
+ 'require-memo': require_memo_1.requireMemo,
67
+ },
68
+ };
69
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,3 @@
1
+ import { TSESLint } from '@typescript-eslint/utils';
2
+ export declare const ARRAY_METHODS: string[];
3
+ export declare const arrayMethodsThisContext: TSESLint.RuleModule<'preferArrow' | 'unexpected', never[]>;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.arrayMethodsThisContext = exports.ARRAY_METHODS = void 0;
4
+ const createRule_1 = require("../utils/createRule");
5
+ exports.ARRAY_METHODS = [
6
+ 'map',
7
+ 'filter',
8
+ 'forEach',
9
+ 'reduce',
10
+ 'some',
11
+ 'every',
12
+ ];
13
+ exports.arrayMethodsThisContext = (0, createRule_1.createRule)({
14
+ create(context) {
15
+ return {
16
+ CallExpression(node) {
17
+ // Array method called with a class method reference
18
+ if (node.callee.type === 'MemberExpression' &&
19
+ node.callee.property.type === 'Identifier' &&
20
+ exports.ARRAY_METHODS.includes(node.callee.property.name) &&
21
+ node.arguments.length > 0 &&
22
+ node.arguments[0].type === 'MemberExpression' &&
23
+ node.arguments[0].object.type === 'ThisExpression') {
24
+ context.report({
25
+ node: node.arguments[0],
26
+ messageId: 'unexpected',
27
+ });
28
+ }
29
+ // Function expression bound to `this` in array method
30
+ else if (node.callee.type === 'MemberExpression' &&
31
+ node.callee.property.type === 'Identifier' &&
32
+ exports.ARRAY_METHODS.includes(node.callee.property.name) &&
33
+ node.arguments.length > 0 &&
34
+ node.arguments[0].type === 'CallExpression' &&
35
+ node.arguments[0].callee.type === 'MemberExpression' &&
36
+ node.arguments[0].callee.object.type === 'FunctionExpression' &&
37
+ node.arguments[0].callee.property.type === 'Identifier' &&
38
+ node.arguments[0].callee.property.name === 'bind' &&
39
+ node.arguments[0].arguments.length > 0 &&
40
+ node.arguments[0].arguments[0].type === 'ThisExpression') {
41
+ context.report({
42
+ node: node.arguments[0],
43
+ messageId: 'preferArrow',
44
+ });
45
+ }
46
+ },
47
+ };
48
+ },
49
+ name: 'array-methods-this-context',
50
+ meta: {
51
+ type: 'problem',
52
+ docs: {
53
+ description: 'Prevent misuse of Array methods in OOP',
54
+ recommended: 'error',
55
+ },
56
+ schema: [],
57
+ messages: {
58
+ unexpected: 'Use an arrow function to preserve "this" context.',
59
+ preferArrow: 'Use an arrow function instead of binding this.',
60
+ },
61
+ },
62
+ defaultOptions: [],
63
+ });
64
+ //# sourceMappingURL=array-methods-this-context.js.map
@@ -0,0 +1,2 @@
1
+ import { TSESLint } from '@typescript-eslint/utils';
2
+ export declare const classMethodsReadTopToBottom: TSESLint.RuleModule<'classMethodsReadTopToBottom', never[]>;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.classMethodsReadTopToBottom = void 0;
4
+ const createRule_1 = require("../utils/createRule");
5
+ const ClassGraphBuilder_1 = require("../utils/graph/ClassGraphBuilder");
6
+ function getMemberName(member) {
7
+ if (member.type === 'MethodDefinition' ||
8
+ member.type === 'PropertyDefinition') {
9
+ return member.key.type === 'Identifier' ? member.key.name : null;
10
+ }
11
+ return null;
12
+ }
13
+ exports.classMethodsReadTopToBottom = (0, createRule_1.createRule)({
14
+ name: 'class-methods-read-top-to-bottom',
15
+ meta: {
16
+ type: 'suggestion',
17
+ docs: {
18
+ description: 'Ensures classes read linearly from top to bottom.',
19
+ recommended: 'warn',
20
+ },
21
+ schema: [],
22
+ messages: {
23
+ classMethodsReadTopToBottom: 'Methods should be ordered for top-down readability.',
24
+ },
25
+ fixable: 'code', // To allow ESLint to autofix issues.
26
+ },
27
+ defaultOptions: [],
28
+ create(context) {
29
+ let className;
30
+ return {
31
+ ClassDeclaration(node) {
32
+ className = node.id?.name || '';
33
+ },
34
+ 'ClassBody:exit'(node) {
35
+ const graphBuilder = new ClassGraphBuilder_1.ClassGraphBuilder(className, node);
36
+ const sortedOrder = graphBuilder.memberNamesSorted;
37
+ const actualOrder = node.body
38
+ .map((member) => member.type === 'MethodDefinition' ||
39
+ member.type === 'PropertyDefinition'
40
+ ? member.key.name
41
+ : null)
42
+ .filter(Boolean);
43
+ for (let i = 0; i < actualOrder.length; i++) {
44
+ if (actualOrder[i] !== sortedOrder[i]) {
45
+ const sourceCode = context.getSourceCode();
46
+ const newClassBody = sortedOrder
47
+ .map((n) => {
48
+ // Fetch the actual AST node corresponding to the name
49
+ const memberNode = node.body.find((member) => getMemberName(member) === n);
50
+ const comments = sourceCode.getCommentsBefore(memberNode);
51
+ memberNode.range = [
52
+ Math.min(memberNode.range[0], Math.min(...comments.map((comment) => comment.range[0]))),
53
+ Math.max(memberNode.range[1], Math.max(...comments.map((comment) => comment.range[1]))),
54
+ ];
55
+ return sourceCode.getText(memberNode);
56
+ })
57
+ .join('\n');
58
+ return context.report({
59
+ node,
60
+ messageId: 'classMethodsReadTopToBottom',
61
+ fix(fixer) {
62
+ return fixer.replaceTextRange([node.range[0] + 1, node.range[1] - 1], // Exclude the curly braces
63
+ newClassBody);
64
+ },
65
+ });
66
+ }
67
+ }
68
+ },
69
+ };
70
+ },
71
+ });
72
+ //# sourceMappingURL=class-methods-read-top-to-bottom.js.map
@@ -0,0 +1,2 @@
1
+ import { TSESLint } from '@typescript-eslint/utils';
2
+ export declare const dynamicHttpsErrors: TSESLint.RuleModule<'dynamicHttpsErrors', never[]>;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dynamicHttpsErrors = void 0;
4
+ /* eslint-disable @blumintinc/blumint/extract-global-constants */
5
+ const createRule_1 = require("../utils/createRule");
6
+ const isHttpsErrorCall = (callee) => {
7
+ if (callee.type === 'MemberExpression') {
8
+ return (callee.object.type === 'Identifier' &&
9
+ callee.object.name === 'https' &&
10
+ callee.property.type === 'Identifier' &&
11
+ callee.property.name === 'HttpsError');
12
+ }
13
+ else if (callee.type === 'Identifier') {
14
+ return callee.name === 'HttpsError';
15
+ }
16
+ return false;
17
+ };
18
+ exports.dynamicHttpsErrors = (0, createRule_1.createRule)({
19
+ name: 'dynamic-https-errors',
20
+ meta: {
21
+ type: 'suggestion',
22
+ docs: {
23
+ description: 'Dynamic error details should only be in the third argument of the HttpsError constructor. The second argument is hashed to produce a unique id.',
24
+ recommended: 'warn',
25
+ },
26
+ schema: [],
27
+ messages: {
28
+ dynamicHttpsErrors: 'Found dynamic error details in the second argument of the HttpsError constructor - the "message" field. This field is hashed to produce a unique id for error monitoring. Move any dynamic details to the third argument - the "details" field - to preserve the unique id and to monitor the error correctly.',
29
+ },
30
+ },
31
+ defaultOptions: [],
32
+ create(context) {
33
+ const checkForHttpsError = (node) => {
34
+ const callee = node.callee;
35
+ if (isHttpsErrorCall(callee)) {
36
+ const secondArg = node.arguments[1];
37
+ if (secondArg && secondArg.type === 'TemplateLiteral') {
38
+ if (secondArg.expressions.length > 0) {
39
+ context.report({
40
+ node: secondArg,
41
+ messageId: 'dynamicHttpsErrors',
42
+ });
43
+ }
44
+ }
45
+ }
46
+ };
47
+ return {
48
+ NewExpression(node) {
49
+ return checkForHttpsError(node);
50
+ },
51
+ CallExpression(node) {
52
+ return checkForHttpsError(node);
53
+ },
54
+ };
55
+ },
56
+ });
57
+ //# sourceMappingURL=dynamic-https-errors.js.map
@@ -0,0 +1,2 @@
1
+ import { TSESLint } from '@typescript-eslint/utils';
2
+ export declare const exportIfInDoubt: TSESLint.RuleModule<'exportIfInDoubt', never[]>;