-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Based on improvements in WordPress/gutenberg#27301
- Loading branch information
Showing
8 changed files
with
195 additions
and
190 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
packages/eslint-plugin-wpcalypso/docs/rules/no-unsafe-wp-apis.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<!-- eslint-disable wpcalypso/no-unsafe-wp-apis --> | ||
|
||
# Prevent unsafe API usage (no-unsafe-wp-apis) | ||
|
||
Prevent unsafe APIs from `@wordpress/*` packages from being imported. | ||
|
||
This includes experimental and unstable APIs which are expected to change and likely to cause issues in application code. | ||
See the [documentation](https://github.com/WordPress/gutenberg/blob/master/docs/contributors/coding-guidelines.md#experimental-and-unstable-apis). | ||
|
||
> **There is no support commitment for experimental and unstable APIs.** They can and will be removed or changed without advance warning, including as part of a minor or patch release. As an external consumer, you should avoid these APIs. | ||
> … | ||
> | ||
> - An **experimental API** is one which is planned for eventual public availability, but is subject to further experimentation, testing, and discussion. | ||
> - An **unstable API** is one which serves as a means to an end. It is not desired to ever be converted into a public API. | ||
## Rule details | ||
|
||
Examples of **incorrect** code for this rule: | ||
|
||
```js | ||
import { __experimentalFeature } from '@wordpress/foo'; | ||
import { __unstableFeature } from '@wordpress/bar'; | ||
``` | ||
|
||
Examples of **correct** code for this rule: | ||
|
||
```js | ||
import { registerBlockType } from '@wordpress/blocks'; | ||
``` | ||
|
||
## Options | ||
|
||
The rule can be configured via an object. | ||
This should be an object where the keys are import package names and the values are arrays of allowed unsafe imports. | ||
|
||
#### Example configuration | ||
|
||
```json | ||
{ | ||
"wpcalypso/no-unsafe-wp-apis": [ | ||
"error", | ||
{ "@wordpress/block-editor": [ "__experimentalBlock" ] } | ||
] | ||
} | ||
``` |
48 changes: 0 additions & 48 deletions
48
packages/eslint-plugin-wpcalypso/docs/rules/wp-no-unsafe-features.md
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
packages/eslint-plugin-wpcalypso/lib/rules/no-unsafe-wp-apis.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/** @type {import('eslint').Rule.RuleModule} */ | ||
module.exports = { | ||
type: 'problem', | ||
meta: { | ||
messages: { | ||
noUnsafeFeatures: 'Usage of `{{importedName}}` from `{{sourceModule}}` is not allowed', | ||
}, | ||
schema: [ | ||
{ | ||
type: 'object', | ||
additionalProperties: false, | ||
patternProperties: { | ||
'^@wordpress\\/[a-zA-Z0-9_-]+$': { | ||
type: 'array', | ||
uniqueItems: true, | ||
minItems: 1, | ||
items: { | ||
type: 'string', | ||
pattern: '^(?:__experimental|__unstable)', | ||
}, | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
create( context ) { | ||
/** @type {AllowedImportsMap} */ | ||
const allowedImports = | ||
( context.options && typeof context.options[ 0 ] === 'object' && context.options[ 0 ] ) || {}; | ||
const reporter = makeListener( { allowedImports, context } ); | ||
|
||
return { ImportDeclaration: reporter }; | ||
}, | ||
}; | ||
|
||
/** | ||
* @param {Object} _ options | ||
* @param {AllowedImportsMap} _.allowedImports Allowed imports | ||
* @param {import('eslint').Rule.RuleContext} _.context Context | ||
* | ||
* @returns {(node: Node) => void} Listener function | ||
*/ | ||
function makeListener( { allowedImports, context } ) { | ||
return function reporter( node ) { | ||
if ( node.type !== 'ImportDeclaration' ) { | ||
return; | ||
} | ||
if ( typeof node.source.value !== 'string' ) { | ||
return; | ||
} | ||
|
||
const sourceModule = node.source.value.trim(); | ||
|
||
// Ignore non-WordPress packages | ||
if ( ! sourceModule.startsWith( '@wordpress/' ) ) { | ||
return; | ||
} | ||
|
||
const allowedImportNames = allowedImports[ sourceModule ] || []; | ||
|
||
node.specifiers.forEach( ( specifierNode ) => { | ||
if ( specifierNode.type !== 'ImportSpecifier' ) { | ||
return; | ||
} | ||
|
||
const importedName = specifierNode.imported.name; | ||
|
||
if ( | ||
! importedName.startsWith( '__unstable' ) && | ||
! importedName.startsWith( '__experimental' ) | ||
) { | ||
return; | ||
} | ||
|
||
if ( allowedImportNames.includes( importedName ) ) { | ||
return; | ||
} | ||
|
||
context.report( { | ||
messageId: 'noUnsafeFeatures', | ||
node: specifierNode, | ||
data: { | ||
sourceModule, | ||
importedName, | ||
}, | ||
} ); | ||
} ); | ||
}; | ||
} | ||
|
||
/** @typedef {import('estree').Node} Node */ | ||
/** @typedef {Object<string, string[]|undefined>} AllowedImportsMap */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.