refactor start
This commit is contained in:
parent
bd49791e06
commit
e46d25f0b7
16699 changed files with 2 additions and 1484887 deletions
190
home/ags/node_modules/eslint-plugin-promise/CHANGELOG.md
generated
vendored
190
home/ags/node_modules/eslint-plugin-promise/CHANGELOG.md
generated
vendored
|
|
@ -1,190 +0,0 @@
|
|||
## 6.0.2
|
||||
|
||||
- Added tests for @typescript-eslint/parser support
|
||||
|
||||
## 6.0.1
|
||||
|
||||
- Fixed @typescript-eslint/parser issue #331, #205
|
||||
|
||||
## 6.0.0
|
||||
|
||||
- Dropped node 10 from engines #231
|
||||
- Updated a ton of deps #236, #237, #235, #234
|
||||
- ESLint 8 support #219
|
||||
|
||||
## 5.2.0
|
||||
|
||||
- Updated `param-names` rule to allow for unused params
|
||||
|
||||
## 5.1.1
|
||||
|
||||
- Updated docs to include `no-callback-in-promise` reasons #215
|
||||
|
||||
## 5.1.0
|
||||
|
||||
- Included `catch()` and `finally()` in `prefer-await-to-then` #196
|
||||
- Added some additional tests and upgraded some dev deps #196
|
||||
- Exempted array methods in prefer-await-to-callbacks
|
||||
([#212](https://github.com/eslint-community/eslint-plugin-promise/issues/212))
|
||||
|
||||
## 5.0.0
|
||||
|
||||
- ESLint 7.0 Support
|
||||
|
||||
## 4.3.1.
|
||||
|
||||
- Updated and applied prettier
|
||||
|
||||
## 4.3.0
|
||||
|
||||
- https://github.com/eslint-community/eslint-plugin-promise/pull/202
|
||||
- Updated jest
|
||||
|
||||
## 4.2.2
|
||||
|
||||
- Added license
|
||||
- Dependabot security updates
|
||||
|
||||
## 4.2.1
|
||||
|
||||
- Added more use cases to `no-return-wrap`
|
||||
|
||||
## 4.0.1
|
||||
|
||||
- Remove `promise/param-names` fixer
|
||||
([#146](https://github.com/eslint-community/eslint-plugin-promise/pull/146))
|
||||
|
||||
## 4.0.0
|
||||
|
||||
- Added fixer for `promise/no-new-statics` rule
|
||||
([#133](https://github.com/eslint-community/eslint-plugin-promise/pull/133))
|
||||
- Support ESLint v5
|
||||
([#144](https://github.com/eslint-community/eslint-plugin-promise/pull/144))
|
||||
|
||||
This is a breaking change that drops support for Node v4. In order to use ESLint
|
||||
v5 and eslint-plugin-promise v4, you must use Node >=6.
|
||||
|
||||
## 3.8.0
|
||||
|
||||
- Removed `promise/avoid-new` from recommended configuration
|
||||
([#119](https://github.com/eslint-community/eslint-plugin-promise/pull/119))
|
||||
- Ignored event listener callbacks in `promise/prefer-await-to-callbacks`
|
||||
([#117](https://github.com/eslint-community/eslint-plugin-promise/pull/117))
|
||||
- Ignored top-level awaits in `promise/prefer-await-to-then`
|
||||
([#126](https://github.com/eslint-community/eslint-plugin-promise/pull/126))
|
||||
- Added docs for `promise/no-nesting` and `promise/prefer-await-to-then`
|
||||
([#120](https://github.com/eslint-community/eslint-plugin-promise/pull/120))
|
||||
([#121](https://github.com/eslint-community/eslint-plugin-promise/pull/121))
|
||||
|
||||
## 3.7.0
|
||||
|
||||
- Added `promise/valid-params` rule
|
||||
([#85](https://github.com/eslint-community/eslint-plugin-promise/pull/85))
|
||||
- Added `promise/no-new-statics` rule
|
||||
([#82](https://github.com/eslint-community/eslint-plugin-promise/pull/82))
|
||||
- Added fixer for `promise/param-names` rule
|
||||
([#99](https://github.com/eslint-community/eslint-plugin-promise/pull/99))
|
||||
- Added rule documentation to each rule
|
||||
([#91](https://github.com/eslint-community/eslint-plugin-promise/pull/91))
|
||||
|
||||
## 3.6.0
|
||||
|
||||
- Added `['catch']` support in `catch-or-return`
|
||||
- Added `no-return-in-finally` rule
|
||||
- Fixed some formatting in the docs
|
||||
- Added `allowReject` option to `no-return-wrap`
|
||||
- Added exceptions for `no-callback-in-promise`
|
||||
|
||||
## 3.5.0
|
||||
|
||||
- Added support for recommended settings using
|
||||
`extends: plugin:promise/recommended`
|
||||
|
||||
## 3.4.2
|
||||
|
||||
- Fixed always return false positive with ternary (#31)
|
||||
|
||||
## 3.4.1
|
||||
|
||||
- fixed #49
|
||||
|
||||
## 3.4.0
|
||||
|
||||
- new rule: avoid-new
|
||||
- new rule: no-promise-in-callback
|
||||
- new rule: no-callback-in-promise
|
||||
- new rule: no-nesting
|
||||
|
||||
## 3.3.2
|
||||
|
||||
- Removed eslint from peerDeps
|
||||
|
||||
## 3.3.1
|
||||
|
||||
- Updated engines with proper stuff
|
||||
- Fixed bug for unreachable code
|
||||
|
||||
## 3.3.0
|
||||
|
||||
- Rule: `prefer-async-to-callbacks` added
|
||||
- Rule: `prefer-async-to-then` added
|
||||
|
||||
## 3.2.1
|
||||
|
||||
- Fix: `no-return-wrap` rule missing from index.js
|
||||
|
||||
## 3.2.0
|
||||
|
||||
- Added `no-return-wrap` rule
|
||||
|
||||
## 3.1.0
|
||||
|
||||
- Added multiple terminationMethods
|
||||
|
||||
## 3.0.1
|
||||
|
||||
- Removed deprecated `always-catch` rule
|
||||
- FIX: always-return error with "fn && fn()"
|
||||
|
||||
## 3.0.0
|
||||
|
||||
- Updated column and line numbers
|
||||
- Added flow analysis for better handling of if statements
|
||||
|
||||
## 2.0.1
|
||||
|
||||
- Fixed type in docs
|
||||
|
||||
## 2.0.0
|
||||
|
||||
- ESLint 3.0 Support
|
||||
|
||||
## 1.3.2
|
||||
|
||||
- Updated tests to run on eslint 2.0
|
||||
- Fixed some issues with `no-native` rule
|
||||
|
||||
## 1.3.1
|
||||
|
||||
- Actually added `no-native` rule
|
||||
|
||||
## 1.3.0
|
||||
|
||||
- Added `no-native` rule
|
||||
|
||||
## 1.2.0
|
||||
|
||||
- Allow `throw` in `always-return` rule
|
||||
- Added `terminationMethod` option to `catch-or-return` rule
|
||||
|
||||
## 1.1.0
|
||||
|
||||
- Added `catch-or-return` rule
|
||||
|
||||
## 1.0.8
|
||||
|
||||
- Fixed crash issues
|
||||
|
||||
## 1.0.0 - 1.0.7
|
||||
|
||||
- Lots of basic feature updates and doc changes
|
||||
13
home/ags/node_modules/eslint-plugin-promise/LICENSE.md
generated
vendored
13
home/ags/node_modules/eslint-plugin-promise/LICENSE.md
generated
vendored
|
|
@ -1,13 +0,0 @@
|
|||
Copyright (c) 2020, Jamund Ferguson
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||
with or without fee is hereby granted, provided that the above copyright notice
|
||||
and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
123
home/ags/node_modules/eslint-plugin-promise/README.md
generated
vendored
123
home/ags/node_modules/eslint-plugin-promise/README.md
generated
vendored
|
|
@ -1,123 +0,0 @@
|
|||
# eslint-plugin-promise
|
||||
|
||||
Enforce best practices for JavaScript promises.
|
||||
|
||||
[](https://github.com/eslint-community/eslint-plugin-promise/actions/workflows/CI.yml)
|
||||
[](https://www.npmjs.com/package/eslint-plugin-promise)
|
||||
[](https://github.com/prettier/prettier)
|
||||
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [Rules](#rules)
|
||||
- [Maintainers](#maintainers)
|
||||
- [License](#license)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
## Installation
|
||||
|
||||
You'll first need to install [ESLint](http://eslint.org):
|
||||
|
||||
```sh
|
||||
npm install eslint --save-dev
|
||||
```
|
||||
|
||||
Next, install `eslint-plugin-promise`:
|
||||
|
||||
```sh
|
||||
npm install eslint-plugin-promise --save-dev
|
||||
```
|
||||
|
||||
**Note:** If you installed ESLint globally (using the `-g` flag) then you must
|
||||
also install `eslint-plugin-promise` globally.
|
||||
|
||||
## Usage
|
||||
|
||||
Add `promise` to the plugins section of your `.eslintrc.json` configuration
|
||||
file. You can omit the `eslint-plugin-` prefix:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["promise"]
|
||||
}
|
||||
```
|
||||
|
||||
Then configure the rules you want to use under the rules section.
|
||||
|
||||
```json
|
||||
{
|
||||
"rules": {
|
||||
"promise/always-return": "error",
|
||||
"promise/no-return-wrap": "error",
|
||||
"promise/param-names": "error",
|
||||
"promise/catch-or-return": "error",
|
||||
"promise/no-native": "off",
|
||||
"promise/no-nesting": "warn",
|
||||
"promise/no-promise-in-callback": "warn",
|
||||
"promise/no-callback-in-promise": "warn",
|
||||
"promise/avoid-new": "warn",
|
||||
"promise/no-new-statics": "error",
|
||||
"promise/no-return-in-finally": "warn",
|
||||
"promise/valid-params": "warn"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
or start with the recommended rule set:
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": ["plugin:promise/recommended"]
|
||||
}
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
<!-- begin auto-generated rules list -->
|
||||
|
||||
💼 Configurations enabled in.\
|
||||
⚠️ Configurations set to warn in.\
|
||||
🚫 Configurations disabled in.\
|
||||
✅ Set in the `recommended` configuration.\
|
||||
🔧 Automatically fixable by the
|
||||
[`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).
|
||||
|
||||
| Name | Description | 💼 | ⚠️ | 🚫 | 🔧 |
|
||||
| :------------------------------------------------------------------- | :------------------------------------------------------------------------------------- | :-- | :-- | :-- | :-- |
|
||||
| [always-return](docs/rules/always-return.md) | Require returning inside each `then()` to create readable and reusable Promise chains. | ✅ | | | |
|
||||
| [avoid-new](docs/rules/avoid-new.md) | Disallow creating `new` promises outside of utility libs (use [pify][] instead). | | | ✅ | |
|
||||
| [catch-or-return](docs/rules/catch-or-return.md) | Enforce the use of `catch()` on un-returned promises. | ✅ | | | |
|
||||
| [no-callback-in-promise](docs/rules/no-callback-in-promise.md) | Disallow calling `cb()` inside of a `then()` (use [nodeify][] instead). | | ✅ | | |
|
||||
| [no-multiple-resolved](docs/rules/no-multiple-resolved.md) | Disallow creating new promises with paths that resolve multiple times. | | | | |
|
||||
| [no-native](docs/rules/no-native.md) | Require creating a `Promise` constructor before using it in an ES5 environment. | | | ✅ | |
|
||||
| [no-nesting](docs/rules/no-nesting.md) | Disallow nested `then()` or `catch()` statements. | | ✅ | | |
|
||||
| [no-new-statics](docs/rules/no-new-statics.md) | Disallow calling `new` on a Promise static method. | ✅ | | | 🔧 |
|
||||
| [no-promise-in-callback](docs/rules/no-promise-in-callback.md) | Disallow using promises inside of callbacks. | | ✅ | | |
|
||||
| [no-return-in-finally](docs/rules/no-return-in-finally.md) | Disallow return statements in `finally()`. | | ✅ | | |
|
||||
| [no-return-wrap](docs/rules/no-return-wrap.md) | Disallow wrapping values in `Promise.resolve` or `Promise.reject` when not needed. | ✅ | | | |
|
||||
| [param-names](docs/rules/param-names.md) | Enforce consistent param names and ordering when creating new promises. | ✅ | | | |
|
||||
| [prefer-await-to-callbacks](docs/rules/prefer-await-to-callbacks.md) | Prefer async/await to the callback pattern. | | | | |
|
||||
| [prefer-await-to-then](docs/rules/prefer-await-to-then.md) | Prefer `await` to `then()`/`catch()`/`finally()` for reading Promise values. | | | | |
|
||||
| [valid-params](docs/rules/valid-params.md) | Enforces the proper number of arguments are passed to Promise functions. | | ✅ | | |
|
||||
|
||||
<!-- end auto-generated rules list -->
|
||||
|
||||
## Maintainers
|
||||
|
||||
- Jamund Ferguson - [@xjamundx][]
|
||||
- Macklin Underdown - [@macklinu][]
|
||||
- Aadit M Shah - [@aaditmshah][]
|
||||
|
||||
## License
|
||||
|
||||
- (c) MMXV jden <mailto:jason@denizac.org> - ISC license.
|
||||
- (c) 2016 Jamund Ferguson <mailto:jamund@gmail.com> - ISC license.
|
||||
|
||||
[nodeify]: https://www.npmjs.com/package/nodeify
|
||||
[pify]: https://www.npmjs.com/package/pify
|
||||
[@aaditmshah]: https://github.com/aaditmshah
|
||||
[@macklinu]: https://github.com/macklinu
|
||||
[@xjamundx]: https://github.com/xjamundx
|
||||
47
home/ags/node_modules/eslint-plugin-promise/index.js
generated
vendored
47
home/ags/node_modules/eslint-plugin-promise/index.js
generated
vendored
|
|
@ -1,47 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
rules: {
|
||||
'param-names': require('./rules/param-names'),
|
||||
'no-return-wrap': require('./rules/no-return-wrap'),
|
||||
'always-return': require('./rules/always-return'),
|
||||
'catch-or-return': require('./rules/catch-or-return'),
|
||||
'prefer-await-to-callbacks': require('./rules/prefer-await-to-callbacks'),
|
||||
'prefer-await-to-then': require('./rules/prefer-await-to-then'),
|
||||
'no-native': require('./rules/no-native'),
|
||||
'no-callback-in-promise': require('./rules/no-callback-in-promise'),
|
||||
'no-promise-in-callback': require('./rules/no-promise-in-callback'),
|
||||
'no-nesting': require('./rules/no-nesting'),
|
||||
'avoid-new': require('./rules/avoid-new'),
|
||||
'no-new-statics': require('./rules/no-new-statics'),
|
||||
'no-return-in-finally': require('./rules/no-return-in-finally'),
|
||||
'valid-params': require('./rules/valid-params'),
|
||||
'no-multiple-resolved': require('./rules/no-multiple-resolved'),
|
||||
},
|
||||
rulesConfig: {
|
||||
'param-names': 1,
|
||||
'always-return': 1,
|
||||
'no-return-wrap': 1,
|
||||
'no-native': 0,
|
||||
'catch-or-return': 1,
|
||||
},
|
||||
configs: {
|
||||
recommended: {
|
||||
plugins: ['promise'],
|
||||
rules: {
|
||||
'promise/always-return': 'error',
|
||||
'promise/no-return-wrap': 'error',
|
||||
'promise/param-names': 'error',
|
||||
'promise/catch-or-return': 'error',
|
||||
'promise/no-native': 'off',
|
||||
'promise/no-nesting': 'warn',
|
||||
'promise/no-promise-in-callback': 'warn',
|
||||
'promise/no-callback-in-promise': 'warn',
|
||||
'promise/avoid-new': 'off',
|
||||
'promise/no-new-statics': 'error',
|
||||
'promise/no-return-in-finally': 'warn',
|
||||
'promise/valid-params': 'warn',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
93
home/ags/node_modules/eslint-plugin-promise/package.json
generated
vendored
93
home/ags/node_modules/eslint-plugin-promise/package.json
generated
vendored
|
|
@ -1,93 +0,0 @@
|
|||
{
|
||||
"name": "eslint-plugin-promise",
|
||||
"version": "6.2.0",
|
||||
"description": "Enforce best practices for JavaScript promises",
|
||||
"keywords": [
|
||||
"eslint",
|
||||
"eslintplugin",
|
||||
"eslint-plugin",
|
||||
"promise",
|
||||
"promises"
|
||||
],
|
||||
"homepage": "https://github.com/eslint-community/eslint-plugin-promise",
|
||||
"bugs": "https://github.com/eslint-community/eslint-plugin-promise/issues",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/eslint-community/eslint-plugin-promise"
|
||||
},
|
||||
"license": "ISC",
|
||||
"author": "jden <jason@denizac.org>",
|
||||
"contributors": [
|
||||
"Brett Zamir",
|
||||
"Aadit M Shah <aaditmshah@aadit.codes> (https://aadit.codes/)"
|
||||
],
|
||||
"scripts": {
|
||||
"format": "prettier --write .",
|
||||
"lint": "npm-run-all \"lint:*\"",
|
||||
"lint:eslint-docs": "npm run update:eslint-docs && git diff --exit-code",
|
||||
"lint:js": "eslint --report-unused-disable-directives .",
|
||||
"prepare": "husky install",
|
||||
"test": "jest --coverage",
|
||||
"update:eslint-docs": "eslint-doc-generator && npm run format"
|
||||
},
|
||||
"lint-staged": {
|
||||
"{README.md,CONTRIBUTING.md}": [
|
||||
"doctoc --maxlevel 3 --notitle"
|
||||
],
|
||||
"*.js": [
|
||||
"prettier --write",
|
||||
"eslint --report-unused-disable-directives --fix"
|
||||
],
|
||||
"*.+(json|md)": [
|
||||
"prettier --write"
|
||||
]
|
||||
},
|
||||
"prettier": {
|
||||
"proseWrap": "always",
|
||||
"semi": false,
|
||||
"singleQuote": true
|
||||
},
|
||||
"jest": {
|
||||
"coverageThreshold": {
|
||||
"global": {
|
||||
"branches": 100,
|
||||
"functions": 100,
|
||||
"lines": 100,
|
||||
"statements": 100
|
||||
}
|
||||
},
|
||||
"collectCoverageFrom": [
|
||||
"rules/*.js",
|
||||
"rules/*/*.js",
|
||||
"!rules/lib/eslint-compat.js"
|
||||
],
|
||||
"testPathIgnorePatterns": [
|
||||
"__tests__/rule-tester.js"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/parser": "^5.45.0",
|
||||
"doctoc": "^2.2.1",
|
||||
"eslint": "^8.28.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-doc-generator": "^0.25.0",
|
||||
"eslint-plugin-eslint-plugin": "^4.4.1",
|
||||
"eslint-plugin-jest": "^26.9.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"globals": "^14.0.0",
|
||||
"husky": "^7.0.4",
|
||||
"jest": "^28.1.3",
|
||||
"lint-staged": "^12.5.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.7.1",
|
||||
"typescript": "^4.9.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": "https://opencollective.com/eslint"
|
||||
}
|
||||
253
home/ags/node_modules/eslint-plugin-promise/rules/always-return.js
generated
vendored
253
home/ags/node_modules/eslint-plugin-promise/rules/always-return.js
generated
vendored
|
|
@ -1,253 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
|
||||
/**
|
||||
* @typedef {import('estree').Node} Node
|
||||
* @typedef {import('estree').SimpleCallExpression} CallExpression
|
||||
* @typedef {import('estree').FunctionExpression} FunctionExpression
|
||||
* @typedef {import('estree').ArrowFunctionExpression} ArrowFunctionExpression
|
||||
* @typedef {import('eslint').Rule.CodePath} CodePath
|
||||
* @typedef {import('eslint').Rule.CodePathSegment} CodePathSegment
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef { (FunctionExpression | ArrowFunctionExpression) & { parent: CallExpression }} InlineThenFunctionExpression
|
||||
*/
|
||||
|
||||
/** @param {Node} node */
|
||||
function isFunctionWithBlockStatement(node) {
|
||||
if (node.type === 'FunctionExpression') {
|
||||
return true
|
||||
}
|
||||
if (node.type === 'ArrowFunctionExpression') {
|
||||
return node.body.type === 'BlockStatement'
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} memberName
|
||||
* @param {Node} node
|
||||
* @returns {node is CallExpression}
|
||||
*/
|
||||
function isMemberCall(memberName, node) {
|
||||
return (
|
||||
node.type === 'CallExpression' &&
|
||||
node.callee.type === 'MemberExpression' &&
|
||||
!node.callee.computed &&
|
||||
node.callee.property.type === 'Identifier' &&
|
||||
node.callee.property.name === memberName
|
||||
)
|
||||
}
|
||||
|
||||
/** @param {Node} node */
|
||||
function isFirstArgument(node) {
|
||||
return Boolean(
|
||||
node.parent && node.parent.arguments && node.parent.arguments[0] === node
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {node is InlineThenFunctionExpression}
|
||||
*/
|
||||
function isInlineThenFunctionExpression(node) {
|
||||
return (
|
||||
isFunctionWithBlockStatement(node) &&
|
||||
isMemberCall('then', node.parent) &&
|
||||
isFirstArgument(node)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given node is the last `then()` callback in a promise chain.
|
||||
* @param {InlineThenFunctionExpression} node
|
||||
*/
|
||||
function isLastCallback(node) {
|
||||
/** @type {Node} */
|
||||
let target = node.parent
|
||||
/** @type {Node | undefined} */
|
||||
let parent = target.parent
|
||||
while (parent) {
|
||||
if (parent.type === 'ExpressionStatement') {
|
||||
// e.g. { promise.then(() => value) }
|
||||
return true
|
||||
}
|
||||
if (parent.type === 'UnaryExpression') {
|
||||
// e.g. void promise.then(() => value)
|
||||
return parent.operator === 'void'
|
||||
}
|
||||
/** @type {Node | null} */
|
||||
let nextTarget = null
|
||||
if (parent.type === 'SequenceExpression') {
|
||||
if (peek(parent.expressions) !== target) {
|
||||
// e.g. (promise?.then(() => value), expr)
|
||||
return true
|
||||
}
|
||||
nextTarget = parent
|
||||
} else if (
|
||||
// e.g. promise?.then(() => value)
|
||||
parent.type === 'ChainExpression' ||
|
||||
// e.g. await promise.then(() => value)
|
||||
parent.type === 'AwaitExpression'
|
||||
) {
|
||||
nextTarget = parent
|
||||
} else if (parent.type === 'MemberExpression') {
|
||||
if (
|
||||
parent.parent &&
|
||||
(isMemberCall('catch', parent.parent) ||
|
||||
isMemberCall('finally', parent.parent))
|
||||
) {
|
||||
// e.g. promise.then(() => value).catch(e => {})
|
||||
nextTarget = parent.parent
|
||||
}
|
||||
}
|
||||
if (nextTarget) {
|
||||
target = nextTarget
|
||||
parent = target.parent
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T[]} arr
|
||||
* @returns {T}
|
||||
*/
|
||||
function peek(arr) {
|
||||
return arr[arr.length - 1]
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'Require returning inside each `then()` to create readable and reusable Promise chains.',
|
||||
url: getDocsUrl('always-return'),
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
ignoreLastCallback: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
create(context) {
|
||||
const options = context.options[0] || {}
|
||||
const ignoreLastCallback = !!options.ignoreLastCallback
|
||||
/**
|
||||
* @typedef {object} FuncInfo
|
||||
* @property {string[]} branchIDStack This is a stack representing the currently
|
||||
* executing branches ("codePathSegment"s) within the given function
|
||||
* @property {Record<string, BranchInfo | undefined>} branchInfoMap This is an object representing information
|
||||
* about all branches within the given function
|
||||
*
|
||||
* @typedef {object} BranchInfo
|
||||
* @property {boolean} good This is a boolean representing whether
|
||||
* the given branch explicitly `return`s or `throw`s. It starts as `false`
|
||||
* for every branch and is updated to `true` if a `return` or `throw`
|
||||
* statement is found
|
||||
* @property {Node} node This is a estree Node object
|
||||
* for the given branch
|
||||
*/
|
||||
|
||||
/**
|
||||
* funcInfoStack is a stack representing the stack of currently executing
|
||||
* functions
|
||||
* example:
|
||||
* funcInfoStack = [ { branchIDStack: [ 's1_1' ],
|
||||
* branchInfoMap:
|
||||
* { s1_1:
|
||||
* { good: false,
|
||||
* loc: <loc> } } },
|
||||
* { branchIDStack: ['s2_1', 's2_4'],
|
||||
* branchInfoMap:
|
||||
* { s2_1:
|
||||
* { good: false,
|
||||
* loc: <loc> },
|
||||
* s2_2:
|
||||
* { good: true,
|
||||
* loc: <loc> },
|
||||
* s2_4:
|
||||
* { good: false,
|
||||
* loc: <loc> } } } ]
|
||||
* @type {FuncInfo[]}
|
||||
*/
|
||||
const funcInfoStack = []
|
||||
|
||||
function markCurrentBranchAsGood() {
|
||||
const funcInfo = peek(funcInfoStack)
|
||||
const currentBranchID = peek(funcInfo.branchIDStack)
|
||||
if (funcInfo.branchInfoMap[currentBranchID]) {
|
||||
funcInfo.branchInfoMap[currentBranchID].good = true
|
||||
}
|
||||
// else unreachable code
|
||||
}
|
||||
|
||||
return {
|
||||
'ReturnStatement:exit': markCurrentBranchAsGood,
|
||||
'ThrowStatement:exit': markCurrentBranchAsGood,
|
||||
|
||||
/**
|
||||
* @param {CodePathSegment} segment
|
||||
* @param {Node} node
|
||||
*/
|
||||
onCodePathSegmentStart(segment, node) {
|
||||
const funcInfo = peek(funcInfoStack)
|
||||
funcInfo.branchIDStack.push(segment.id)
|
||||
funcInfo.branchInfoMap[segment.id] = { good: false, node }
|
||||
},
|
||||
|
||||
onCodePathSegmentEnd() {
|
||||
const funcInfo = peek(funcInfoStack)
|
||||
funcInfo.branchIDStack.pop()
|
||||
},
|
||||
|
||||
onCodePathStart() {
|
||||
funcInfoStack.push({
|
||||
branchIDStack: [],
|
||||
branchInfoMap: {},
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {CodePath} path
|
||||
* @param {Node} node
|
||||
*/
|
||||
onCodePathEnd(path, node) {
|
||||
const funcInfo = funcInfoStack.pop()
|
||||
|
||||
if (!isInlineThenFunctionExpression(node)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (ignoreLastCallback && isLastCallback(node)) {
|
||||
return
|
||||
}
|
||||
|
||||
path.finalSegments.forEach((segment) => {
|
||||
const id = segment.id
|
||||
const branch = funcInfo.branchInfoMap[id]
|
||||
if (!branch.good) {
|
||||
context.report({
|
||||
message: 'Each then() should return a value or throw',
|
||||
node: branch.node,
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
29
home/ags/node_modules/eslint-plugin-promise/rules/avoid-new.js
generated
vendored
29
home/ags/node_modules/eslint-plugin-promise/rules/avoid-new.js
generated
vendored
|
|
@ -1,29 +0,0 @@
|
|||
/**
|
||||
* Rule: avoid-new
|
||||
* Avoid creating new promises outside of utility libraries.
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description:
|
||||
'Disallow creating `new` promises outside of utility libs (use [pify][] instead).',
|
||||
url: getDocsUrl('avoid-new'),
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
NewExpression(node) {
|
||||
if (node.callee.name === 'Promise') {
|
||||
context.report({ node, message: 'Avoid creating new promises.' })
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
122
home/ags/node_modules/eslint-plugin-promise/rules/catch-or-return.js
generated
vendored
122
home/ags/node_modules/eslint-plugin-promise/rules/catch-or-return.js
generated
vendored
|
|
@ -1,122 +0,0 @@
|
|||
/**
|
||||
* Rule: catch-or-return
|
||||
* Ensures that promises either include a catch() handler
|
||||
* or are returned (to be handled upstream)
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
const isPromise = require('./lib/is-promise')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Enforce the use of `catch()` on un-returned promises.',
|
||||
url: getDocsUrl('catch-or-return'),
|
||||
},
|
||||
messages: {
|
||||
terminationMethod: 'Expected {{ terminationMethod }}() or return',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
allowFinally: {
|
||||
type: 'boolean',
|
||||
},
|
||||
allowThen: {
|
||||
type: 'boolean',
|
||||
},
|
||||
terminationMethod: {
|
||||
oneOf: [
|
||||
{ type: 'string' },
|
||||
{
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
create(context) {
|
||||
const options = context.options[0] || {}
|
||||
const allowThen = options.allowThen
|
||||
const allowFinally = options.allowFinally
|
||||
let terminationMethod = options.terminationMethod || 'catch'
|
||||
|
||||
if (typeof terminationMethod === 'string') {
|
||||
terminationMethod = [terminationMethod]
|
||||
}
|
||||
|
||||
function isAllowedPromiseTermination(expression) {
|
||||
// somePromise.then(a, b)
|
||||
if (
|
||||
allowThen &&
|
||||
expression.type === 'CallExpression' &&
|
||||
expression.callee.type === 'MemberExpression' &&
|
||||
expression.callee.property.name === 'then' &&
|
||||
expression.arguments.length === 2
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
// somePromise.catch().finally(fn)
|
||||
if (
|
||||
allowFinally &&
|
||||
expression.type === 'CallExpression' &&
|
||||
expression.callee.type === 'MemberExpression' &&
|
||||
expression.callee.property.name === 'finally' &&
|
||||
isPromise(expression.callee.object) &&
|
||||
isAllowedPromiseTermination(expression.callee.object)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
// somePromise.catch()
|
||||
if (
|
||||
expression.type === 'CallExpression' &&
|
||||
expression.callee.type === 'MemberExpression' &&
|
||||
terminationMethod.indexOf(expression.callee.property.name) !== -1
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
// somePromise['catch']()
|
||||
if (
|
||||
expression.type === 'CallExpression' &&
|
||||
expression.callee.type === 'MemberExpression' &&
|
||||
expression.callee.property.type === 'Literal' &&
|
||||
expression.callee.property.value === 'catch'
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return {
|
||||
ExpressionStatement(node) {
|
||||
if (!isPromise(node.expression)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (isAllowedPromiseTermination(node.expression)) {
|
||||
return
|
||||
}
|
||||
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'terminationMethod',
|
||||
data: { terminationMethod },
|
||||
})
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
33
home/ags/node_modules/eslint-plugin-promise/rules/lib/eslint-compat.js
generated
vendored
33
home/ags/node_modules/eslint-plugin-promise/rules/lib/eslint-compat.js
generated
vendored
|
|
@ -1,33 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
function getSourceCode(context) {
|
||||
if (context.sourceCode != null) {
|
||||
return context.sourceCode
|
||||
}
|
||||
|
||||
return context.getSourceCode()
|
||||
}
|
||||
|
||||
function getAncestors(context, node) {
|
||||
const sourceCode = getSourceCode(context)
|
||||
if (typeof sourceCode.getAncestors === 'function') {
|
||||
return sourceCode.getAncestors(node)
|
||||
}
|
||||
|
||||
return context.getAncestors(node)
|
||||
}
|
||||
|
||||
function getScope(context, node) {
|
||||
const sourceCode = getSourceCode(context)
|
||||
if (typeof sourceCode.getScope === 'function') {
|
||||
return sourceCode.getScope(node)
|
||||
}
|
||||
|
||||
return context.getScope(node)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getSourceCode,
|
||||
getAncestors,
|
||||
getScope,
|
||||
}
|
||||
17
home/ags/node_modules/eslint-plugin-promise/rules/lib/get-docs-url.js
generated
vendored
17
home/ags/node_modules/eslint-plugin-promise/rules/lib/get-docs-url.js
generated
vendored
|
|
@ -1,17 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const REPO_URL = 'https://github.com/eslint-community/eslint-plugin-promise'
|
||||
|
||||
/**
|
||||
* Generates the URL to documentation for the given rule name. It uses the
|
||||
* package version to build the link to a tagged version of the
|
||||
* documentation file.
|
||||
*
|
||||
* @param {string} ruleName - Name of the eslint rule
|
||||
* @returns {string} URL to the documentation for the given rule
|
||||
*/
|
||||
function getDocsUrl(ruleName) {
|
||||
return `${REPO_URL}/blob/main/docs/rules/${ruleName}.md`
|
||||
}
|
||||
|
||||
module.exports = getDocsUrl
|
||||
37
home/ags/node_modules/eslint-plugin-promise/rules/lib/has-promise-callback.js
generated
vendored
37
home/ags/node_modules/eslint-plugin-promise/rules/lib/has-promise-callback.js
generated
vendored
|
|
@ -1,37 +0,0 @@
|
|||
/**
|
||||
* Library: Has Promise Callback
|
||||
* Makes sure that an Expression node is part of a promise
|
||||
* with callback functions (like then() or catch())
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* @typedef {import('estree').SimpleCallExpression} CallExpression
|
||||
* @typedef {import('estree').MemberExpression} MemberExpression
|
||||
* @typedef {import('estree').Identifier} Identifier
|
||||
*
|
||||
* @typedef {object} NameIsThenOrCatch
|
||||
* @property {'then' | 'catch'} name
|
||||
*
|
||||
* @typedef {object} PropertyIsThenOrCatch
|
||||
* @property {Identifier & NameIsThenOrCatch} property
|
||||
*
|
||||
* @typedef {object} CalleeIsPromiseCallback
|
||||
* @property {MemberExpression & PropertyIsThenOrCatch} callee
|
||||
*
|
||||
* @typedef {CallExpression & CalleeIsPromiseCallback} HasPromiseCallback
|
||||
*/
|
||||
/**
|
||||
* @param {import('estree').Node} node
|
||||
* @returns {node is HasPromiseCallback}
|
||||
*/
|
||||
function hasPromiseCallback(node) {
|
||||
// istanbul ignore if -- only being called within `CallExpression`
|
||||
if (node.type !== 'CallExpression') return
|
||||
if (node.callee.type !== 'MemberExpression') return
|
||||
const propertyName = node.callee.property.name
|
||||
return propertyName === 'then' || propertyName === 'catch'
|
||||
}
|
||||
|
||||
module.exports = hasPromiseCallback
|
||||
14
home/ags/node_modules/eslint-plugin-promise/rules/lib/is-callback.js
generated
vendored
14
home/ags/node_modules/eslint-plugin-promise/rules/lib/is-callback.js
generated
vendored
|
|
@ -1,14 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const isNamedCallback = require('./is-named-callback')
|
||||
|
||||
function isCallback(node, exceptions) {
|
||||
const isCallExpression = node.type === 'CallExpression'
|
||||
// istanbul ignore next -- always invoked on `CallExpression`
|
||||
const callee = node.callee || {}
|
||||
const nameIsCallback = isNamedCallback(callee.name, exceptions)
|
||||
const isCB = isCallExpression && nameIsCallback
|
||||
return isCB
|
||||
}
|
||||
|
||||
module.exports = isCallback
|
||||
20
home/ags/node_modules/eslint-plugin-promise/rules/lib/is-inside-callback.js
generated
vendored
20
home/ags/node_modules/eslint-plugin-promise/rules/lib/is-inside-callback.js
generated
vendored
|
|
@ -1,20 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const isInsidePromise = require('./is-inside-promise')
|
||||
|
||||
function isInsideCallback(node) {
|
||||
const isCallExpression =
|
||||
node.type === 'FunctionExpression' ||
|
||||
node.type === 'ArrowFunctionExpression' ||
|
||||
node.type === 'FunctionDeclaration' // this may be controversial
|
||||
|
||||
// it's totally fine to use promises inside promises
|
||||
if (isInsidePromise(node)) return
|
||||
|
||||
const name = node.params && node.params[0] && node.params[0].name
|
||||
const firstArgIsError = name === 'err' || name === 'error'
|
||||
const isInACallback = isCallExpression && firstArgIsError
|
||||
return isInACallback
|
||||
}
|
||||
|
||||
module.exports = isInsideCallback
|
||||
15
home/ags/node_modules/eslint-plugin-promise/rules/lib/is-inside-promise.js
generated
vendored
15
home/ags/node_modules/eslint-plugin-promise/rules/lib/is-inside-promise.js
generated
vendored
|
|
@ -1,15 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
function isInsidePromise(node) {
|
||||
const isFunctionExpression =
|
||||
node.type === 'FunctionExpression' ||
|
||||
node.type === 'ArrowFunctionExpression'
|
||||
const parent = node.parent || {}
|
||||
const callee = parent.callee || {}
|
||||
const name = (callee.property && callee.property.name) || ''
|
||||
const parentIsPromise = name === 'then' || name === 'catch'
|
||||
const isInCB = isFunctionExpression && parentIsPromise
|
||||
return isInCB
|
||||
}
|
||||
|
||||
module.exports = isInsidePromise
|
||||
14
home/ags/node_modules/eslint-plugin-promise/rules/lib/is-named-callback.js
generated
vendored
14
home/ags/node_modules/eslint-plugin-promise/rules/lib/is-named-callback.js
generated
vendored
|
|
@ -1,14 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
let callbacks = ['done', 'cb', 'callback', 'next']
|
||||
|
||||
module.exports = function isNamedCallback(potentialCallbackName, exceptions) {
|
||||
for (let i = 0; i < exceptions.length; i++) {
|
||||
callbacks = callbacks.filter((item) => {
|
||||
return item !== exceptions[i]
|
||||
})
|
||||
}
|
||||
return callbacks.some((trueCallbackName) => {
|
||||
return potentialCallbackName === trueCallbackName
|
||||
})
|
||||
}
|
||||
48
home/ags/node_modules/eslint-plugin-promise/rules/lib/is-promise-constructor.js
generated
vendored
48
home/ags/node_modules/eslint-plugin-promise/rules/lib/is-promise-constructor.js
generated
vendored
|
|
@ -1,48 +0,0 @@
|
|||
/**
|
||||
* Library: isPromiseConstructor
|
||||
* Makes sure that an Expression node is new Promise().
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* @typedef {import('estree').Node} Node
|
||||
* @typedef {import('estree').Expression} Expression
|
||||
* @typedef {import('estree').NewExpression} NewExpression
|
||||
* @typedef {import('estree').FunctionExpression} FunctionExpression
|
||||
* @typedef {import('estree').ArrowFunctionExpression} ArrowFunctionExpression
|
||||
*
|
||||
* @typedef {NewExpression & { callee: { type: 'Identifier', name: 'Promise' } }} NewPromise
|
||||
* @typedef {NewPromise & { arguments: [FunctionExpression | ArrowFunctionExpression] }} NewPromiseWithInlineExecutor
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Checks whether the given node is new Promise().
|
||||
* @param {Node} node
|
||||
* @returns {node is NewPromise}
|
||||
*/
|
||||
function isPromiseConstructor(node) {
|
||||
return (
|
||||
node.type === 'NewExpression' &&
|
||||
node.callee.type === 'Identifier' &&
|
||||
node.callee.name === 'Promise'
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given node is new Promise(() => {}).
|
||||
* @param {Node} node
|
||||
* @returns {node is NewPromiseWithInlineExecutor}
|
||||
*/
|
||||
function isPromiseConstructorWithInlineExecutor(node) {
|
||||
return (
|
||||
isPromiseConstructor(node) &&
|
||||
node.arguments.length === 1 &&
|
||||
(node.arguments[0].type === 'FunctionExpression' ||
|
||||
node.arguments[0].type === 'ArrowFunctionExpression')
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isPromiseConstructor,
|
||||
isPromiseConstructorWithInlineExecutor,
|
||||
}
|
||||
36
home/ags/node_modules/eslint-plugin-promise/rules/lib/is-promise.js
generated
vendored
36
home/ags/node_modules/eslint-plugin-promise/rules/lib/is-promise.js
generated
vendored
|
|
@ -1,36 +0,0 @@
|
|||
/**
|
||||
* Library: isPromise
|
||||
* Makes sure that an Expression node is part of a promise.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const PROMISE_STATICS = require('./promise-statics')
|
||||
|
||||
function isPromise(expression) {
|
||||
return (
|
||||
// hello.then()
|
||||
(expression.type === 'CallExpression' &&
|
||||
expression.callee.type === 'MemberExpression' &&
|
||||
expression.callee.property.name === 'then') ||
|
||||
// hello.catch()
|
||||
(expression.type === 'CallExpression' &&
|
||||
expression.callee.type === 'MemberExpression' &&
|
||||
expression.callee.property.name === 'catch') ||
|
||||
// hello.finally()
|
||||
(expression.type === 'CallExpression' &&
|
||||
expression.callee.type === 'MemberExpression' &&
|
||||
expression.callee.property.name === 'finally') ||
|
||||
// somePromise.ANYTHING()
|
||||
(expression.type === 'CallExpression' &&
|
||||
expression.callee.type === 'MemberExpression' &&
|
||||
isPromise(expression.callee.object)) ||
|
||||
// Promise.STATIC_METHOD()
|
||||
(expression.type === 'CallExpression' &&
|
||||
expression.callee.type === 'MemberExpression' &&
|
||||
expression.callee.object.type === 'Identifier' &&
|
||||
expression.callee.object.name === 'Promise' &&
|
||||
PROMISE_STATICS[expression.callee.property.name])
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = isPromise
|
||||
10
home/ags/node_modules/eslint-plugin-promise/rules/lib/promise-statics.js
generated
vendored
10
home/ags/node_modules/eslint-plugin-promise/rules/lib/promise-statics.js
generated
vendored
|
|
@ -1,10 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
all: true,
|
||||
allSettled: true,
|
||||
any: true,
|
||||
race: true,
|
||||
reject: true,
|
||||
resolve: true,
|
||||
}
|
||||
71
home/ags/node_modules/eslint-plugin-promise/rules/no-callback-in-promise.js
generated
vendored
71
home/ags/node_modules/eslint-plugin-promise/rules/no-callback-in-promise.js
generated
vendored
|
|
@ -1,71 +0,0 @@
|
|||
/**
|
||||
* Rule: no-callback-in-promise
|
||||
* Avoid calling back inside of a promise
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
const { getAncestors } = require('./lib/eslint-compat')
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
const hasPromiseCallback = require('./lib/has-promise-callback')
|
||||
const isInsidePromise = require('./lib/is-inside-promise')
|
||||
const isCallback = require('./lib/is-callback')
|
||||
|
||||
const CB_BLACKLIST = ['callback', 'cb', 'next', 'done']
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description:
|
||||
'Disallow calling `cb()` inside of a `then()` (use [nodeify][] instead).',
|
||||
url: getDocsUrl('no-callback-in-promise'),
|
||||
},
|
||||
messages: {
|
||||
callback: 'Avoid calling back inside of a promise.',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
exceptions: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
CallExpression(node) {
|
||||
const options = context.options[0] || {}
|
||||
const exceptions = options.exceptions || []
|
||||
if (!isCallback(node, exceptions)) {
|
||||
// in general we send you packing if you're not a callback
|
||||
// but we also need to watch out for whatever.then(cb)
|
||||
if (hasPromiseCallback(node)) {
|
||||
const name =
|
||||
node.arguments && node.arguments[0] && node.arguments[0].name
|
||||
if (!exceptions.includes(name) && CB_BLACKLIST.includes(name)) {
|
||||
context.report({
|
||||
node: node.arguments[0],
|
||||
messageId: 'callback',
|
||||
})
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if (getAncestors(context, node).some(isInsidePromise)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'callback',
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
476
home/ags/node_modules/eslint-plugin-promise/rules/no-multiple-resolved.js
generated
vendored
476
home/ags/node_modules/eslint-plugin-promise/rules/no-multiple-resolved.js
generated
vendored
|
|
@ -1,476 +0,0 @@
|
|||
/**
|
||||
* Rule: no-multiple-resolved
|
||||
* Disallow creating new promises with paths that resolve multiple times
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
const { getScope } = require('./lib/eslint-compat')
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
const {
|
||||
isPromiseConstructorWithInlineExecutor,
|
||||
} = require('./lib/is-promise-constructor')
|
||||
|
||||
/**
|
||||
* @typedef {import('estree').Node} Node
|
||||
* @typedef {import('estree').Expression} Expression
|
||||
* @typedef {import('estree').Identifier} Identifier
|
||||
* @typedef {import('estree').FunctionExpression} FunctionExpression
|
||||
* @typedef {import('estree').ArrowFunctionExpression} ArrowFunctionExpression
|
||||
* @typedef {import('estree').SimpleCallExpression} CallExpression
|
||||
* @typedef {import('estree').MemberExpression} MemberExpression
|
||||
* @typedef {import('estree').NewExpression} NewExpression
|
||||
* @typedef {import('estree').ImportExpression} ImportExpression
|
||||
* @typedef {import('estree').YieldExpression} YieldExpression
|
||||
* @typedef {import('eslint').Rule.CodePath} CodePath
|
||||
* @typedef {import('eslint').Rule.CodePathSegment} CodePathSegment
|
||||
*/
|
||||
|
||||
/**
|
||||
* An expression that can throw an error.
|
||||
* see https://github.com/eslint/eslint/blob/e940be7a83d0caea15b64c1e1c2785a6540e2641/lib/linter/code-path-analysis/code-path-analyzer.js#L639-L643
|
||||
* @typedef {CallExpression | MemberExpression | NewExpression | ImportExpression | YieldExpression} ThrowableExpression
|
||||
*/
|
||||
|
||||
/**
|
||||
* Iterate all previous path segments.
|
||||
* @param {CodePathSegment} segment
|
||||
* @returns {Iterable<CodePathSegment[]>}
|
||||
*/
|
||||
function* iterateAllPrevPathSegments(segment) {
|
||||
yield* iterate(segment, [])
|
||||
|
||||
/**
|
||||
* @param {CodePathSegment} segment
|
||||
* @param {CodePathSegment[]} processed
|
||||
*/
|
||||
function* iterate(segment, processed) {
|
||||
if (processed.includes(segment)) {
|
||||
return
|
||||
}
|
||||
const nextProcessed = [segment, ...processed]
|
||||
|
||||
for (const prev of segment.prevSegments) {
|
||||
if (prev.prevSegments.length === 0) {
|
||||
yield [prev]
|
||||
} else {
|
||||
for (const segments of iterate(prev, nextProcessed)) {
|
||||
yield [prev, ...segments]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Iterate all next path segments.
|
||||
* @param {CodePathSegment} segment
|
||||
* @returns {Iterable<CodePathSegment[]>}
|
||||
*/
|
||||
function* iterateAllNextPathSegments(segment) {
|
||||
yield* iterate(segment, [])
|
||||
|
||||
/**
|
||||
* @param {CodePathSegment} segment
|
||||
* @param {CodePathSegment[]} processed
|
||||
*/
|
||||
function* iterate(segment, processed) {
|
||||
if (processed.includes(segment)) {
|
||||
return
|
||||
}
|
||||
const nextProcessed = [segment, ...processed]
|
||||
|
||||
for (const next of segment.nextSegments) {
|
||||
if (next.nextSegments.length === 0) {
|
||||
yield [next]
|
||||
} else {
|
||||
for (const segments of iterate(next, nextProcessed)) {
|
||||
yield [next, ...segments]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the same route path from the given path following previous path segments.
|
||||
* @param {CodePathSegment} segment
|
||||
* @returns {CodePathSegment | null}
|
||||
*/
|
||||
function findSameRoutePathSegment(segment) {
|
||||
/** @type {Set<CodePathSegment>} */
|
||||
const routeSegments = new Set()
|
||||
for (const route of iterateAllPrevPathSegments(segment)) {
|
||||
if (routeSegments.size === 0) {
|
||||
// First
|
||||
for (const seg of route) {
|
||||
routeSegments.add(seg)
|
||||
}
|
||||
continue
|
||||
}
|
||||
for (const seg of routeSegments) {
|
||||
if (!route.includes(seg)) {
|
||||
routeSegments.delete(seg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const routeSegment of routeSegments) {
|
||||
let hasUnreached = false
|
||||
for (const segments of iterateAllNextPathSegments(routeSegment)) {
|
||||
if (!segments.includes(segment)) {
|
||||
// It has a route that does not reach the given path.
|
||||
hasUnreached = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!hasUnreached) {
|
||||
return routeSegment
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
class CodePathInfo {
|
||||
/**
|
||||
* @param {CodePath} path
|
||||
*/
|
||||
constructor(path) {
|
||||
this.path = path
|
||||
/** @type {Map<CodePathSegment, CodePathSegmentInfo>} */
|
||||
this.segmentInfos = new Map()
|
||||
this.resolvedCount = 0
|
||||
/** @type {CodePathSegment[]} */
|
||||
this.allSegments = []
|
||||
}
|
||||
|
||||
getCurrentSegmentInfos() {
|
||||
return this.path.currentSegments.map((segment) => {
|
||||
const info = this.segmentInfos.get(segment)
|
||||
if (info) {
|
||||
return info
|
||||
}
|
||||
const newInfo = new CodePathSegmentInfo(this, segment)
|
||||
this.segmentInfos.set(segment, newInfo)
|
||||
return newInfo
|
||||
})
|
||||
}
|
||||
/**
|
||||
* @typedef {object} AlreadyResolvedData
|
||||
* @property {Identifier} resolved
|
||||
* @property {'certain' | 'potential'} kind
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check all paths and return paths resolved multiple times.
|
||||
* @param {PromiseCodePathContext} promiseCodePathContext
|
||||
* @returns {Iterable<AlreadyResolvedData & { node: Identifier }>}
|
||||
*/
|
||||
*iterateReports(promiseCodePathContext) {
|
||||
const targets = [...this.segmentInfos.values()].filter(
|
||||
(info) => info.resolved
|
||||
)
|
||||
for (const segmentInfo of targets) {
|
||||
const result = this._getAlreadyResolvedData(
|
||||
segmentInfo.segment,
|
||||
promiseCodePathContext
|
||||
)
|
||||
if (result) {
|
||||
yield {
|
||||
node: segmentInfo.resolved,
|
||||
resolved: result.resolved,
|
||||
kind: result.kind,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Compute the previously resolved path.
|
||||
* @param {CodePathSegment} segment
|
||||
* @param {PromiseCodePathContext} promiseCodePathContext
|
||||
* @returns {AlreadyResolvedData | null}
|
||||
*/
|
||||
_getAlreadyResolvedData(segment, promiseCodePathContext) {
|
||||
const prevSegments = segment.prevSegments.filter(
|
||||
(prev) => !promiseCodePathContext.isResolvedTryBlockCodePathSegment(prev)
|
||||
)
|
||||
if (prevSegments.length === 0) {
|
||||
return null
|
||||
}
|
||||
const prevSegmentInfos = prevSegments.map((prev) =>
|
||||
this._getProcessedSegmentInfo(prev, promiseCodePathContext)
|
||||
)
|
||||
if (prevSegmentInfos.every((info) => info.resolved)) {
|
||||
// If the previous paths are all resolved, the next path is also resolved.
|
||||
return {
|
||||
resolved: prevSegmentInfos[0].resolved,
|
||||
kind: 'certain',
|
||||
}
|
||||
}
|
||||
|
||||
for (const prevSegmentInfo of prevSegmentInfos) {
|
||||
if (prevSegmentInfo.resolved) {
|
||||
// If the previous path is partially resolved,
|
||||
// then the next path is potentially resolved.
|
||||
return {
|
||||
resolved: prevSegmentInfo.resolved,
|
||||
kind: 'potential',
|
||||
}
|
||||
}
|
||||
if (prevSegmentInfo.potentiallyResolved) {
|
||||
let potential = false
|
||||
if (prevSegmentInfo.segment.nextSegments.length === 1) {
|
||||
// If the previous path is potentially resolved and there is one next path,
|
||||
// then the next path is potentially resolved.
|
||||
potential = true
|
||||
} else {
|
||||
// This is necessary, for example, if `resolve()` in the finally section.
|
||||
const segmentInfo = this.segmentInfos.get(segment)
|
||||
if (segmentInfo && segmentInfo.resolved) {
|
||||
if (
|
||||
prevSegmentInfo.segment.nextSegments.every((next) => {
|
||||
const nextSegmentInfo = this.segmentInfos.get(next)
|
||||
return (
|
||||
nextSegmentInfo &&
|
||||
nextSegmentInfo.resolved === segmentInfo.resolved
|
||||
)
|
||||
})
|
||||
) {
|
||||
// If the previous path is potentially resolved and
|
||||
// the next paths all point to the same resolved node,
|
||||
// then the next path is potentially resolved.
|
||||
potential = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (potential) {
|
||||
return {
|
||||
resolved: prevSegmentInfo.potentiallyResolved,
|
||||
kind: 'potential',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sameRoute = findSameRoutePathSegment(segment)
|
||||
if (sameRoute) {
|
||||
const sameRouteSegmentInfo = this._getProcessedSegmentInfo(sameRoute)
|
||||
if (sameRouteSegmentInfo.potentiallyResolved) {
|
||||
return {
|
||||
resolved: sameRouteSegmentInfo.potentiallyResolved,
|
||||
kind: 'potential',
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
/**
|
||||
* @param {CodePathSegment} segment
|
||||
* @param {PromiseCodePathContext} promiseCodePathContext
|
||||
*/
|
||||
_getProcessedSegmentInfo(segment, promiseCodePathContext) {
|
||||
const segmentInfo = this.segmentInfos.get(segment)
|
||||
if (segmentInfo) {
|
||||
return segmentInfo
|
||||
}
|
||||
const newInfo = new CodePathSegmentInfo(this, segment)
|
||||
this.segmentInfos.set(segment, newInfo)
|
||||
|
||||
const alreadyResolvedData = this._getAlreadyResolvedData(
|
||||
segment,
|
||||
promiseCodePathContext
|
||||
)
|
||||
if (alreadyResolvedData) {
|
||||
if (alreadyResolvedData.kind === 'certain') {
|
||||
newInfo.resolved = alreadyResolvedData.resolved
|
||||
} else {
|
||||
newInfo.potentiallyResolved = alreadyResolvedData.resolved
|
||||
}
|
||||
}
|
||||
return newInfo
|
||||
}
|
||||
}
|
||||
|
||||
class CodePathSegmentInfo {
|
||||
/**
|
||||
* @param {CodePathInfo} pathInfo
|
||||
* @param {CodePathSegment} segment
|
||||
*/
|
||||
constructor(pathInfo, segment) {
|
||||
this.pathInfo = pathInfo
|
||||
this.segment = segment
|
||||
/** @type {Identifier | null} */
|
||||
this._resolved = null
|
||||
/** @type {Identifier | null} */
|
||||
this.potentiallyResolved = null
|
||||
}
|
||||
|
||||
get resolved() {
|
||||
return this._resolved
|
||||
}
|
||||
/** @type {Identifier} */
|
||||
set resolved(identifier) {
|
||||
this._resolved = identifier
|
||||
this.pathInfo.resolvedCount++
|
||||
}
|
||||
}
|
||||
|
||||
class PromiseCodePathContext {
|
||||
constructor() {
|
||||
/** @type {Set<string>} */
|
||||
this.resolvedSegmentIds = new Set()
|
||||
}
|
||||
/** @param {CodePathSegment} */
|
||||
addResolvedTryBlockCodePathSegment(segment) {
|
||||
this.resolvedSegmentIds.add(segment.id)
|
||||
}
|
||||
/** @param {CodePathSegment} */
|
||||
isResolvedTryBlockCodePathSegment(segment) {
|
||||
return this.resolvedSegmentIds.has(segment.id)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'Disallow creating new promises with paths that resolve multiple times.',
|
||||
url: getDocsUrl('no-multiple-resolved'),
|
||||
},
|
||||
messages: {
|
||||
alreadyResolved:
|
||||
'Promise should not be resolved multiple times. Promise is already resolved on line {{line}}.',
|
||||
potentiallyAlreadyResolved:
|
||||
'Promise should not be resolved multiple times. Promise is potentially resolved on line {{line}}.',
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
/** @param {import('eslint').Rule.RuleContext} context */
|
||||
create(context) {
|
||||
const reported = new Set()
|
||||
const promiseCodePathContext = new PromiseCodePathContext()
|
||||
/**
|
||||
* @param {Identifier} node
|
||||
* @param {Identifier} resolved
|
||||
* @param {'certain' | 'potential'} kind
|
||||
*/
|
||||
function report(node, resolved, kind) {
|
||||
if (reported.has(node)) {
|
||||
return
|
||||
}
|
||||
reported.add(node)
|
||||
context.report({
|
||||
node: node.parent,
|
||||
messageId:
|
||||
kind === 'certain' ? 'alreadyResolved' : 'potentiallyAlreadyResolved',
|
||||
data: {
|
||||
line: resolved.loc.start.line,
|
||||
},
|
||||
})
|
||||
}
|
||||
/**
|
||||
* @param {CodePathInfo} codePathInfo
|
||||
* @param {PromiseCodePathContext} promiseCodePathContext
|
||||
*/
|
||||
function verifyMultipleResolvedPath(codePathInfo, promiseCodePathContext) {
|
||||
for (const { node, resolved, kind } of codePathInfo.iterateReports(
|
||||
promiseCodePathContext
|
||||
)) {
|
||||
report(node, resolved, kind)
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {CodePathInfo[]} */
|
||||
const codePathInfoStack = []
|
||||
/** @type {Set<Identifier>[]} */
|
||||
const resolverReferencesStack = [new Set()]
|
||||
/** @type {ThrowableExpression | null} */
|
||||
let lastThrowableExpression = null
|
||||
return {
|
||||
/** @param {FunctionExpression | ArrowFunctionExpression} node */
|
||||
'FunctionExpression, ArrowFunctionExpression'(node) {
|
||||
if (!isPromiseConstructorWithInlineExecutor(node.parent)) {
|
||||
return
|
||||
}
|
||||
// Collect and stack `resolve` and `reject` references.
|
||||
/** @type {Set<Identifier>} */
|
||||
const resolverReferences = new Set()
|
||||
const resolvers = node.params.filter(
|
||||
/** @returns {node is Identifier} */
|
||||
(node) => node && node.type === 'Identifier'
|
||||
)
|
||||
for (const resolver of resolvers) {
|
||||
const variable = getScope(context, node).set.get(resolver.name)
|
||||
// istanbul ignore next -- Usually always present.
|
||||
if (!variable) continue
|
||||
for (const reference of variable.references) {
|
||||
resolverReferences.add(reference.identifier)
|
||||
}
|
||||
}
|
||||
|
||||
resolverReferencesStack.unshift(resolverReferences)
|
||||
},
|
||||
/** @param {FunctionExpression | ArrowFunctionExpression} node */
|
||||
'FunctionExpression, ArrowFunctionExpression:exit'(node) {
|
||||
if (!isPromiseConstructorWithInlineExecutor(node.parent)) {
|
||||
return
|
||||
}
|
||||
resolverReferencesStack.shift()
|
||||
},
|
||||
/** @param {CodePath} path */
|
||||
onCodePathStart(path) {
|
||||
codePathInfoStack.unshift(new CodePathInfo(path))
|
||||
},
|
||||
onCodePathEnd() {
|
||||
const codePathInfo = codePathInfoStack.shift()
|
||||
if (codePathInfo.resolvedCount > 1) {
|
||||
verifyMultipleResolvedPath(codePathInfo, promiseCodePathContext)
|
||||
}
|
||||
},
|
||||
/** @param {ThrowableExpression} node */
|
||||
'CallExpression, MemberExpression, NewExpression, ImportExpression, YieldExpression:exit'(
|
||||
node
|
||||
) {
|
||||
lastThrowableExpression = node
|
||||
},
|
||||
/**
|
||||
* @param {CodePathSegment} segment
|
||||
* @param {Node} node
|
||||
*/
|
||||
onCodePathSegmentEnd(segment, node) {
|
||||
if (
|
||||
node.type === 'CatchClause' &&
|
||||
lastThrowableExpression &&
|
||||
lastThrowableExpression.type === 'CallExpression' &&
|
||||
node.parent.type === 'TryStatement' &&
|
||||
node.parent.range[0] <= lastThrowableExpression.range[0] &&
|
||||
lastThrowableExpression.range[1] <= node.parent.range[1]
|
||||
) {
|
||||
const resolverReferences = resolverReferencesStack[0]
|
||||
if (resolverReferences.has(lastThrowableExpression.callee)) {
|
||||
// Mark a segment if the last expression in the try block is a call to resolve.
|
||||
promiseCodePathContext.addResolvedTryBlockCodePathSegment(segment)
|
||||
}
|
||||
}
|
||||
},
|
||||
/** @type {Identifier} */
|
||||
'CallExpression > Identifier.callee'(node) {
|
||||
const codePathInfo = codePathInfoStack[0]
|
||||
const resolverReferences = resolverReferencesStack[0]
|
||||
if (!resolverReferences.has(node)) {
|
||||
return
|
||||
}
|
||||
for (const segmentInfo of codePathInfo.getCurrentSegmentInfos()) {
|
||||
// If a resolving path is found, report if the path is already resolved.
|
||||
// Store the information if it is not already resolved.
|
||||
if (segmentInfo.resolved) {
|
||||
report(node, segmentInfo.resolved, 'certain')
|
||||
continue
|
||||
}
|
||||
segmentInfo.resolved = node
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
77
home/ags/node_modules/eslint-plugin-promise/rules/no-native.js
generated
vendored
77
home/ags/node_modules/eslint-plugin-promise/rules/no-native.js
generated
vendored
|
|
@ -1,77 +0,0 @@
|
|||
// Borrowed from here:
|
||||
// https://github.com/colonyamerican/eslint-plugin-cah/issues/3
|
||||
|
||||
'use strict'
|
||||
|
||||
const { getScope } = require('./lib/eslint-compat')
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
|
||||
function isDeclared(scope, ref) {
|
||||
return scope.variables.some((variable) => {
|
||||
if (variable.name !== ref.identifier.name) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Presumably can't pass this since the implicit `Promise` global
|
||||
// being checked here would always lack `defs`
|
||||
// istanbul ignore else
|
||||
if (!variable.defs || !variable.defs.length) {
|
||||
return false
|
||||
}
|
||||
|
||||
// istanbul ignore next
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description:
|
||||
'Require creating a `Promise` constructor before using it in an ES5 environment.',
|
||||
url: getDocsUrl('no-native'),
|
||||
},
|
||||
messages: {
|
||||
name: '"{{name}}" is not defined.',
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
/**
|
||||
* Checks for and reports reassigned constants
|
||||
*
|
||||
* @param {Scope} scope - an eslint-scope Scope object
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
return {
|
||||
'Program:exit'(node) {
|
||||
const scope = getScope(context, node)
|
||||
const leftToBeResolved =
|
||||
scope.implicit.left ||
|
||||
/**
|
||||
* Fixes https://github.com/eslint-community/eslint-plugin-promise/issues/205.
|
||||
* The problem was that @typescript-eslint has a scope manager
|
||||
* which has `leftToBeResolved` instead of the default `left`.
|
||||
*/
|
||||
scope.implicit.leftToBeResolved
|
||||
|
||||
leftToBeResolved.forEach((ref) => {
|
||||
if (ref.identifier.name !== 'Promise') {
|
||||
return
|
||||
}
|
||||
|
||||
// istanbul ignore else
|
||||
if (!isDeclared(scope, ref)) {
|
||||
context.report({
|
||||
node: ref.identifier,
|
||||
messageId: 'name',
|
||||
data: { name: ref.identifier.name },
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
120
home/ags/node_modules/eslint-plugin-promise/rules/no-nesting.js
generated
vendored
120
home/ags/node_modules/eslint-plugin-promise/rules/no-nesting.js
generated
vendored
|
|
@ -1,120 +0,0 @@
|
|||
/**
|
||||
* Rule: no-nesting
|
||||
* Avoid nesting your promises.
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
const { getScope } = require('./lib/eslint-compat')
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
const hasPromiseCallback = require('./lib/has-promise-callback')
|
||||
const isInsidePromise = require('./lib/is-inside-promise')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'Disallow nested `then()` or `catch()` statements.',
|
||||
url: getDocsUrl('no-nesting'),
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
/**
|
||||
* Array of callback function scopes.
|
||||
* Scopes are in order closest to the current node.
|
||||
* @type {import('eslint').Scope.Scope[]}
|
||||
*/
|
||||
const callbackScopes = []
|
||||
|
||||
/**
|
||||
* @param {import('eslint').Scope.Scope} scope
|
||||
* @returns {Iterable<import('eslint').Scope.Reference>}
|
||||
*/
|
||||
function* iterateDefinedReferences(scope) {
|
||||
for (const variable of scope.variables) {
|
||||
for (const reference of variable.references) {
|
||||
yield reference
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
':function'(node) {
|
||||
if (isInsidePromise(node)) {
|
||||
callbackScopes.unshift(getScope(context, node))
|
||||
}
|
||||
},
|
||||
':function:exit'(node) {
|
||||
if (isInsidePromise(node)) {
|
||||
callbackScopes.shift()
|
||||
}
|
||||
},
|
||||
CallExpression(node) {
|
||||
if (!hasPromiseCallback(node)) return
|
||||
if (!callbackScopes.length) {
|
||||
// The node is not in the callback function.
|
||||
return
|
||||
}
|
||||
|
||||
// Checks if the argument callback uses variables defined in the closest callback function scope.
|
||||
//
|
||||
// e.g.
|
||||
// ```
|
||||
// doThing()
|
||||
// .then(a => getB(a)
|
||||
// .then(b => getC(a, b))
|
||||
// )
|
||||
// ```
|
||||
//
|
||||
// In the above case, Since the variables it references are undef,
|
||||
// we cannot refactor the nesting like following:
|
||||
// ```
|
||||
// doThing()
|
||||
// .then(a => getB(a))
|
||||
// .then(b => getC(a, b))
|
||||
// ```
|
||||
//
|
||||
// However, `getD` can be refactored in the following:
|
||||
// ```
|
||||
// doThing()
|
||||
// .then(a => getB(a)
|
||||
// .then(b => getC(a, b)
|
||||
// .then(c => getD(a, c))
|
||||
// )
|
||||
// )
|
||||
// ```
|
||||
// ↓
|
||||
// ```
|
||||
// doThing()
|
||||
// .then(a => getB(a)
|
||||
// .then(b => getC(a, b))
|
||||
// .then(c => getD(a, c))
|
||||
// )
|
||||
// ```
|
||||
// This is why we only check the closest callback function scope.
|
||||
//
|
||||
const closestCallbackScope = callbackScopes[0]
|
||||
for (const reference of iterateDefinedReferences(
|
||||
closestCallbackScope
|
||||
)) {
|
||||
if (
|
||||
node.arguments.some(
|
||||
(arg) =>
|
||||
arg.range[0] <= reference.identifier.range[0] &&
|
||||
reference.identifier.range[1] <= arg.range[1]
|
||||
)
|
||||
) {
|
||||
// Argument callbacks refer to variables defined in the callback function.
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
context.report({
|
||||
node: node.callee.property,
|
||||
message: 'Avoid nesting promises.',
|
||||
})
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
39
home/ags/node_modules/eslint-plugin-promise/rules/no-new-statics.js
generated
vendored
39
home/ags/node_modules/eslint-plugin-promise/rules/no-new-statics.js
generated
vendored
|
|
@ -1,39 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const PROMISE_STATICS = require('./lib/promise-statics')
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Disallow calling `new` on a Promise static method.',
|
||||
url: getDocsUrl('no-new-statics'),
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
NewExpression(node) {
|
||||
if (
|
||||
node.callee.type === 'MemberExpression' &&
|
||||
node.callee.object.name === 'Promise' &&
|
||||
PROMISE_STATICS[node.callee.property.name]
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
message: "Avoid calling 'new' on 'Promise.{{ name }}()'",
|
||||
data: { name: node.callee.property.name },
|
||||
fix(fixer) {
|
||||
return fixer.replaceTextRange(
|
||||
[node.range[0], node.range[0] + 'new '.length],
|
||||
''
|
||||
)
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
43
home/ags/node_modules/eslint-plugin-promise/rules/no-promise-in-callback.js
generated
vendored
43
home/ags/node_modules/eslint-plugin-promise/rules/no-promise-in-callback.js
generated
vendored
|
|
@ -1,43 +0,0 @@
|
|||
/**
|
||||
* Rule: no-promise-in-callback
|
||||
* Discourage using promises inside of callbacks.
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
const { getAncestors } = require('./lib/eslint-compat')
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
const isPromise = require('./lib/is-promise')
|
||||
const isInsideCallback = require('./lib/is-inside-callback')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'Disallow using promises inside of callbacks.',
|
||||
url: getDocsUrl('no-promise-in-callback'),
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
CallExpression(node) {
|
||||
if (!isPromise(node)) return
|
||||
|
||||
// if i'm returning the promise, it's probably not really a callback
|
||||
// function, and I should be okay....
|
||||
if (node.parent.type === 'ReturnStatement') return
|
||||
|
||||
// what about if the parent is an ArrowFunctionExpression
|
||||
// would that imply an implicit return?
|
||||
|
||||
if (getAncestors(context, node).some(isInsideCallback)) {
|
||||
context.report({
|
||||
node: node.callee,
|
||||
message: 'Avoid using promises inside of callbacks.',
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
47
home/ags/node_modules/eslint-plugin-promise/rules/no-return-in-finally.js
generated
vendored
47
home/ags/node_modules/eslint-plugin-promise/rules/no-return-in-finally.js
generated
vendored
|
|
@ -1,47 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
const isPromise = require('./lib/is-promise')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Disallow return statements in `finally()`.',
|
||||
url: getDocsUrl('no-return-in-finally'),
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
CallExpression(node) {
|
||||
if (isPromise(node)) {
|
||||
if (
|
||||
node.callee &&
|
||||
node.callee.property &&
|
||||
node.callee.property.name === 'finally'
|
||||
) {
|
||||
// istanbul ignore else -- passing `isPromise` means should have a body
|
||||
if (
|
||||
node.arguments &&
|
||||
node.arguments[0] &&
|
||||
node.arguments[0].body &&
|
||||
node.arguments[0].body.body
|
||||
) {
|
||||
if (
|
||||
node.arguments[0].body.body.some((statement) => {
|
||||
return statement.type === 'ReturnStatement'
|
||||
})
|
||||
) {
|
||||
context.report({
|
||||
node: node.callee.property,
|
||||
message: 'No return in finally',
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
96
home/ags/node_modules/eslint-plugin-promise/rules/no-return-wrap.js
generated
vendored
96
home/ags/node_modules/eslint-plugin-promise/rules/no-return-wrap.js
generated
vendored
|
|
@ -1,96 +0,0 @@
|
|||
/**
|
||||
* Rule: no-return-wrap function
|
||||
* Prevents unnecessary wrapping of results in Promise.resolve
|
||||
* or Promise.reject as the Promise will do that for us
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
const { getAncestors } = require('./lib/eslint-compat')
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
const isPromise = require('./lib/is-promise')
|
||||
|
||||
function isInPromise(context, node) {
|
||||
let functionNode = getAncestors(context, node)
|
||||
.filter((node) => {
|
||||
return (
|
||||
node.type === 'ArrowFunctionExpression' ||
|
||||
node.type === 'FunctionExpression'
|
||||
)
|
||||
})
|
||||
.reverse()[0]
|
||||
while (
|
||||
functionNode &&
|
||||
functionNode.parent &&
|
||||
functionNode.parent.type === 'MemberExpression' &&
|
||||
functionNode.parent.object === functionNode &&
|
||||
functionNode.parent.property.type === 'Identifier' &&
|
||||
functionNode.parent.property.name === 'bind' &&
|
||||
functionNode.parent.parent &&
|
||||
functionNode.parent.parent.type === 'CallExpression' &&
|
||||
functionNode.parent.parent.callee === functionNode.parent
|
||||
) {
|
||||
functionNode = functionNode.parent.parent
|
||||
}
|
||||
return functionNode && functionNode.parent && isPromise(functionNode.parent)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description:
|
||||
'Disallow wrapping values in `Promise.resolve` or `Promise.reject` when not needed.',
|
||||
url: getDocsUrl('no-return-wrap'),
|
||||
},
|
||||
messages: {
|
||||
resolve: 'Avoid wrapping return values in Promise.resolve',
|
||||
reject: 'Expected throw instead of Promise.reject',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
allowReject: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
create(context) {
|
||||
const options = context.options[0] || {}
|
||||
const allowReject = options.allowReject
|
||||
|
||||
/**
|
||||
* Checks a call expression, reporting if necessary.
|
||||
* @param callExpression The call expression.
|
||||
* @param node The node to report.
|
||||
*/
|
||||
function checkCallExpression({ callee }, node) {
|
||||
if (
|
||||
isInPromise(context, node) &&
|
||||
callee.type === 'MemberExpression' &&
|
||||
callee.object.name === 'Promise'
|
||||
) {
|
||||
if (callee.property.name === 'resolve') {
|
||||
context.report({ node, messageId: 'resolve' })
|
||||
} else if (!allowReject && callee.property.name === 'reject') {
|
||||
context.report({ node, messageId: 'reject' })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
ReturnStatement(node) {
|
||||
if (node.argument && node.argument.type === 'CallExpression') {
|
||||
checkCallExpression(node.argument, node)
|
||||
}
|
||||
},
|
||||
'ArrowFunctionExpression > CallExpression'(node) {
|
||||
checkCallExpression(node, node)
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
70
home/ags/node_modules/eslint-plugin-promise/rules/param-names.js
generated
vendored
70
home/ags/node_modules/eslint-plugin-promise/rules/param-names.js
generated
vendored
|
|
@ -1,70 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
const {
|
||||
isPromiseConstructorWithInlineExecutor,
|
||||
} = require('./lib/is-promise-constructor')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description:
|
||||
'Enforce consistent param names and ordering when creating new promises.',
|
||||
url: getDocsUrl('param-names'),
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
resolvePattern: { type: 'string' },
|
||||
rejectPattern: { type: 'string' },
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
create(context) {
|
||||
const options = context.options[0] || {}
|
||||
const resolvePattern = new RegExp(
|
||||
options.resolvePattern || '^_?resolve$',
|
||||
'u'
|
||||
)
|
||||
const rejectPattern = new RegExp(options.rejectPattern || '^_?reject$', 'u')
|
||||
|
||||
return {
|
||||
NewExpression(node) {
|
||||
if (isPromiseConstructorWithInlineExecutor(node)) {
|
||||
const params = node.arguments[0].params
|
||||
|
||||
if (!params || !params.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const resolveParamName = params[0] && params[0].name
|
||||
if (resolveParamName && !resolvePattern.test(resolveParamName)) {
|
||||
context.report({
|
||||
node: params[0],
|
||||
message:
|
||||
'Promise constructor parameters must be named to match "{{ resolvePattern }}"',
|
||||
data: {
|
||||
resolvePattern: resolvePattern.source,
|
||||
},
|
||||
})
|
||||
}
|
||||
const rejectParamName = params[1] && params[1].name
|
||||
if (rejectParamName && !rejectPattern.test(rejectParamName)) {
|
||||
context.report({
|
||||
node: params[1],
|
||||
message:
|
||||
'Promise constructor parameters must be named to match "{{ rejectPattern }}"',
|
||||
data: {
|
||||
rejectPattern: rejectPattern.source,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
97
home/ags/node_modules/eslint-plugin-promise/rules/prefer-await-to-callbacks.js
generated
vendored
97
home/ags/node_modules/eslint-plugin-promise/rules/prefer-await-to-callbacks.js
generated
vendored
|
|
@ -1,97 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const { getAncestors } = require('./lib/eslint-compat')
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'Prefer async/await to the callback pattern.',
|
||||
url: getDocsUrl('prefer-await-to-callbacks'),
|
||||
},
|
||||
messages: {
|
||||
error: 'Avoid callbacks. Prefer Async/Await.',
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
function checkLastParamsForCallback(node) {
|
||||
const lastParam = node.params[node.params.length - 1] || {}
|
||||
if (lastParam.name === 'callback' || lastParam.name === 'cb') {
|
||||
context.report({ node: lastParam, messageId: 'error' })
|
||||
}
|
||||
}
|
||||
function isInsideYieldOrAwait(node) {
|
||||
return getAncestors(context, node).some((parent) => {
|
||||
return (
|
||||
parent.type === 'AwaitExpression' || parent.type === 'YieldExpression'
|
||||
)
|
||||
})
|
||||
}
|
||||
return {
|
||||
CallExpression(node) {
|
||||
// Callbacks aren't allowed.
|
||||
if (node.callee.name === 'cb' || node.callee.name === 'callback') {
|
||||
context.report({ node, messageId: 'error' })
|
||||
return
|
||||
}
|
||||
|
||||
// Then-ables aren't allowed either.
|
||||
const args = node.arguments
|
||||
const lastArgIndex = args.length - 1
|
||||
const arg = lastArgIndex > -1 && node.arguments[lastArgIndex]
|
||||
if (
|
||||
(arg && arg.type === 'FunctionExpression') ||
|
||||
arg.type === 'ArrowFunctionExpression'
|
||||
) {
|
||||
// Ignore event listener callbacks.
|
||||
if (
|
||||
node.callee.property &&
|
||||
(node.callee.property.name === 'on' ||
|
||||
node.callee.property.name === 'once')
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
// carve out exemption for map/filter/etc
|
||||
const arrayMethods = [
|
||||
'map',
|
||||
'every',
|
||||
'forEach',
|
||||
'some',
|
||||
'find',
|
||||
'filter',
|
||||
]
|
||||
const isLodash =
|
||||
node.callee.object &&
|
||||
['lodash', 'underscore', '_'].includes(node.callee.object.name)
|
||||
const callsArrayMethod =
|
||||
node.callee.property &&
|
||||
arrayMethods.includes(node.callee.property.name) &&
|
||||
(node.arguments.length === 1 ||
|
||||
(node.arguments.length === 2 && isLodash))
|
||||
const isArrayMethod =
|
||||
node.callee.name &&
|
||||
arrayMethods.includes(node.callee.name) &&
|
||||
node.arguments.length === 2
|
||||
if (callsArrayMethod || isArrayMethod) return
|
||||
|
||||
// actually check for callbacks (I know this is the worst)
|
||||
if (
|
||||
arg.params &&
|
||||
arg.params[0] &&
|
||||
(arg.params[0].name === 'err' || arg.params[0].name === 'error')
|
||||
) {
|
||||
if (!isInsideYieldOrAwait(node)) {
|
||||
context.report({ node: arg, messageId: 'error' })
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
FunctionDeclaration: checkLastParamsForCallback,
|
||||
FunctionExpression: checkLastParamsForCallback,
|
||||
ArrowFunctionExpression: checkLastParamsForCallback,
|
||||
}
|
||||
},
|
||||
}
|
||||
61
home/ags/node_modules/eslint-plugin-promise/rules/prefer-await-to-then.js
generated
vendored
61
home/ags/node_modules/eslint-plugin-promise/rules/prefer-await-to-then.js
generated
vendored
|
|
@ -1,61 +0,0 @@
|
|||
/**
|
||||
* Rule: prefer-await-to-then
|
||||
* Discourage using then()/catch()/finally() and instead use async/await.
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
const { getAncestors, getScope } = require('./lib/eslint-compat')
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description:
|
||||
'Prefer `await` to `then()`/`catch()`/`finally()` for reading Promise values.',
|
||||
url: getDocsUrl('prefer-await-to-then'),
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
/** Returns true if node is inside yield or await expression. */
|
||||
function isInsideYieldOrAwait(node) {
|
||||
return getAncestors(context, node).some((parent) => {
|
||||
return (
|
||||
parent.type === 'AwaitExpression' || parent.type === 'YieldExpression'
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if node is created at the top-level scope.
|
||||
* Await statements are not allowed at the top level,
|
||||
* only within function declarations.
|
||||
*/
|
||||
function isTopLevelScoped(node) {
|
||||
return getScope(context, node).block.type === 'Program'
|
||||
}
|
||||
|
||||
return {
|
||||
'CallExpression > MemberExpression.callee'(node) {
|
||||
if (isTopLevelScoped(node) || isInsideYieldOrAwait(node)) {
|
||||
return
|
||||
}
|
||||
|
||||
// if you're a then/catch/finally expression then you're probably a promise
|
||||
if (
|
||||
node.property &&
|
||||
(node.property.name === 'then' ||
|
||||
node.property.name === 'catch' ||
|
||||
node.property.name === 'finally')
|
||||
) {
|
||||
context.report({
|
||||
node: node.property,
|
||||
message: 'Prefer await to then()/catch()/finally().',
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
71
home/ags/node_modules/eslint-plugin-promise/rules/valid-params.js
generated
vendored
71
home/ags/node_modules/eslint-plugin-promise/rules/valid-params.js
generated
vendored
|
|
@ -1,71 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const getDocsUrl = require('./lib/get-docs-url')
|
||||
const isPromise = require('./lib/is-promise')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'Enforces the proper number of arguments are passed to Promise functions.',
|
||||
url: getDocsUrl('valid-params'),
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
CallExpression(node) {
|
||||
if (!isPromise(node)) {
|
||||
return
|
||||
}
|
||||
|
||||
const name = node.callee.property.name
|
||||
const numArgs = node.arguments.length
|
||||
|
||||
// istanbul ignore next -- `isPromise` filters out others
|
||||
switch (name) {
|
||||
case 'resolve':
|
||||
case 'reject':
|
||||
if (numArgs > 1) {
|
||||
context.report({
|
||||
node,
|
||||
message:
|
||||
'Promise.{{ name }}() requires 0 or 1 arguments, but received {{ numArgs }}',
|
||||
data: { name, numArgs },
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'then':
|
||||
if (numArgs < 1 || numArgs > 2) {
|
||||
context.report({
|
||||
node,
|
||||
message:
|
||||
'Promise.{{ name }}() requires 1 or 2 arguments, but received {{ numArgs }}',
|
||||
data: { name, numArgs },
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'race':
|
||||
case 'all':
|
||||
case 'allSettled':
|
||||
case 'any':
|
||||
case 'catch':
|
||||
case 'finally':
|
||||
if (numArgs !== 1) {
|
||||
context.report({
|
||||
node,
|
||||
message:
|
||||
'Promise.{{ name }}() requires 1 argument, but received {{ numArgs }}',
|
||||
data: { name, numArgs },
|
||||
})
|
||||
}
|
||||
break
|
||||
default:
|
||||
// istanbul ignore next -- `isPromise` filters out others
|
||||
break
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue