Skip to content

Commit

Permalink
permit Promise.prototype['then'] access and test for other prototype …
Browse files Browse the repository at this point in the history
…access
  • Loading branch information
brettz9 committed Oct 16, 2024
1 parent 65a8b7d commit b64feb1
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 8 deletions.
3 changes: 3 additions & 0 deletions __tests__/spec-only.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ ruleTester.run('spec-only', rule, {
'Promise.all()',
'Promise["all"]',
'Promise[method];',
'Promise.prototype;',
'Promise.prototype[method];',
'Promise.prototype["then"];',
'Promise.race()',
'var ctch = Promise.prototype.catch',
'Promise.withResolvers()',
Expand Down
39 changes: 31 additions & 8 deletions rules/spec-only.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,28 @@ const getDocsUrl = require('./lib/get-docs-url')

const PROMISE_INSTANCE_METHODS = new Set(['then', 'catch', 'finally'])

function isPermittedProperty(expression, standardSet, allowedMethods) {
// istanbul ignore if
if (expression.type !== 'MemberExpression') return false

if (expression.property.type === 'Literal')
return (
standardSet.has(expression.property.value) ||
allowedMethods.includes(expression.property.value)
)

// istanbul ignore else
if (expression.property.type === 'Identifier')
return (
expression.computed ||
standardSet.has(expression.property.name) ||
allowedMethods.includes(expression.property.name)
)

// istanbul ignore next
return false
}

module.exports = {
meta: {
type: 'problem',
Expand Down Expand Up @@ -37,15 +59,16 @@ module.exports = {
MemberExpression(node) {
if (
node.object.type === 'Identifier' &&
(!node.computed || node.property.type === 'Literal') &&
node.object.name === 'Promise' &&
((node.property.name && !PROMISE_STATICS.has(node.property.name)) ||
(node.property.value &&
!PROMISE_STATICS.has(node.property.value))) &&
(node.property.name !== 'prototype' ||
(!PROMISE_INSTANCE_METHODS.has(node?.parent?.property?.name) &&
!allowedMethods.includes(node?.parent?.property?.name))) &&
!allowedMethods.includes(node.property.name ?? node.property.value)
((node.property.name !== 'prototype' &&
!isPermittedProperty(node, PROMISE_STATICS, allowedMethods)) ||
(node.property.name === 'prototype' &&
node.parent.type === 'MemberExpression' &&
!isPermittedProperty(
node.parent,
PROMISE_INSTANCE_METHODS,
allowedMethods,
)))
) {
context.report({
node,
Expand Down

0 comments on commit b64feb1

Please sign in to comment.