@adonisjs/eslint-plugin 1.3.0 → 2.0.0-beta.1
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 +9 -0
- package/README.md +99 -19
- package/package.json +111 -22
- package/dist/bin/test.js +0 -36
- package/dist/src/index.js +0 -12
- package/dist/src/rules/prefer_lazy_controller_import.js +0 -111
- package/dist/src/rules/prefer_lazy_listener_import.js +0 -84
- package/dist/src/utils.js +0 -5
- package/dist/tests/prefer_lazy_controller_import.spec.js +0 -76
- package/dist/tests/prefer_lazy_listener_import.spec.js +0 -45
package/LICENSE.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# The MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,34 +1,114 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @adonisjs/eslint-plugin
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Compatible with ESLint>=9.0 and TypeScript >=5.4
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
<hr>
|
|
6
|
+
<br />
|
|
7
|
+
|
|
8
|
+
<div align="center">
|
|
9
|
+
<h3>ESLint plugin for AdonisJS applications</h3>
|
|
10
|
+
<p>
|
|
11
|
+
The plugin forces your application to use lazy imports for controllers and event listeners. <strong>Lazy imports are a must when you are using HMR mode in AdonisJS</strong>.
|
|
12
|
+
</p>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<br />
|
|
16
|
+
|
|
17
|
+
<div align="center">
|
|
18
|
+
|
|
19
|
+
[![gh-workflow-image]][gh-workflow-url] [![typescript-image]][typescript-url] [![npm-image]][npm-url] [![license-image]][license-url]
|
|
20
|
+
|
|
21
|
+
</div>
|
|
7
22
|
|
|
8
23
|
## Installation
|
|
9
24
|
|
|
10
|
-
|
|
25
|
+
The package comes pre-configured with the [@adonisjs/eslint-config](https://github.com/adonisjs/eslint-config) preset and hence manual installation is not required.
|
|
11
26
|
|
|
12
|
-
|
|
13
|
-
npm i -D @adonisjs/eslint-plugin
|
|
27
|
+
However, you can install and configure it as follows.
|
|
14
28
|
|
|
15
|
-
|
|
16
|
-
|
|
29
|
+
```sh
|
|
30
|
+
npm i -D @adonisjs/eslint-plugin@beta
|
|
17
31
|
|
|
18
|
-
#
|
|
19
|
-
|
|
32
|
+
# Install peer dependencies
|
|
33
|
+
npm i -D eslint@9 typescript typescript-eslint
|
|
20
34
|
```
|
|
21
35
|
|
|
22
36
|
## Usage
|
|
23
37
|
|
|
24
|
-
|
|
38
|
+
After installation, you can register the following as follows. Make sure to also setup the `typescript-eslint` parser in order for the rules to work.
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
// eslint.config.js
|
|
42
|
+
import adonisJSPlugin from '@adonisjs/eslint-plugin'
|
|
25
43
|
|
|
26
|
-
|
|
27
|
-
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
44
|
+
export default [
|
|
45
|
+
{
|
|
46
|
+
plugins: {
|
|
47
|
+
'@adonisjs': adonisJSPlugin,
|
|
48
|
+
},
|
|
49
|
+
rules: {
|
|
50
|
+
'@adonisjs/prefer-lazy-controller-import': 'error',
|
|
51
|
+
'@adonisjs/prefer-lazy-listener-import': 'error',
|
|
52
|
+
},
|
|
32
53
|
},
|
|
33
|
-
|
|
54
|
+
]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## `prefer-lazy-controller-import`
|
|
58
|
+
|
|
59
|
+
The `@adonisjs/prefer-lazy-controller-import` rule complains when you import a controller using the import expression and assign it to a route. For example:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import router from '@adonisjs/core/services/router'
|
|
63
|
+
// ❌ Error: Replace standard import with lazy controller import
|
|
64
|
+
import UsersController from '#controllers/user_controller'
|
|
65
|
+
|
|
66
|
+
router.get('users', [UsersController, 'index'])
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The rule is auto fixable, therefore you can apply the fix depending upon the shortcuts provided by your
|
|
70
|
+
code editor.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import router from '@adonisjs/core/services/router'
|
|
74
|
+
// ✅ Fixed
|
|
75
|
+
const UsersController = () => import('#controllers/user_controller')
|
|
76
|
+
|
|
77
|
+
router.get('users', [UsersController, 'index'])
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## `prefer-lazy-listener-import`
|
|
81
|
+
|
|
82
|
+
The `@adonisjs/prefer-lazy-listener-import` rule complains when you import an event listener using the import expression and assign it to an event. For example:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import emitter from '@adonisjs/core/services/emitter'
|
|
86
|
+
// ❌ Error: Replace standard import with lazy controller import
|
|
87
|
+
import SendVerificationEmail from '#listeners/send_verification_email'
|
|
88
|
+
|
|
89
|
+
emitter.on('user:created', [SendVerificationEmail, 'handle'])
|
|
34
90
|
```
|
|
91
|
+
|
|
92
|
+
The rule is auto fixable, therefore you can apply the fix depending upon the shortcuts provided by your
|
|
93
|
+
code editor.
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import emitter from '@adonisjs/core/services/emitter'
|
|
97
|
+
// ✅ Fixed
|
|
98
|
+
const SendVerificationEmail = () => import('#listeners/send_verification_email')
|
|
99
|
+
|
|
100
|
+
emitter.on('user:created', [SendVerificationEmail, 'handle'])
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
<div align="center">
|
|
104
|
+
<sub>Built with ❤︎ by <a href="https://github.com/Julien-R44">Julien Ripouteau</a> and <a href="https://github.com/thetutlage">Harminder Virk</a>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
[gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/eslint-plugin-adonisjs/checks.yml?style=for-the-badge
|
|
108
|
+
[gh-workflow-url]: https://github.com/adonisjs/eslint-plugin-adonisjs/actions/workflows/checks.yml 'Github action'
|
|
109
|
+
[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
|
|
110
|
+
[typescript-url]: "typescript"
|
|
111
|
+
[npm-image]: https://img.shields.io/npm/v/@adonisjs/eslint-plugin/latest.svg?style=for-the-badge&logo=npm
|
|
112
|
+
[npm-url]: https://www.npmjs.com/package/@adonisjs/eslint-plugin/v/latest 'npm'
|
|
113
|
+
[license-url]: LICENSE.md
|
|
114
|
+
[license-image]: https://img.shields.io/github/license/adonisjs/eslint-plugin-adonisjs?style=for-the-badge
|
package/package.json
CHANGED
|
@@ -1,40 +1,129 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adonisjs/eslint-plugin",
|
|
3
3
|
"description": "ESLint plugin to enforce AdonisJS app specific linting rules",
|
|
4
|
-
"version": "
|
|
5
|
-
"
|
|
4
|
+
"version": "2.0.0-beta.1",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=20.6.0"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
6
9
|
"files": [
|
|
7
|
-
"
|
|
10
|
+
"build",
|
|
11
|
+
"!build/bin",
|
|
12
|
+
"!build/tests"
|
|
8
13
|
],
|
|
14
|
+
"main": "build/index.js",
|
|
9
15
|
"exports": {
|
|
10
|
-
".": "./
|
|
16
|
+
".": "./build/index.js"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"pretest": "npm run lint",
|
|
20
|
+
"test": "c8 npm run quick:test",
|
|
21
|
+
"lint": "eslint .",
|
|
22
|
+
"format": "prettier --write .",
|
|
23
|
+
"clean": "del-cli build",
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"precompile": "npm run lint && npm run clean",
|
|
26
|
+
"compile": "tsup-node && tsc --emitDeclarationOnly --declaration",
|
|
27
|
+
"build": "npm run compile",
|
|
28
|
+
"release": "release-it",
|
|
29
|
+
"quick:test": "node --import=ts-node-maintained/register/esm --enable-source-maps bin/test.ts"
|
|
11
30
|
},
|
|
12
31
|
"devDependencies": {
|
|
13
|
-
"@
|
|
14
|
-
"@
|
|
15
|
-
"@japa/
|
|
16
|
-
"@
|
|
17
|
-
"@
|
|
18
|
-
"ts
|
|
19
|
-
"
|
|
32
|
+
"@adonisjs/prettier-config": "^1.3.0",
|
|
33
|
+
"@adonisjs/tsconfig": "^1.3.0",
|
|
34
|
+
"@japa/assert": "^3.0.0",
|
|
35
|
+
"@japa/runner": "^3.1.4",
|
|
36
|
+
"@release-it/conventional-changelog": "^8.0.1",
|
|
37
|
+
"@stylistic/eslint-plugin-ts": "^2.7.2",
|
|
38
|
+
"@swc/core": "^1.7.21",
|
|
39
|
+
"@types/node": "^22.5.1",
|
|
40
|
+
"@typescript-eslint/rule-tester": "^8.3.0",
|
|
41
|
+
"c8": "^10.1.2",
|
|
42
|
+
"del-cli": "^5.1.0",
|
|
43
|
+
"eslint": "^9.9.1",
|
|
44
|
+
"eslint-config-prettier": "^9.1.0",
|
|
45
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
46
|
+
"eslint-plugin-unicorn": "^55.0.0",
|
|
47
|
+
"prettier": "^3.3.3",
|
|
48
|
+
"release-it": "^17.6.0",
|
|
49
|
+
"ts-node-maintained": "^10.9.3",
|
|
50
|
+
"tsup": "^8.2.4",
|
|
51
|
+
"typescript": "^5.5.4",
|
|
52
|
+
"typescript-eslint": "^8.3.0"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"eslint": "^9.9.1"
|
|
20
56
|
},
|
|
21
57
|
"dependencies": {
|
|
22
|
-
"@typescript-eslint/utils": "^
|
|
58
|
+
"@typescript-eslint/utils": "^8.3.0"
|
|
59
|
+
},
|
|
60
|
+
"homepage": "https://github.com/adonisjs/eslint-plugin-adonisjs#readme",
|
|
61
|
+
"repository": {
|
|
62
|
+
"type": "git",
|
|
63
|
+
"url": "git+https://github.com/adonisjs/eslint-plugin-adonisjs.git"
|
|
64
|
+
},
|
|
65
|
+
"bugs": {
|
|
66
|
+
"url": "https://github.com/adonisjs/eslint-plugin-adonisjs/issues"
|
|
23
67
|
},
|
|
24
|
-
"author": "Julien Ripouteau <julien@ripouteau.com>",
|
|
25
|
-
"license": "MIT",
|
|
26
68
|
"keywords": [
|
|
27
69
|
"eslint",
|
|
28
70
|
"adonisjs",
|
|
29
71
|
"eslint-plugin"
|
|
30
72
|
],
|
|
73
|
+
"author": "Julien Ripouteau <julien@ripouteau.com>",
|
|
31
74
|
"contributors": [
|
|
32
|
-
|
|
33
|
-
|
|
75
|
+
{
|
|
76
|
+
"name": "Harminder Virk",
|
|
77
|
+
"email": "virk@adonisjs.com"
|
|
78
|
+
}
|
|
34
79
|
],
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
80
|
+
"license": "MIT",
|
|
81
|
+
"publishConfig": {
|
|
82
|
+
"provenance": true
|
|
83
|
+
},
|
|
84
|
+
"tsup": {
|
|
85
|
+
"entry": [
|
|
86
|
+
"index.ts"
|
|
87
|
+
],
|
|
88
|
+
"outDir": "./build",
|
|
89
|
+
"clean": true,
|
|
90
|
+
"format": "esm",
|
|
91
|
+
"dts": false,
|
|
92
|
+
"sourcemap": true,
|
|
93
|
+
"target": "esnext"
|
|
94
|
+
},
|
|
95
|
+
"release-it": {
|
|
96
|
+
"git": {
|
|
97
|
+
"requireCleanWorkingDir": true,
|
|
98
|
+
"requireUpstream": true,
|
|
99
|
+
"commitMessage": "chore(release): ${version}",
|
|
100
|
+
"tagAnnotation": "v${version}",
|
|
101
|
+
"push": true,
|
|
102
|
+
"tagName": "v${version}"
|
|
103
|
+
},
|
|
104
|
+
"github": {
|
|
105
|
+
"release": true
|
|
106
|
+
},
|
|
107
|
+
"npm": {
|
|
108
|
+
"publish": true,
|
|
109
|
+
"skipChecks": true
|
|
110
|
+
},
|
|
111
|
+
"plugins": {
|
|
112
|
+
"@release-it/conventional-changelog": {
|
|
113
|
+
"preset": {
|
|
114
|
+
"name": "angular"
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
"c8": {
|
|
120
|
+
"reporter": [
|
|
121
|
+
"text",
|
|
122
|
+
"html"
|
|
123
|
+
],
|
|
124
|
+
"exclude": [
|
|
125
|
+
"tests/**"
|
|
126
|
+
]
|
|
127
|
+
},
|
|
128
|
+
"prettier": "@adonisjs/prettier-config"
|
|
129
|
+
}
|
package/dist/bin/test.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const assert_1 = require("@japa/assert");
|
|
4
|
-
const spec_reporter_1 = require("@japa/spec-reporter");
|
|
5
|
-
const runner_1 = require("@japa/runner");
|
|
6
|
-
/*
|
|
7
|
-
|--------------------------------------------------------------------------
|
|
8
|
-
| Configure tests
|
|
9
|
-
|--------------------------------------------------------------------------
|
|
10
|
-
|
|
|
11
|
-
| The configure method accepts the configuration to configure the Japa
|
|
12
|
-
| tests runner.
|
|
13
|
-
|
|
|
14
|
-
| The first method call "processCliArgs" process the command line arguments
|
|
15
|
-
| and turns them into a config object. Using this method is not mandatory.
|
|
16
|
-
|
|
|
17
|
-
| Please consult japa.dev/runner-config for the config docs.
|
|
18
|
-
*/
|
|
19
|
-
(0, runner_1.configure)({
|
|
20
|
-
...(0, runner_1.processCliArgs)(process.argv.slice(2)),
|
|
21
|
-
...{
|
|
22
|
-
plugins: [(0, assert_1.assert)()],
|
|
23
|
-
reporters: [(0, spec_reporter_1.specReporter)()],
|
|
24
|
-
importer: (filePath) => require(filePath),
|
|
25
|
-
files: ['tests/**/*.spec.ts'],
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
/*
|
|
29
|
-
|--------------------------------------------------------------------------
|
|
30
|
-
| Run tests
|
|
31
|
-
|--------------------------------------------------------------------------
|
|
32
|
-
|
|
|
33
|
-
| The following "run" method is required to execute all the tests.
|
|
34
|
-
|
|
|
35
|
-
*/
|
|
36
|
-
(0, runner_1.run)();
|
package/dist/src/index.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
const prefer_lazy_controller_import_1 = __importDefault(require("./rules/prefer_lazy_controller_import"));
|
|
6
|
-
const prefer_lazy_listener_import_1 = __importDefault(require("./rules/prefer_lazy_listener_import"));
|
|
7
|
-
module.exports = {
|
|
8
|
-
rules: {
|
|
9
|
-
'prefer-lazy-controller-import': prefer_lazy_controller_import_1.default,
|
|
10
|
-
'prefer-lazy-listener-import': prefer_lazy_listener_import_1.default,
|
|
11
|
-
},
|
|
12
|
-
};
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const utils_1 = require("@typescript-eslint/utils");
|
|
4
|
-
const utils_2 = require("../utils");
|
|
5
|
-
const httpMethods = ['get', 'post', 'put', 'delete', 'patch'];
|
|
6
|
-
exports.default = (0, utils_2.createEslintRule)({
|
|
7
|
-
name: 'prefer-lazy-controller-import',
|
|
8
|
-
defaultOptions: [],
|
|
9
|
-
meta: {
|
|
10
|
-
type: 'problem',
|
|
11
|
-
fixable: 'code',
|
|
12
|
-
docs: {
|
|
13
|
-
description: 'Prefer lazy controller import over standard import',
|
|
14
|
-
recommended: 'recommended',
|
|
15
|
-
},
|
|
16
|
-
schema: [],
|
|
17
|
-
messages: {
|
|
18
|
-
preferLazyControllerImport: 'Replace standard import with lazy controller import',
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
create: function (context) {
|
|
22
|
-
let importIdentifiers = [];
|
|
23
|
-
let routerIdentifier = '';
|
|
24
|
-
let importNodes = [];
|
|
25
|
-
function isRouteCallExpression(node, identifier) {
|
|
26
|
-
return (node.callee.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
27
|
-
node.callee.object.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
28
|
-
node.callee.object.name === identifier &&
|
|
29
|
-
node.callee.property.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
30
|
-
httpMethods.includes(node.callee.property.name));
|
|
31
|
-
}
|
|
32
|
-
function isRouteResourceCallExpression(node, identifier) {
|
|
33
|
-
return (node.callee.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
34
|
-
node.callee.object.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
35
|
-
node.callee.object.name === identifier &&
|
|
36
|
-
node.callee.property.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
37
|
-
node.callee.property.name === 'resource');
|
|
38
|
-
}
|
|
39
|
-
return {
|
|
40
|
-
/**
|
|
41
|
-
* Track all imported identifiers
|
|
42
|
-
* Also get the local name of the router import
|
|
43
|
-
*/
|
|
44
|
-
ImportDeclaration(node) {
|
|
45
|
-
for (const specifier of node.specifiers) {
|
|
46
|
-
if (specifier.type === 'ImportDefaultSpecifier' || specifier.type === 'ImportSpecifier') {
|
|
47
|
-
importIdentifiers.push(specifier.local.name);
|
|
48
|
-
importNodes[specifier.local.name] = node;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
if (node.source.value === '@adonisjs/core/services/router') {
|
|
52
|
-
if (node.specifiers[0] && node.specifiers[0].type === 'ImportDefaultSpecifier') {
|
|
53
|
-
routerIdentifier = node.specifiers[0].local.name;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
CallExpression(node) {
|
|
58
|
-
/**
|
|
59
|
-
* Check if we are calling router.get() or any other http method
|
|
60
|
-
* OR if we are calling router.resource that also takes a controller
|
|
61
|
-
* as an argument
|
|
62
|
-
*/
|
|
63
|
-
const isRouteCallExpr = isRouteCallExpression(node, routerIdentifier);
|
|
64
|
-
const isRouteResourceExpr = isRouteResourceCallExpression(node, routerIdentifier);
|
|
65
|
-
if (!isRouteCallExpr && !isRouteResourceExpr) {
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Now let's extract the controller identifier from the call expression
|
|
70
|
-
*
|
|
71
|
-
* In the case of router.get/post/put.. we have to extract
|
|
72
|
-
* the first element from the array
|
|
73
|
-
*
|
|
74
|
-
* router.get("/", [HomeController, 'index'])
|
|
75
|
-
*/
|
|
76
|
-
let controller;
|
|
77
|
-
if (isRouteCallExpr) {
|
|
78
|
-
const secondArgument = node.arguments[1];
|
|
79
|
-
if (secondArgument.type !== utils_1.AST_NODE_TYPES.ArrayExpression)
|
|
80
|
-
return;
|
|
81
|
-
controller = secondArgument.elements[0];
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* In the case of router.resource, we just have to extract the first argument
|
|
85
|
-
*
|
|
86
|
-
* router.resource("foo", UserController)
|
|
87
|
-
*/
|
|
88
|
-
if (isRouteResourceExpr) {
|
|
89
|
-
controller = node.arguments[1];
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* If we are dealing with an Identifier that was imported
|
|
93
|
-
* through a standard import, then report it as an error
|
|
94
|
-
*/
|
|
95
|
-
const element = controller;
|
|
96
|
-
if (element.type !== 'Identifier' || !importIdentifiers.includes(element.name)) {
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
context.report({
|
|
100
|
-
node: importNodes[element.name],
|
|
101
|
-
messageId: 'preferLazyControllerImport',
|
|
102
|
-
fix(fixer) {
|
|
103
|
-
const importPath = importNodes[element.name].source.raw;
|
|
104
|
-
const newImportDeclaration = `const ${element.name} = () => import(${importPath})`;
|
|
105
|
-
return fixer.replaceText(importNodes[element.name], newImportDeclaration);
|
|
106
|
-
},
|
|
107
|
-
});
|
|
108
|
-
},
|
|
109
|
-
};
|
|
110
|
-
},
|
|
111
|
-
});
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const utils_1 = require("@typescript-eslint/utils");
|
|
4
|
-
const utils_2 = require("../utils");
|
|
5
|
-
exports.default = (0, utils_2.createEslintRule)({
|
|
6
|
-
name: 'prefer-lazy-listener-import',
|
|
7
|
-
defaultOptions: [],
|
|
8
|
-
meta: {
|
|
9
|
-
type: 'problem',
|
|
10
|
-
fixable: 'code',
|
|
11
|
-
docs: {
|
|
12
|
-
description: 'Prefer lazy listener import over standard import',
|
|
13
|
-
recommended: 'recommended',
|
|
14
|
-
},
|
|
15
|
-
schema: [],
|
|
16
|
-
messages: {
|
|
17
|
-
preferLazyListenerImport: 'Replace standard import with lazy listener import',
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
create: function (context) {
|
|
21
|
-
let importIdentifiers = [];
|
|
22
|
-
let emitterIdentifier = '';
|
|
23
|
-
let importNodes = [];
|
|
24
|
-
function isEmitterOnCallExpression(node, routerIdentifier) {
|
|
25
|
-
return (node.callee.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
26
|
-
node.callee.object.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
27
|
-
node.callee.object.name === routerIdentifier &&
|
|
28
|
-
node.callee.property.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
29
|
-
node.callee.property.name === 'on');
|
|
30
|
-
}
|
|
31
|
-
return {
|
|
32
|
-
/**
|
|
33
|
-
* Track all imported identifiers
|
|
34
|
-
* Also get the local name of the emitter import
|
|
35
|
-
*/
|
|
36
|
-
ImportDeclaration(node) {
|
|
37
|
-
for (const specifier of node.specifiers) {
|
|
38
|
-
if (specifier.type === 'ImportDefaultSpecifier' || specifier.type === 'ImportSpecifier') {
|
|
39
|
-
importIdentifiers.push(specifier.local.name);
|
|
40
|
-
importNodes[specifier.local.name] = node;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
if (node.source.value === '@adonisjs/core/services/emitter') {
|
|
44
|
-
if (node.specifiers[0] && node.specifiers[0].type === 'ImportDefaultSpecifier') {
|
|
45
|
-
emitterIdentifier = node.specifiers[0].local.name;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
CallExpression(node) {
|
|
50
|
-
/**
|
|
51
|
-
* Check if we are calling emitter.on()
|
|
52
|
-
*/
|
|
53
|
-
if (!isEmitterOnCallExpression(node, emitterIdentifier)) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Ensure the second argument is an array
|
|
58
|
-
*/
|
|
59
|
-
const secondArgument = node.arguments[1];
|
|
60
|
-
if (secondArgument.type !== utils_1.AST_NODE_TYPES.ArrayExpression) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
for (const element of secondArgument.elements) {
|
|
64
|
-
/**
|
|
65
|
-
* If we are dealing with an Identifier that was imported
|
|
66
|
-
* through a standard import, then report it as an error
|
|
67
|
-
*/
|
|
68
|
-
if (element.type !== 'Identifier' || !importIdentifiers.includes(element.name)) {
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
context.report({
|
|
72
|
-
node: importNodes[element.name],
|
|
73
|
-
messageId: 'preferLazyListenerImport',
|
|
74
|
-
fix(fixer) {
|
|
75
|
-
const importPath = importNodes[element.name].source.raw;
|
|
76
|
-
const newImportDeclaration = `const ${element.name} = () => import(${importPath})`;
|
|
77
|
-
return fixer.replaceText(importNodes[element.name], newImportDeclaration);
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
},
|
|
84
|
-
});
|
package/dist/src/utils.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const runner_1 = require("@japa/runner");
|
|
7
|
-
const ts_eslint_1 = require("@typescript-eslint/utils/ts-eslint");
|
|
8
|
-
const prefer_lazy_controller_import_1 = __importDefault(require("../src/rules/prefer_lazy_controller_import"));
|
|
9
|
-
const valids = [
|
|
10
|
-
`
|
|
11
|
-
import router from "@adonisjs/core/services/router"
|
|
12
|
-
const lazyController = () => import("./controller")
|
|
13
|
-
|
|
14
|
-
router.get("/", "HomeController.index")
|
|
15
|
-
router.get("/test", [lazyController, 'index'])
|
|
16
|
-
`,
|
|
17
|
-
`
|
|
18
|
-
import router from "@adonisjs/core/services/router"
|
|
19
|
-
import middleware from '#start/middleware'
|
|
20
|
-
|
|
21
|
-
const lazyController = () => import("./controller")
|
|
22
|
-
|
|
23
|
-
router.get("/", "HomeController.index").middleware(middleware.auth())
|
|
24
|
-
router.get("/test", [lazyController, 'index']).middleware(middleware.auth())
|
|
25
|
-
`,
|
|
26
|
-
];
|
|
27
|
-
const invalids = [
|
|
28
|
-
[
|
|
29
|
-
`
|
|
30
|
-
import router from "@adonisjs/core/services/router"
|
|
31
|
-
import HomeController from "./controller"
|
|
32
|
-
|
|
33
|
-
router.group(() => {
|
|
34
|
-
router.get("/", [HomeController, 'index'])
|
|
35
|
-
})
|
|
36
|
-
`,
|
|
37
|
-
`
|
|
38
|
-
import router from "@adonisjs/core/services/router"
|
|
39
|
-
const HomeController = () => import("./controller")
|
|
40
|
-
|
|
41
|
-
router.group(() => {
|
|
42
|
-
router.get("/", [HomeController, 'index'])
|
|
43
|
-
})
|
|
44
|
-
`,
|
|
45
|
-
],
|
|
46
|
-
/**
|
|
47
|
-
* When used with route.resource
|
|
48
|
-
*/
|
|
49
|
-
[
|
|
50
|
-
`
|
|
51
|
-
import router from "@adonisjs/core/services/router"
|
|
52
|
-
import ProjectThreadsController from "./controller"
|
|
53
|
-
|
|
54
|
-
router.resource("project/:id/threads", ProjectThreadsController)
|
|
55
|
-
`,
|
|
56
|
-
`
|
|
57
|
-
import router from "@adonisjs/core/services/router"
|
|
58
|
-
const ProjectThreadsController = () => import("./controller")
|
|
59
|
-
|
|
60
|
-
router.resource("project/:id/threads", ProjectThreadsController)
|
|
61
|
-
`,
|
|
62
|
-
],
|
|
63
|
-
];
|
|
64
|
-
(0, runner_1.test)('Prefer lazy controller import', ({ assert }) => {
|
|
65
|
-
const ruleTester = new ts_eslint_1.RuleTester({
|
|
66
|
-
parser: require.resolve('@typescript-eslint/parser'),
|
|
67
|
-
});
|
|
68
|
-
ruleTester.run('prefer-lazy-controller-import', prefer_lazy_controller_import_1.default, {
|
|
69
|
-
valid: valids,
|
|
70
|
-
invalid: invalids.map((invalid) => ({
|
|
71
|
-
code: invalid[0],
|
|
72
|
-
output: invalid[1],
|
|
73
|
-
errors: [{ messageId: 'preferLazyControllerImport' }],
|
|
74
|
-
})),
|
|
75
|
-
});
|
|
76
|
-
});
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const runner_1 = require("@japa/runner");
|
|
7
|
-
const ts_eslint_1 = require("@typescript-eslint/utils/ts-eslint");
|
|
8
|
-
const prefer_lazy_listener_import_1 = __importDefault(require("../src/rules/prefer_lazy_listener_import"));
|
|
9
|
-
const valids = [
|
|
10
|
-
`
|
|
11
|
-
import emitter from '@adonisjs/core/services/emitter'
|
|
12
|
-
const SendVerificationEmail = () => import('#listeners/send_verification_email')
|
|
13
|
-
|
|
14
|
-
emitter.on('user:registered', [SendVerificationEmail, 'handle'])
|
|
15
|
-
`,
|
|
16
|
-
];
|
|
17
|
-
const invalids = [
|
|
18
|
-
[
|
|
19
|
-
`
|
|
20
|
-
import emitter from '@adonisjs/core/services/emitter'
|
|
21
|
-
import SendVerificationEmail from '#listeners/send_verification_email'
|
|
22
|
-
|
|
23
|
-
emitter.on('user:registered', [SendVerificationEmail, 'handle'])
|
|
24
|
-
`,
|
|
25
|
-
`
|
|
26
|
-
import emitter from '@adonisjs/core/services/emitter'
|
|
27
|
-
const SendVerificationEmail = () => import('#listeners/send_verification_email')
|
|
28
|
-
|
|
29
|
-
emitter.on('user:registered', [SendVerificationEmail, 'handle'])
|
|
30
|
-
`,
|
|
31
|
-
],
|
|
32
|
-
];
|
|
33
|
-
(0, runner_1.test)('Prefer lazy event listener import', ({ assert }) => {
|
|
34
|
-
const ruleTester = new ts_eslint_1.RuleTester({
|
|
35
|
-
parser: require.resolve('@typescript-eslint/parser'),
|
|
36
|
-
});
|
|
37
|
-
ruleTester.run('prefer-lazy-listener-import', prefer_lazy_listener_import_1.default, {
|
|
38
|
-
valid: valids,
|
|
39
|
-
invalid: invalids.map((invalid) => ({
|
|
40
|
-
code: invalid[0],
|
|
41
|
-
output: invalid[1],
|
|
42
|
-
errors: [{ messageId: 'preferLazyListenerImport' }],
|
|
43
|
-
})),
|
|
44
|
-
});
|
|
45
|
-
});
|