eslint-plugin-vue
Advanced tools
Comparing version 7.0.1 to 7.1.0
@@ -8,5 +8,7 @@ /* | ||
rules: { | ||
'vue/array-bracket-newline': 'off', | ||
'vue/array-bracket-spacing': 'off', | ||
'vue/arrow-spacing': 'off', | ||
'vue/block-spacing': 'off', | ||
'vue/block-tag-newline': 'off', | ||
'vue/brace-style': 'off', | ||
@@ -13,0 +15,0 @@ 'vue/comma-dangle': 'off', |
@@ -10,2 +10,3 @@ /* | ||
rules: { | ||
'array-bracket-newline': require('./rules/array-bracket-newline'), | ||
'array-bracket-spacing': require('./rules/array-bracket-spacing'), | ||
@@ -16,2 +17,3 @@ 'arrow-spacing': require('./rules/arrow-spacing'), | ||
'block-spacing': require('./rules/block-spacing'), | ||
'block-tag-newline': require('./rules/block-tag-newline'), | ||
'brace-style': require('./rules/brace-style'), | ||
@@ -18,0 +20,0 @@ camelcase: require('./rules/camelcase'), |
@@ -9,5 +9,4 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule( | ||
require('eslint/lib/rules/array-bracket-spacing'), | ||
{ skipDynamicArguments: true } | ||
) | ||
module.exports = wrapCoreRule('array-bracket-spacing', { | ||
skipDynamicArguments: true | ||
}) |
@@ -9,2 +9,2 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/arrow-spacing')) | ||
module.exports = wrapCoreRule('arrow-spacing') |
@@ -9,4 +9,4 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/block-spacing'), { | ||
module.exports = wrapCoreRule('block-spacing', { | ||
skipDynamicArguments: true | ||
}) |
@@ -9,4 +9,4 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/brace-style'), { | ||
module.exports = wrapCoreRule('brace-style', { | ||
skipDynamicArguments: true | ||
}) |
@@ -9,2 +9,2 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/camelcase')) | ||
module.exports = wrapCoreRule('camelcase') |
@@ -9,2 +9,2 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/comma-dangle')) | ||
module.exports = wrapCoreRule('comma-dangle') |
@@ -9,5 +9,5 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/comma-spacing'), { | ||
module.exports = wrapCoreRule('comma-spacing', { | ||
skipDynamicArguments: true, | ||
skipDynamicArgumentsReport: true | ||
}) |
@@ -9,3 +9,3 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/comma-style'), { | ||
module.exports = wrapCoreRule('comma-style', { | ||
create(_context, { coreHandlers }) { | ||
@@ -12,0 +12,0 @@ return { |
@@ -14,2 +14,3 @@ /** | ||
const { isKebabCase } = require('../utils/casing') | ||
const { toRegExp } = require('../utils/regexp') | ||
@@ -76,3 +77,16 @@ // ------------------------------------------------------------------------------ | ||
fixable: null, | ||
schema: [], | ||
schema: [ | ||
{ | ||
type: 'object', | ||
properties: { | ||
ignores: { | ||
type: 'array', | ||
items: { type: 'string' }, | ||
uniqueItems: true, | ||
additionalItems: false | ||
} | ||
}, | ||
additionalProperties: false | ||
} | ||
], | ||
messages: { | ||
@@ -85,2 +99,5 @@ unexpected: "Custom event name '{{name}}' must be kebab-case." | ||
const setupContexts = new Map() | ||
const options = context.options[0] || {} | ||
/** @type {RegExp[]} */ | ||
const ignores = (options.ignores || []).map(toRegExp) | ||
@@ -92,3 +109,3 @@ /** | ||
const name = nameLiteralNode.value | ||
if (isValidEventName(name)) { | ||
if (ignores.some((re) => re.test(name)) || isValidEventName(name)) { | ||
return | ||
@@ -95,0 +112,0 @@ } |
@@ -9,2 +9,2 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/dot-location')) | ||
module.exports = wrapCoreRule('dot-location') |
@@ -9,2 +9,2 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/dot-notation')) | ||
module.exports = wrapCoreRule('dot-notation') |
@@ -9,2 +9,2 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/eqeqeq')) | ||
module.exports = wrapCoreRule('eqeqeq') |
@@ -9,4 +9,4 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/func-call-spacing'), { | ||
module.exports = wrapCoreRule('func-call-spacing', { | ||
skipDynamicArguments: true | ||
}) |
@@ -9,4 +9,4 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/key-spacing'), { | ||
module.exports = wrapCoreRule('key-spacing', { | ||
skipDynamicArguments: true | ||
}) |
@@ -9,4 +9,4 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/keyword-spacing'), { | ||
module.exports = wrapCoreRule('keyword-spacing', { | ||
skipDynamicArguments: true | ||
}) |
@@ -9,2 +9,2 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/no-empty-pattern')) | ||
module.exports = wrapCoreRule('no-empty-pattern') |
@@ -10,3 +10,3 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/no-extra-parens'), { | ||
module.exports = wrapCoreRule('no-extra-parens', { | ||
skipDynamicArguments: true, | ||
@@ -13,0 +13,0 @@ create: createForVueSyntax |
@@ -9,2 +9,2 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/no-restricted-syntax')) | ||
module.exports = wrapCoreRule('no-restricted-syntax') |
@@ -9,2 +9,2 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/no-sparse-arrays')) | ||
module.exports = wrapCoreRule('no-sparse-arrays') |
@@ -184,2 +184,13 @@ /** | ||
registeredComponents.push(...utils.getRegisteredComponents(obj)) | ||
const nameProperty = utils.findProperty(obj, 'name') | ||
if (nameProperty) { | ||
if (nameProperty.value.type === 'Literal') { | ||
registeredComponents.push({ | ||
node: nameProperty, | ||
name: `${nameProperty.value.value}` | ||
}) | ||
} | ||
} | ||
}) | ||
@@ -186,0 +197,0 @@ ) |
@@ -581,2 +581,37 @@ /** | ||
/** | ||
* @param {VueComponentPropertiesContainer} container | ||
* @param {UsedProps} baseUseProps | ||
*/ | ||
function processUsed(container, baseUseProps) { | ||
for (const { usedNames, unknown } of iterateUsedProps(baseUseProps)) { | ||
if (unknown) { | ||
container.unknown = true | ||
return | ||
} | ||
for (const name of usedNames.names()) { | ||
container.usedNames.add(name) | ||
} | ||
} | ||
} | ||
/** | ||
* @param {Expression} node | ||
* @returns {Property|null} | ||
*/ | ||
function getParentProperty(node) { | ||
if ( | ||
!node.parent || | ||
node.parent.type !== 'Property' || | ||
node.parent.value !== node | ||
) { | ||
return null | ||
} | ||
const property = node.parent | ||
if (!property.parent || property.parent.type !== 'ObjectExpression') { | ||
return null | ||
} | ||
return /** @type {Property} */ (property) | ||
} | ||
const scriptVisitor = Object.assign( | ||
@@ -633,2 +668,57 @@ {}, | ||
}, | ||
/** @param { (FunctionExpression | ArrowFunctionExpression) & { parent: Property }} node */ | ||
'ObjectExpression > Property > :function[params.length>0]'( | ||
node, | ||
vueData | ||
) { | ||
const property = getParentProperty(node) | ||
if (!property) { | ||
return | ||
} | ||
if (property.parent === vueData.node) { | ||
if (utils.getStaticPropertyName(property) !== 'data') { | ||
return | ||
} | ||
// check { data: (vm) => vm.prop } | ||
} else { | ||
const parentProperty = getParentProperty(property.parent) | ||
if (!parentProperty) { | ||
return | ||
} | ||
if (parentProperty.parent === vueData.node) { | ||
if (utils.getStaticPropertyName(parentProperty) !== 'computed') { | ||
return | ||
} | ||
// check { computed: { foo: (vm) => vm.prop } } | ||
} else { | ||
const parentParentProperty = getParentProperty( | ||
parentProperty.parent | ||
) | ||
if (!parentParentProperty) { | ||
return | ||
} | ||
if (parentParentProperty.parent === vueData.node) { | ||
if ( | ||
utils.getStaticPropertyName(parentParentProperty) !== | ||
'computed' || | ||
utils.getStaticPropertyName(property) !== 'handler' | ||
) { | ||
return | ||
} | ||
// check { computed: { foo: { handler: (vm) => vm.prop } } } | ||
} else { | ||
return | ||
} | ||
} | ||
} | ||
const paramsUsedProps = getParamsUsedProps(node) | ||
const usedProps = /** @type {ParamUsedProps} */ (paramsUsedProps.getParam( | ||
0 | ||
)) | ||
processUsed( | ||
getVueComponentPropertiesContainer(vueData.node), | ||
usedProps | ||
) | ||
}, | ||
onSetupFunctionEnter(node, vueData) { | ||
@@ -695,11 +785,3 @@ const container = getVueComponentPropertiesContainer(vueData.node) | ||
for (const { usedNames, unknown } of iterateUsedProps(usedProps)) { | ||
if (unknown) { | ||
container.unknown = true | ||
return | ||
} | ||
for (const name of usedNames.names()) { | ||
container.usedNames.add(name) | ||
} | ||
} | ||
processUsed(container, usedProps) | ||
} | ||
@@ -706,0 +788,0 @@ }), |
@@ -9,2 +9,2 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/no-useless-concat')) | ||
module.exports = wrapCoreRule('no-useless-concat') |
@@ -9,5 +9,4 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule( | ||
require('eslint/lib/rules/object-curly-newline'), | ||
{ skipDynamicArguments: true } | ||
) | ||
module.exports = wrapCoreRule('object-curly-newline', { | ||
skipDynamicArguments: true | ||
}) |
@@ -9,5 +9,4 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule( | ||
require('eslint/lib/rules/object-curly-spacing'), | ||
{ skipDynamicArguments: true } | ||
) | ||
module.exports = wrapCoreRule('object-curly-spacing', { | ||
skipDynamicArguments: true | ||
}) |
@@ -9,5 +9,4 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule( | ||
require('eslint/lib/rules/object-property-newline'), | ||
{ skipDynamicArguments: true } | ||
) | ||
module.exports = wrapCoreRule('object-property-newline', { | ||
skipDynamicArguments: true | ||
}) |
@@ -9,2 +9,2 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/operator-linebreak')) | ||
module.exports = wrapCoreRule('operator-linebreak') |
@@ -9,2 +9,2 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/prefer-template')) | ||
module.exports = wrapCoreRule('prefer-template') |
@@ -9,5 +9,5 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/space-in-parens'), { | ||
module.exports = wrapCoreRule('space-in-parens', { | ||
skipDynamicArguments: true, | ||
skipDynamicArgumentsReport: true | ||
}) |
@@ -9,4 +9,4 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/space-infix-ops'), { | ||
module.exports = wrapCoreRule('space-infix-ops', { | ||
skipDynamicArguments: true | ||
}) |
@@ -9,4 +9,4 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule(require('eslint/lib/rules/space-unary-ops'), { | ||
module.exports = wrapCoreRule('space-unary-ops', { | ||
skipDynamicArguments: true | ||
}) |
@@ -9,5 +9,4 @@ /** | ||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule( | ||
require('eslint/lib/rules/template-curly-spacing'), | ||
{ skipDynamicArguments: true } | ||
) | ||
module.exports = wrapCoreRule('template-curly-spacing', { | ||
skipDynamicArguments: true | ||
}) |
@@ -78,3 +78,3 @@ /** | ||
/** | ||
* Get the normalized name of a given `v-slot` directive node. | ||
* Get the normalized name of a given `v-slot` directive node with modifiers after `v-slot:` directive. | ||
* @param {VDirective} node The `v-slot` directive node. | ||
@@ -85,5 +85,8 @@ * @param {SourceCode} sourceCode The source code. | ||
function getNormalizedName(node, sourceCode) { | ||
return node.key.argument == null | ||
? 'default' | ||
: sourceCode.getText(node.key.argument) | ||
if (node.key.argument == null) { | ||
return 'default' | ||
} | ||
return node.key.modifiers.length === 0 | ||
? sourceCode.getText(node.key.argument) | ||
: sourceCode.text.slice(node.key.argument.range[0], node.key.range[1]) | ||
} | ||
@@ -155,2 +158,15 @@ | ||
/** | ||
* If `allowModifiers` option is set to `true`, check whether a given argument node has invalid modifiers like `v-slot.foo`. | ||
* Otherwise, check whether a given argument node has at least one modifier. | ||
* @param {VDirective} vSlot The `v-slot` directive to check. | ||
* @param {boolean} allowModifiers `allowModifiers` option in context. | ||
* @return {boolean} `true` if that argument node has invalid modifiers like `v-slot.foo`. | ||
*/ | ||
function hasInvalidModifiers(vSlot, allowModifiers) { | ||
return allowModifiers | ||
? vSlot.key.argument == null && vSlot.key.modifiers.length >= 1 | ||
: vSlot.key.modifiers.length >= 1 | ||
} | ||
module.exports = { | ||
@@ -165,3 +181,12 @@ meta: { | ||
fixable: null, | ||
schema: [], | ||
schema: [ | ||
{ | ||
type: 'object', | ||
properties: { | ||
allowModifiers: { | ||
type: 'boolean' | ||
} | ||
} | ||
} | ||
], | ||
messages: { | ||
@@ -188,2 +213,4 @@ ownerMustBeCustomElement: | ||
const sourceCode = context.getSourceCode() | ||
const options = context.options[0] || {} | ||
const allowModifiers = options.allowModifiers === true | ||
@@ -272,3 +299,4 @@ return utils.defineTemplateBodyVisitor(context, { | ||
// Verify modifiers. | ||
if (node.key.modifiers.length >= 1) { | ||
if (hasInvalidModifiers(node, allowModifiers)) { | ||
// E.g., <template v-slot.foo> | ||
context.report({ | ||
@@ -275,0 +303,0 @@ node, |
@@ -111,3 +111,15 @@ /** | ||
/** @type { Map<string, RuleModule> | null } */ | ||
let ruleMap = null | ||
/** | ||
* Get the core rule implementation from the rule name | ||
* @param {string} name | ||
* @returns {RuleModule} | ||
*/ | ||
function getCoreRule(name) { | ||
const map = ruleMap || (ruleMap = new (require('eslint').Linter)().getRules()) | ||
return map.get(name) || require(`eslint/lib/rules/${name}`) | ||
} | ||
/** | ||
* Wrap the rule context object to override methods which access to tokens (such as getTokenAfter). | ||
@@ -229,3 +241,3 @@ * @param {RuleContext} context The rule context object. | ||
* Wrap a given core rule to apply it to Vue.js template. | ||
* @param {RuleModule} coreRule The core rule implementation to wrap. | ||
* @param {string} coreRuleName The name of the core rule implementation to wrap. | ||
* @param {Object} [options] The option of this rule. | ||
@@ -238,3 +250,4 @@ * @param {string[]} [options.categories] The categories of this rule. | ||
*/ | ||
wrapCoreRule(coreRule, options) { | ||
wrapCoreRule(coreRuleName, options) { | ||
const coreRule = getCoreRule(coreRuleName) | ||
const { | ||
@@ -241,0 +254,0 @@ categories, |
{ | ||
"name": "eslint-plugin-vue", | ||
"version": "7.0.1", | ||
"version": "7.1.0", | ||
"description": "Official ESLint plugin for Vue.js", | ||
@@ -16,3 +16,2 @@ "main": "lib/index.js", | ||
"lint:fix": "eslint . --rulesdir eslint-internal-rules --fix", | ||
"pretsc": "node ./tools/setup-eslint-rule-types.js", | ||
"tsc": "tsc", | ||
@@ -60,3 +59,3 @@ "preversion": "npm test && npm run update && git add .", | ||
"semver": "^7.3.2", | ||
"vue-eslint-parser": "^7.1.0" | ||
"vue-eslint-parser": "^7.1.1" | ||
}, | ||
@@ -63,0 +62,0 @@ "devDependencies": { |
@@ -43,3 +43,3 @@ # eslint-plugin-vue | ||
- [ESTree docs](https://github.com/estree/estree) | ||
- [vue-eslint-parser AST docs](https://github.com/mysticatea/vue-eslint-parser/blob/master/docs/ast.md) | ||
- [vue-eslint-parser AST docs](https://github.com/vuejs/vue-eslint-parser/blob/master/docs/ast.md) | ||
@@ -46,0 +46,0 @@ The `vue-eslint-parser` provides a few useful parser services that help traverse the produced AST and access tokens of the template: |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
761304
203
23463
2
Updatedvue-eslint-parser@^7.1.1