in src/dispatch/static/dispatch/eslint-local-rules.js [89:386]
fix(fixer) {
const fixes = []
// remove vee-validate imports
vvImportNodes.forEach((node) => {
fixes.push(fixer.remove(node))
context.getDeclaredVariables(node).forEach((variable) => {
variable.references.forEach((reference) => {
fixes.push(
fixer.removeRange([
context.sourceCode.getIndexFromLoc({
line: reference.identifier.parent.loc.start.line,
column: 0,
}) - 1,
context.sourceCode.getIndexFromLoc(reference.identifier.parent.loc.end) +
1,
])
)
})
})
})
vvRuleImportNodes.forEach((node) => {
fixes.push(fixer.remove(node))
})
if (observerNode) {
const observerRef = observerNode.startTag.attributes.find((attr) => {
return attr.type === "VAttribute" && attr.key.name === "ref"
})
const observerSlot = observerNode.startTag.attributes.find((attr) => {
return (
attr.type === "VAttribute" &&
attr.key.type === "VDirectiveKey" &&
attr.key.name.name === "slot"
)
})
const otherAttrs = observerNode.startTag.attributes
.filter((attr) => {
return attr !== observerRef && attr !== observerSlot
})
.map((attr) => context.sourceCode.getText(attr))
let formSubmitHandlerName
let formSubmitHandlerNode
if (formNode) {
const submitListener = formNode.startTag.attributes.find((attr) => {
return (
attr.directive &&
attr.key.name.name === "on" &&
attr.key.argument.name === "submit"
)
})
if (submitListener) {
formSubmitHandlerName = submitListener.value.expression.name
if (formSubmitHandlerName) {
methodNodes.forEach((node) => {
if (node.key.name === formSubmitHandlerName) {
formSubmitHandlerNode = node
}
})
if (!formSubmitHandlerNode) {
throw new Error("Unable to locate form submit handler")
}
}
} else {
throw new Error("No submit listener")
}
}
let newStartTag = "<v-form"
if (observerRef) {
newStartTag += ` ref="form"`
}
if (otherAttrs.length) {
newStartTag += " " + otherAttrs.join(" ")
}
if (formNode) {
const formAttrs = formNode.startTag.attributes.map((attr) =>
context.sourceCode.getText(attr)
)
if (formAttrs.length) {
newStartTag += " " + formAttrs.join(" ")
}
} else {
newStartTag += ` @submit.prevent`
}
if (observerSlot) {
newStartTag += ` v-slot="{ isValid }"`
}
newStartTag += ">"
if (formNode) {
fixes.push(
fixer.replaceTextRange(
[observerNode.startTag.range[0], formNode.startTag.range[1]],
newStartTag
)
)
} else {
fixes.push(fixer.replaceText(observerNode.startTag, newStartTag))
}
if (observerSlot) {
observerNode.variables.forEach((variable) => {
if (variable.id.name === "invalid") {
variable.references.forEach((ref) => {
fixes.push(fixer.replaceText(ref.id, "!isValid.value"))
})
} else if (variable.id.name !== "validated") {
throw new Error("unsupported variable")
}
})
}
if (formNode) {
fixes.push(
fixer.replaceTextRange(
[formNode.endTag.range[0], observerNode.endTag.range[1]],
"</v-form>"
)
)
} else {
fixes.push(fixer.replaceText(observerNode.endTag, "</v-form>"))
}
observerRefNodes.forEach((node) => {
fixes.push(fixer.replaceText(node.property, "form"))
if (node.parent.property.name === "reset") {
fixes.push(fixer.replaceText(node.parent.property, "resetValidation"))
} else {
fixes.push({
range: Array(2).fill(
context.sourceCode.getIndexFromLoc({
line: node.loc.start.line + 1,
column: 0,
}) - 1
),
text: " // TODO: find vuetify equivalent",
})
}
})
if (formSubmitHandlerNode) {
if (!formSubmitHandlerNode.value.async) {
fixes.push(fixer.insertTextBefore(formSubmitHandlerNode.key, "async "))
}
let paramName = "event"
if (!formSubmitHandlerNode.value.params.length) {
fixes.push(
fixer.replaceTextRange(
[
formSubmitHandlerNode.value.range[0],
formSubmitHandlerNode.value.body.range[0],
],
`(${paramName}) `
)
)
} else {
paramName = formSubmitHandlerNode.value.params[0].name
}
const indent = context.sourceCode.lines
.at(formSubmitHandlerNode.value.body.body[0].loc.start.line - 1)
.match(/^\s*/)[0]
fixes.push(
fixer.insertTextBefore(
formSubmitHandlerNode.value.body.body[0],
`if (!(await ${paramName}).valid) return\n\n${indent}`
)
)
}
}
validationProviderNodes.forEach(({ node, child, rules, vid }) => {
fixes.push(fixer.removeRange([node.startTag.range[0], child.startTag.range[0]]))
if (node.variables.length) {
const b4 = template.getTokenBefore(
node.variables[0].references[0].id.parent.parent
)
fixes.push(
fixer.removeRange([
b4.range[1],
node.variables[0].references[0].id.parent.parent.range[1],
])
)
} else {
node.children.forEach((child) => {
if (child.type === "VElement") {
child.startTag.attributes.forEach((attr) => {
if (
attr.key.type === "VDirectiveKey" &&
attr.key.name.name === "slot-scope"
) {
fixes.push(fixer.remove(attr))
if (child.variables.length) {
child.variables.forEach((variable) => {
const b4 = template.getTokenBefore(
variable.references[0].id.parent.parent
)
fixes.push(
fixer.removeRange([
b4.range[1],
variable.references[0].id.parent.parent.range[1],
])
)
})
} else {
throw new Error("slot-scope without variables")
}
}
})
}
})
}
const isMultiline = child.startTag.loc.start.line !== child.startTag.loc.end.line
const indent = isMultiline
? "\n" +
context.sourceCode.lines
.at(child.startTag.loc.start.line - 1)
.match(/^\s*/)[0] +
" ".repeat(2)
: " "
if (vid) {
fixes.push(
fixer.insertTextAfter(
child.startTag.attributes.at(-1),
indent +
(vid.directive
? `:name=${context.sourceCode.getText(vid.value)}`
: `name="${vid.value.value}"`)
)
)
}
if (rules) {
let rulesArray
let rulesString
if (rules.directive) {
// dynamic rules
if (
rules.value.expression.type !== "TemplateLiteral" ||
rules.value.expression.quasis.length !== 2 ||
rules.value.expression.expressions.length !== 1 ||
rules.value.expression.expressions[0].type !== "ConditionalExpression" ||
rules.value.expression.expressions[0].alternate.type !== "Literal" ||
rules.value.expression.expressions[0].alternate.value !== ""
) {
throw new Error("Unsupported dynamic rules")
}
const test = context.sourceCode.getText(
rules.value.expression.expressions[0].test
)
const rulesValue = rules.value.expression.expressions[0].consequent.value
rulesArray = rulesValue.split("|")
rulesString = `:rules="${test} ? [${rulesArray
.map((v) => `rules.${v}`)
.join(", ")}] : []"`
} else {
const rulesValue = rules.value.value
rulesArray = rulesValue.split("|")
rulesString = `:rules="[${rulesArray.map((v) => `rules.${v}`).join(", ")}]"`
}
fixes.push(
fixer.insertTextAfter(child.startTag.attributes.at(-1), indent + rulesString)
)
rulesArray.forEach((rule) => rulesToImport.add(rule))
}
fixes.push(
fixer.removeRange([
child.startTag.selfClosing ? child.startTag.range[1] : child.endTag.range[1],
node.endTag.range[1],
])
)
})
if (rulesToImport.size) {
fixes.push(
fixer.insertTextBefore(
context.sourceCode.ast.body[0],
"import { " + [...rulesToImport].join(", ") + " } from '@/util/form'\n"
),
fixer.insertTextAfterRange(
[vueObjectNode.range[0] + 1, vueObjectNode.range[0] + 1],
`
setup() {
return {
rules: { ${[...rulesToImport].join(", ")} }
}
},`
)
)
}
return fixes
},