eslint-plugin-unicorn
Version:
Various awesome ESLint rules
70 lines (62 loc) • 2.05 kB
JavaScript
'use strict';
const {methodCallSelector} = require('./selectors/index.js');
const {appendArgument} = require('./fix/index.js');
const ERROR = 'error';
const SUGGESTION_TARGET_LOCATION_ORIGIN = 'target-location-origin';
const SUGGESTION_SELF_LOCATION_ORIGIN = 'self-location-origin';
const SUGGESTION_STAR = 'star';
const messages = {
[ERROR]: 'Missing the `targetOrigin` argument.',
[SUGGESTION_TARGET_LOCATION_ORIGIN]: 'Use `{{target}}.location.origin`.',
[SUGGESTION_SELF_LOCATION_ORIGIN]: 'Use `self.location.origin`.',
[SUGGESTION_STAR]: 'Use `"*"`.'
};
/** @param {import('eslint').Rule.RuleContext} context */
function create(context) {
const sourceCode = context.getSourceCode();
return {
[methodCallSelector({name: 'postMessage', length: 1})](node) {
const [penultimateToken, lastToken] = sourceCode.getLastTokens(node, 2);
const suggestions = [];
const target = node.callee.object;
if (target.type === 'Identifier') {
const {name} = target;
suggestions.push({
messageId: SUGGESTION_TARGET_LOCATION_ORIGIN,
data: {target: name},
code: `${target.name}.location.origin`
});
if (name !== 'self' && name !== 'window' && name !== 'globalThis') {
suggestions.push({messageId: SUGGESTION_SELF_LOCATION_ORIGIN, code: 'self.location.origin'});
}
} else {
suggestions.push({messageId: SUGGESTION_SELF_LOCATION_ORIGIN, code: 'self.location.origin'});
}
suggestions.push({messageId: SUGGESTION_STAR, code: '\'*\''});
return {
loc: {
start: penultimateToken.loc.end,
end: lastToken.loc.end
},
messageId: ERROR,
suggest: suggestions.map(({messageId, data, code}) => ({
messageId,
data,
/** @param {import('eslint').Rule.RuleFixer} fixer */
fix: fixer => appendArgument(fixer, node, code, sourceCode)
}))
};
}
};
}
module.exports = {
create,
meta: {
type: 'problem',
docs: {
description: 'Enforce using the `targetOrigin` argument with `window.postMessage()`.'
},
messages,
hasSuggestions: true
}
};