Skip to content

Commit 8b877f7

Browse files
Vuex and Pinia support for no-undef-properties (#2513)
Co-authored-by: Flo Edelmann <[email protected]>
1 parent 3157fad commit 8b877f7

File tree

2 files changed

+608
-1
lines changed

2 files changed

+608
-1
lines changed

lib/rules/no-undef-properties.js

+52-1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ module.exports = {
111111
).map(toRegExp)
112112
const propertyReferenceExtractor = definePropertyReferenceExtractor(context)
113113
const programNode = context.getSourceCode().ast
114+
/**
115+
* Property names identified as defined via a Vuex or Pinia helpers
116+
* @type {Set<string>}
117+
*/
118+
const propertiesDefinedByStoreHelpers = new Set()
114119

115120
/**
116121
* @param {ASTNode} node
@@ -185,7 +190,8 @@ module.exports = {
185190
report(node, name, messageId = 'undef') {
186191
if (
187192
reserved.includes(name) ||
188-
ignores.some((ignore) => ignore.test(name))
193+
ignores.some((ignore) => ignore.test(name)) ||
194+
propertiesDefinedByStoreHelpers.has(name)
189195
) {
190196
return
191197
}
@@ -331,6 +337,51 @@ module.exports = {
331337
}
332338
}),
333339
utils.defineVueVisitor(context, {
340+
/**
341+
* @param {CallExpression} node
342+
*/
343+
CallExpression(node) {
344+
if (node.callee.type !== 'Identifier') return
345+
/** @type {'methods'|'computed'|null} */
346+
let groupName = null
347+
if (/^mapMutations|mapActions$/u.test(node.callee.name)) {
348+
groupName = GROUP_METHODS
349+
} else if (
350+
/^mapState|mapGetters|mapWritableState$/u.test(node.callee.name)
351+
) {
352+
groupName = GROUP_COMPUTED_PROPERTY
353+
}
354+
355+
if (!groupName || node.arguments.length === 0) return
356+
// On Pinia the store is always the first argument
357+
const arg =
358+
node.arguments.length === 2 ? node.arguments[1] : node.arguments[0]
359+
if (arg.type === 'ObjectExpression') {
360+
// e.g.
361+
// `mapMutations({ add: 'increment' })`
362+
// `mapState({ count: state => state.todosCount })`
363+
for (const prop of arg.properties) {
364+
const name =
365+
prop.type === 'SpreadElement'
366+
? null
367+
: utils.getStaticPropertyName(prop)
368+
if (name) {
369+
propertiesDefinedByStoreHelpers.add(name)
370+
}
371+
}
372+
} else if (arg.type === 'ArrayExpression') {
373+
// e.g. `mapMutations(['add'])`
374+
for (const element of arg.elements) {
375+
if (!element || !utils.isStringLiteral(element)) {
376+
continue
377+
}
378+
const name = utils.getStringLiteralValue(element)
379+
if (name) {
380+
propertiesDefinedByStoreHelpers.add(name)
381+
}
382+
}
383+
}
384+
},
334385
onVueObjectEnter(node) {
335386
const ctx = getVueComponentContext(node)
336387

0 commit comments

Comments
 (0)