@vue-vine/eslint-plugin
Version:
ESLint plugin for Vue Vine
1,530 lines (1,508 loc) • 60 kB
JavaScript
import VueVineESLintParser, { NS } from "@vue-vine/eslint-parser";
import { unindent } from "@antfu/utils";
import { generateDifferences, showInvisibles } from "prettier-linter-helpers";
import { makeModuleSynchronized } from "make-synchronized";
//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
//#region package.json
var version = "1.1.12";
//#endregion
//#region src/data/html-elements.json
var html_elements_default = [
"html",
"body",
"base",
"head",
"link",
"meta",
"style",
"title",
"address",
"article",
"aside",
"footer",
"header",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"hgroup",
"nav",
"section",
"div",
"dd",
"dl",
"dt",
"figcaption",
"figure",
"hr",
"img",
"li",
"main",
"ol",
"p",
"pre",
"ul",
"a",
"b",
"abbr",
"bdi",
"bdo",
"br",
"cite",
"code",
"data",
"dfn",
"em",
"i",
"kbd",
"mark",
"q",
"rp",
"rt",
"rtc",
"ruby",
"s",
"samp",
"small",
"span",
"strong",
"sub",
"sup",
"time",
"u",
"var",
"wbr",
"area",
"audio",
"map",
"track",
"video",
"embed",
"object",
"param",
"source",
"canvas",
"script",
"noscript",
"del",
"ins",
"caption",
"col",
"colgroup",
"table",
"thead",
"tbody",
"tfoot",
"td",
"th",
"tr",
"button",
"datalist",
"fieldset",
"form",
"input",
"label",
"legend",
"meter",
"optgroup",
"option",
"output",
"progress",
"select",
"textarea",
"details",
"dialog",
"menu",
"menuitem",
"summary",
"content",
"element",
"shadow",
"template",
"slot",
"blockquote",
"iframe",
"noframes",
"picture"
];
//#endregion
//#region src/data/math-elements.json
var math_elements_default = [
"math",
"maction",
"annotation",
"annotation-xml",
"menclose",
"merror",
"mfenced",
"mfrac",
"mi",
"mmultiscripts",
"mn",
"mo",
"mover",
"mpadded",
"mphantom",
"mprescripts",
"mroot",
"mrow",
"ms",
"semantics",
"mspace",
"msqrt",
"mstyle",
"msub",
"msup",
"msubsup",
"mtable",
"mtd",
"mtext",
"mtr",
"munder",
"munderover"
];
//#endregion
//#region src/data/svg-elements.json
var svg_elements_default = [
"a",
"animate",
"animateMotion",
"animateTransform",
"audio",
"canvas",
"circle",
"clipPath",
"defs",
"desc",
"discard",
"ellipse",
"feBlend",
"feColorMatrix",
"feComponentTransfer",
"feComposite",
"feConvolveMatrix",
"feDiffuseLighting",
"feDisplacementMap",
"feDistantLight",
"feDropShadow",
"feFlood",
"feFuncA",
"feFuncB",
"feFuncG",
"feFuncR",
"feGaussianBlur",
"feImage",
"feMerge",
"feMergeNode",
"feMorphology",
"feOffset",
"fePointLight",
"feSpecularLighting",
"feSpotLight",
"feTile",
"feTurbulence",
"filter",
"foreignObject",
"g",
"iframe",
"image",
"line",
"linearGradient",
"marker",
"mask",
"metadata",
"mpath",
"path",
"pattern",
"polygon",
"polyline",
"radialGradient",
"rect",
"script",
"set",
"stop",
"style",
"svg",
"switch",
"symbol",
"text",
"textPath",
"title",
"tspan",
"unknown",
"use",
"video",
"view"
];
//#endregion
//#region src/data/void-elements.json
var void_elements_default = [
"area",
"base",
"br",
"col",
"embed",
"hr",
"img",
"input",
"keygen",
"link",
"menuitem",
"meta",
"param",
"source",
"track",
"wbr"
];
//#endregion
//#region src/utils.ts
const hasDocs = [
"format-prefer-template",
"format-vine-component-name",
"format-vine-macros-leading",
"format-vine-style-indent",
"no-child-content",
"no-dupe-attributes",
"no-dupe-else-if"
];
const blobUrl = "https://github.com/vue-vine/vue-vine/blob/main/packages/eslint-plugin/src/rules";
/**
* Creates reusable function to create rules with default options and docs URLs.
*
* @param urlCreator Creates a documentation URL for a given rule name.
* @returns Function to create a rule with the docs URL format.
*/
function RuleCreator(urlCreator) {
return function createNamedRule({ name, meta,...rule$13 }) {
return createRule({
meta: {
...meta,
docs: {
...meta.docs,
url: urlCreator(name, meta.docs.category)
}
},
...rule$13
});
};
}
/**
* Creates a well-typed TSESLint custom ESLint rule without a docs URL.
*
* @returns Well-typed TSESLint custom ESLint rule.
* @remarks It is generally better to provide a docs URL function to RuleCreator.
*/
function createRule({ create, defaultOptions, meta }) {
return {
create: ((context) => {
return create(context, context.options.map((options, index) => {
return {
...defaultOptions[index] || {},
...options || {}
};
}));
}),
defaultOptions,
meta
};
}
const createEslintRule = RuleCreator((ruleName, category) => hasDocs.includes(ruleName) ? `${blobUrl}/${category}/${ruleName}.md` : `${blobUrl}/${category}/${ruleName}.ts`);
function notVineCompFn(node) {
return !node.__isVine__;
}
/**
* Checks whether or not the tokens of two given nodes are same.
* @param left A node 1 to compare.
* @param right A node 2 to compare.
* @param {ParserServices.TokenStore | SourceCode} sourceCode The ESLint source code object.
* @returns {boolean} the source code for the given node.
*/
function equalTokens(left, right, sourceCode) {
const tokensL = sourceCode.getTokens(left);
const tokensR = sourceCode.getTokens(right);
if (tokensL.length !== tokensR.length) return false;
return tokensL.every((token, i) => token.type === tokensR[i].type && token.value === tokensR[i].value);
}
/**
* Get the previous sibling element of the given element.
* @param node The element node to get the previous sibling element.
* @returns The previous sibling element.
*/
function prevSibling(node) {
let prevElement = null;
for (const siblingNode of node.parent && node.parent.children || []) {
if (siblingNode === node) return prevElement;
if (siblingNode.type === "VElement") prevElement = siblingNode;
}
return null;
}
/**
* Get the directive which has the given name.
* @param node The start tag node to check.
* @param name The directive name to check.
* @param argument The directive argument to check.
* @returns The found directive.
*/
function getDirective(node, name, argument) {
return node.startTag.attributes.find((node$1) => node$1.directive && node$1.key.name.name === name && (argument === void 0 || (node$1.key.argument && node$1.key.argument.type === "VIdentifier" && node$1.key.argument.name) === argument)) || null;
}
function isVElement(node) {
return node.type === "VElement";
}
function hasAttribute(node, name, value) {
return Boolean(getAttribute(node, name, value));
}
function hasDirective(node, name, argument) {
return Boolean(getDirective(node, name, argument));
}
/**
* Get the attribute which has the given name.
*/
function getAttribute(node, name, value) {
return node.startTag.attributes.find((node$1) => !node$1.directive && node$1.key.name === name && (value === void 0 || node$1.value != null && node$1.value.value === value)) || null;
}
function isHtmlElementNode(node) {
return node.namespace === NS.HTML;
}
function isSvgElementNode(node) {
return node.namespace === NS.SVG;
}
function isMathElementNode(node) {
return node.namespace === NS.MathML;
}
function isHtmlVoidElementName(name) {
return void_elements_default.includes(name);
}
function isHtmlWellKnownElementName(name) {
return html_elements_default.includes(name);
}
function isSvgWellKnownElementName(name) {
return svg_elements_default.includes(name);
}
function isMathWellKnownElementName(name) {
return math_elements_default.includes(name);
}
function isCustomComponent(node, ignoreElementNamespaces = false) {
if (hasAttribute(node, "is") || hasDirective(node, "bind", "is") || hasDirective(node, "is")) return true;
const isHtmlName = isHtmlWellKnownElementName(node.rawName);
const isSvgName = isSvgWellKnownElementName(node.rawName);
const isMathName = isMathWellKnownElementName(node.rawName);
if (ignoreElementNamespaces) return !isHtmlName && !isSvgName && !isMathName;
return isHtmlElementNode(node) && !isHtmlName || isSvgElementNode(node) && !isSvgName || isMathElementNode(node) && !isMathName;
}
function checkPascalCase(fnName) {
return /^[A-Z][a-zA-Z0-9]*$/.test(fnName);
}
function prettierSnapshot(result) {
const resultLines = result.split("\n");
const maxLineNumLength = String(resultLines.length).length;
return `
┌${"─".repeat(maxLineNumLength + 2)}┬────────────────────────────────
${resultLines.map((line, i) => ` │ ${String(i + 1).padStart(maxLineNumLength)} │${line}`).join("\n")}
└${"─".repeat(maxLineNumLength + 2)}┴────────────────────────────────
`.trim();
}
//#endregion
//#region src/rules/essentials/no-child-content.ts
const RULE_NAME$6 = "no-child-content";
const SUGGEST_REMOVE_CHILD_CONTENT = "remove-child-content";
const DEFAULT_CATCH_NAMES = ["html", "text"];
function isWhiteSpaceTextNode(node) {
return node.type === "VText" && node.value.trim() === "";
}
const rule$12 = createEslintRule({
name: RULE_NAME$6,
meta: {
type: "problem",
docs: {
category: "essentials",
description: "Disallow element's child contents which would be overwritten by a directive like v-html or v-text"
},
hasSuggestions: true,
schema: [{
type: "object",
properties: { directives: {
type: "string",
default: []
} },
additionalProperties: false
}],
messages: {
[RULE_NAME$6]: "Child content is disallowed because it will be overwritten by directive v-{{ directiveName }}",
[SUGGEST_REMOVE_CHILD_CONTENT]: "Remove child content"
}
},
defaultOptions: [{ directives: [] }],
create(context) {
return { "VAttribute[directive=true]": (attrNode) => {
const { directives = [] } = context.options?.[0] ?? {};
const catchNames = [...new Set(DEFAULT_CATCH_NAMES.concat(directives))];
const directiveName = attrNode.key.name.name;
if (!catchNames.includes(directiveName)) return;
const vElementNode = attrNode.parent.parent;
if (!(vElementNode.children.length > 0)) return;
const notEmptyChildContents = vElementNode.children.filter((node) => !isWhiteSpaceTextNode(node));
if (notEmptyChildContents.length === 0) return;
notEmptyChildContents.forEach((node) => {
context.report({
node,
messageId: RULE_NAME$6,
data: { directiveName },
suggest: [{
messageId: SUGGEST_REMOVE_CHILD_CONTENT,
fix: (fixer) => {
return fixer.remove(node);
}
}]
});
});
} };
}
});
var no_child_content_default = rule$12;
//#endregion
//#region src/rules/essentials/no-dupe-attributes.ts
const RULE_NAME$5 = "no-dupe-attributes";
/**
* Get the name of the given attribute node.
* @param attribute The attribute node to get.
* @returns The name of the attribute.
*/
function getName(attribute) {
if (!attribute.directive) return attribute.key.name;
if (attribute.key.name.name === "bind") return attribute.key.argument && attribute.key.argument.type === "VIdentifier" && attribute.key.argument.name || null;
return null;
}
const rule$11 = createEslintRule({
name: RULE_NAME$5,
meta: {
type: "problem",
docs: {
category: "essentials",
description: "Disallow duplication of attributes"
},
schema: [{
type: "object",
properties: { directives: {
type: "string",
default: []
} },
additionalProperties: false
}],
messages: { [RULE_NAME$5]: "Duplicate attribute '{{name}}'." }
},
defaultOptions: [],
create(context) {
const directiveNames = /* @__PURE__ */ new Set();
const attributeNames = /* @__PURE__ */ new Set();
function isDuplicate(name, isDirective) {
if (name === "style" || name === "class") return isDirective ? directiveNames.has(name) : attributeNames.has(name);
return directiveNames.has(name) || attributeNames.has(name);
}
return {
VStartTag: () => {
directiveNames.clear();
attributeNames.clear();
},
VAttribute: (node) => {
const name = getName(node);
if (name == null) return;
if (isDuplicate(name, node.directive)) context.report({
node,
loc: node.loc,
messageId: RULE_NAME$5,
data: { name }
});
if (node.directive) directiveNames.add(name);
else attributeNames.add(name);
}
};
}
});
var no_dupe_attributes_default = rule$11;
//#endregion
//#region src/rules/essentials/no-dupe-else-if.ts
/**
* Splits the given node by the given logical operator.
* @param operator Logical operator `||` or `&&`.
* @param node The node to split.
* @returns Array of conditions that makes the node when joined by the operator.
*/
function splitByLogicalOperator(operator, node) {
if (node.type === "LogicalExpression" && node.operator === operator) return [...splitByLogicalOperator(operator, node.left), ...splitByLogicalOperator(operator, node.right)];
return [node];
}
function splitByOr(node) {
return splitByLogicalOperator("||", node);
}
function splitByAnd(node) {
return splitByLogicalOperator("&&", node);
}
function buildOrOperands(node) {
return {
node,
operands: splitByOr(node).map((orOperand) => {
return {
node: orOperand,
operands: splitByAnd(orOperand)
};
})
};
}
/**
* Determines whether the two given nodes are considered to be equal. In particular, given that the nodes
* represent expressions in a boolean context, `||` and `&&` can be considered as commutative operators.
* @param a First node.
* @param b Second node.
* @returns `true` if the nodes are considered to be equal.
*/
function equal(a, b, sourceCode) {
if (a.type !== b.type) return false;
if (a.type === "LogicalExpression" && b.type === "LogicalExpression" && (a.operator === "||" || a.operator === "&&") && a.operator === b.operator) return equal(a.left, b.left, sourceCode) && equal(a.right, b.right, sourceCode) || equal(a.left, b.right, sourceCode) && equal(a.right, b.left, sourceCode);
return equalTokens(a, b, sourceCode);
}
/**
* Determines whether the first given AndOperands is a subset of the second given AndOperands.
*
* e.g. A: (a && b), B: (a && b && c): B is a subset of A.
*
* @param operandsA The AndOperands to compare from.
* @param operandsB The AndOperands to compare against.
* @returns `true` if the `andOperandsA` is a subset of the `andOperandsB`.
*/
function isSubset(operandsA, operandsB, sourceCode) {
return operandsA.operands.every((operandA) => operandsB.operands.some((operandB) => equal(operandA, operandB, sourceCode)));
}
const RULE_NAME$4 = "no-dupe-else-if";
const rule$10 = createEslintRule({
name: RULE_NAME$4,
meta: {
type: "problem",
docs: {
category: "essentials",
description: "Disallow duplicate conditions in `v-if` / `v-else-if` chains"
},
hasSuggestions: true,
schema: [],
messages: { [RULE_NAME$4]: "This branch can never execute. Its condition is a duplicate or covered by previous conditions in the `v-if` / `v-else-if` chain." }
},
defaultOptions: [],
create(context) {
const { sourceCode } = context;
return { "VAttribute[directive=true][key.name.name='else-if']": (node) => {
if (!node.value || !node.value.expression) return;
const test = node.value.expression;
const listToCheck = (test.type === "LogicalExpression" && test.operator === "&&" ? [...splitByAnd(test), test] : [test]).map(buildOrOperands);
let current = node.parent.parent;
while (current) {
current = prevSibling(current);
if (!current) break;
const vIf = getDirective(current, "if");
const currentTestDir = vIf || getDirective(current, "else-if");
if (!currentTestDir) return;
if (currentTestDir.value && currentTestDir.value.expression) {
const currentOrOperands = buildOrOperands(currentTestDir.value.expression);
for (const condition of listToCheck) if ((condition.operands = condition.operands.filter((orOperand) => !currentOrOperands.operands.some((currentOrOperand) => isSubset(currentOrOperand, orOperand, sourceCode)))).length === 0) {
context.report({
node: condition.node,
messageId: RULE_NAME$4
});
return;
}
}
if (vIf) return;
}
} };
}
});
var no_dupe_else_if_default = rule$10;
//#endregion
//#region src/rules/essentials/no-lifecycle-hook-after-await.ts
const RULE_NAME$3 = "no-lifecycle-hook-after-await";
const LIFECYCLE_HOOKS = [
"onMounted",
"onBeforeMount",
"onUnmounted",
"onBeforeUnmount",
"onActivated",
"onDeactivated",
"onErrorCaptured",
"onRenderTracked",
"onRenderTriggered",
"onBeforeUpdate",
"onUpdated",
"onServerPrefetch"
];
const rule$9 = createEslintRule({
name: RULE_NAME$3,
meta: {
type: "problem",
docs: {
category: "essentials",
description: "Disallow lifecycle hooks after await expression"
},
schema: [],
messages: { [RULE_NAME$3]: "Lifecycle hooks should be registered synchronously before await expressions." }
},
defaultOptions: [],
create(context) {
return { "FunctionDeclaration[async=true], ArrowFunctionExpression[async=true], FunctionExpression[async=true]": (node) => {
if (notVineCompFn(node) || node.body.type !== "BlockStatement") return;
let awaitFound = false;
const lifecycleHooksAfterAwait = [];
function checkNode(node$1) {
if (!node$1) return;
if (node$1.type === "AwaitExpression") {
awaitFound = true;
return;
}
if (awaitFound && node$1.type === "CallExpression" && node$1.callee.type === "Identifier" && LIFECYCLE_HOOKS.includes(node$1.callee.name)) {
lifecycleHooksAfterAwait.push(node$1);
return;
}
if (node$1.body && Array.isArray(node$1.body)) node$1.body.forEach(checkNode);
else if (node$1.body) checkNode(node$1.body);
if (node$1.consequent) checkNode(node$1.consequent);
if (node$1.alternate) checkNode(node$1.alternate);
if (node$1.expression) checkNode(node$1.expression);
}
checkNode(node.body);
lifecycleHooksAfterAwait.forEach((hook) => {
context.report({
node: hook,
loc: hook.loc,
messageId: RULE_NAME$3
});
});
} };
}
});
var no_lifecycle_hook_after_await_default = rule$9;
//#endregion
//#region src/rules/essentials/no-v-for-key-on-child.ts
const RULE_NAME$2 = "no-v-for-key-on-child";
/**
* Check whether the given attribute is using the variables which are defined by `v-for` directives.
* @param {VDirective} vFor The attribute node of `v-for` to check.
* @param {VDirective} vBindKey The attribute node of `v-bind:key` to check.
* @returns {boolean} `true` if the node is using the variables which are defined by `v-for` directives.
*/
function isUsingIterationVar(vFor, vBindKey) {
if (vBindKey.value == null) return false;
const references = vBindKey.value.references;
const variables = vFor.parent.parent.variables;
return references.some((reference) => variables.some((variable) => variable.id.name === reference.id.name && variable.kind === "v-for"));
}
const rule$8 = createEslintRule({
name: RULE_NAME$2,
meta: {
type: "suggestion",
docs: {
category: "essentials",
description: "Disallow the key of the <template v-for> placed on the child elements."
},
schema: [],
messages: { [RULE_NAME$2]: "The key of the <template v-for> should be placed on the <template> tag." }
},
defaultOptions: [],
create(context) {
return { "VElement[name='template'] > VStartTag > VAttribute[directive=true][key.name.name='for']": (node) => {
const template = node.parent?.parent;
const vBindOnTemplate = getDirective(template, "bind", "key");
if (vBindOnTemplate && isUsingIterationVar(node, vBindOnTemplate)) return;
for (const child of template.children.filter(isVElement)) {
if (hasDirective(child, "if") || hasDirective(child, "else-if") || hasDirective(child, "else") || hasDirective(child, "for")) continue;
const vBindKeyOnChild = getDirective(child, "bind", "key");
if (vBindKeyOnChild && isUsingIterationVar(node, vBindKeyOnChild)) context.report({
node: vBindKeyOnChild,
loc: vBindKeyOnChild.loc,
messageId: RULE_NAME$2
});
}
} };
}
});
var no_v_for_key_on_child_default = rule$8;
//#endregion
//#region src/rules/format/format-html-self-closing.ts
const messageId$5 = "format-html-self-closing";
const disallowSelfClosingMessageId = "disallow-html-self-closing";
/**
* These strings wil be displayed in error messages.
*/
const ELEMENT_TYPE_MESSAGES = Object.freeze({
NORMAL: "HTML elements",
VOID: "HTML void elements",
COMPONENT: "Vue.js custom components",
SVG: "SVG elements",
MATH: "MathML elements",
UNKNOWN: "unknown elements"
});
/**
* Get the elementType of the given element.
* @param {VElement} node The element node to get.
* @returns {keyof Options} The elementType of the element.
*/
function getElementType(node) {
if (isCustomComponent(node)) return "COMPONENT";
if (isHtmlElementNode(node)) {
if (isHtmlVoidElementName(node.name)) return "VOID";
return "NORMAL";
}
if (isSvgElementNode(node)) return "SVG";
if (isMathElementNode(node)) return "MATH";
return "UNKNOWN";
}
function parseOptionToMode(option) {
return {
NORMAL: option.html.normal,
VOID: option.html.void,
COMPONENT: option.html.component,
SVG: option.svg,
MATH: option.math,
UNKNOWN: null
};
}
function isEmpty(node, sourceCode) {
const start = node.startTag.range[1];
const end = node.endTag == null ? node.range[1] : node.endTag.range[0];
return sourceCode.text.slice(start, end).trim() === "";
}
const rule$7 = createEslintRule({
name: messageId$5,
meta: {
type: "layout",
docs: {
description: "Enforce self-closing style for HTML elements and Vue components",
category: "format"
},
fixable: "code",
schema: [{
type: "object",
properties: {
html: {
type: "object",
properties: {
void: {
type: "string",
enum: ["never", "always"]
},
normal: {
type: "string",
enum: ["never", "always"]
},
component: {
type: "string",
enum: ["never", "always"]
}
}
},
svg: {
type: "string",
enum: ["always", "never"]
},
math: {
type: "string",
enum: ["always", "never"]
}
}
}],
messages: {
[messageId$5]: "Require self-closing on {{elementType}} (<{{name}}>).",
[disallowSelfClosingMessageId]: "Disallow self-closing on {{elementType}} (<{{name}}/>)."
}
},
defaultOptions: [{
html: {
void: "never",
normal: "always",
component: "always"
},
svg: "always",
math: "always"
}],
create(context) {
const sourceCode = context.sourceCode;
const options = context.options?.[0];
return { VElement: (node) => {
const elementType = getElementType(node);
const mode = parseOptionToMode(options)[elementType];
if (mode === "always" && !node.startTag.selfClosing && isEmpty(node, sourceCode)) context.report({
node,
loc: node.loc,
messageId: messageId$5,
data: {
elementType: ELEMENT_TYPE_MESSAGES[elementType],
name: node.rawName
},
fix: (fixer) => {
const startTag = node.startTag;
const endTag = node.endTag;
if (!startTag || !endTag) return [];
return [fixer.replaceText(startTag, context.sourceCode.getText(startTag).replace(">", "/>")), fixer.removeRange([startTag.range[1], endTag.range[1]])];
}
});
if (mode === "never" && node.startTag.selfClosing) context.report({
node,
loc: node.loc,
messageId: disallowSelfClosingMessageId,
data: {
elementType: ELEMENT_TYPE_MESSAGES[elementType],
name: node.rawName
}
});
} };
}
});
var format_html_self_closing_default = rule$7;
//#endregion
//#region src/rules/format/format-prefer-template.ts
const messageId$4 = "format-prefer-template";
const inTemplateMessageId = "format-prefer-template-inside-vine-template";
function isConcatingString(node) {
return node.left.type === "Literal" && typeof node.left.value === "string" || node.right.type === "Literal" && typeof node.right.value === "string" || node.left.type === "BinaryExpression" && isConcatingString(node.left) || node.right.type === "BinaryExpression" && isConcatingString(node.right);
}
function collectParts(context, node) {
if (node.type === "BinaryExpression" && node.operator === "+") return [...collectParts(context, node.left), ...collectParts(context, node.right)];
if (node.type === "Literal" && typeof node.value === "string") return [{
type: "string",
value: node.value,
raw: context.sourceCode.getText(node)
}];
const text = context.sourceCode.getText(node);
if (text.startsWith("`") && text.endsWith("`")) return [{
type: "string",
value: text.slice(1, -1),
raw: text
}];
return [{
type: "expression",
value: text
}];
}
const rule$6 = createEslintRule({
name: messageId$4,
meta: {
type: "problem",
docs: {
category: "format",
description: "Require template literals instead of string concatenation."
},
fixable: "code",
schema: [{
type: "object",
properties: { allowInTemplate: {
type: "boolean",
default: false
} }
}],
messages: {
[messageId$4]: "Unexpected string concatenation. Please use template literals.",
[inTemplateMessageId]: "Not recommend string concatenation in vine template. Please extract it to a variable or computed."
}
},
defaultOptions: [{ allowInTemplate: false }],
create(context) {
return {
"VTemplateRoot BinaryExpression": (node) => {
if (node.operator !== "+" || !isConcatingString(node)) return;
if (context.options[0]?.allowInTemplate ?? false) return;
context.report({
node,
messageId: inTemplateMessageId
});
},
"BinaryExpression:not(VTemplateRoot BinaryExpression) ": (node) => {
if (node.operator !== "+" || !isConcatingString(node) || node.parent?._isReportedPreferTemplate) return;
context.report({
node,
messageId: messageId$4,
fix(fixer) {
const result = collectParts(context, node).map((part) => {
if (part.type === "string") {
if (part.raw?.startsWith("`") && part.raw?.endsWith("`")) return part.value;
return part.value;
}
return `\${${part.value}}`;
}).join("");
return fixer.replaceText(node, `\`${result}\``);
}
});
node._isReportedPreferTemplate = true;
}
};
}
});
var format_prefer_template_default = rule$6;
//#endregion
//#region src/rules/format/format-vine-component-name.ts
const RULE_NAME$1 = "format-vine-component-name";
const CONFLICT_WITH_HTML_BUILT_IN = "format-vine-component-name-conflict-with-html-built-in";
const NOT_PASCAL_CASE = "format-vine-component-name-not-pascal-case";
const CONFLICT_WITH_HTML_BUILT_IN_MSG = "Vue Vine component function name must not conflict with HTML built-in tag names";
const NOT_PASCAL_CASE_MSG = "Vue Vine component function name must be in PascalCase";
const HTML_BUILT_IN_ELEMENTS = [
"a",
"abbr",
"address",
"area",
"article",
"aside",
"audio",
"b",
"base",
"bdi",
"bdo",
"blockquote",
"body",
"br",
"button",
"canvas",
"caption",
"cite",
"code",
"col",
"colgroup",
"data",
"datalist",
"dd",
"del",
"details",
"dfn",
"dialog",
"div",
"dl",
"dt",
"em",
"embed",
"fieldset",
"figcaption",
"figure",
"footer",
"form",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"head",
"header",
"hgroup",
"hr",
"html",
"i",
"iframe",
"img",
"input",
"ins",
"kbd",
"label",
"legend",
"li",
"link",
"main",
"map",
"mark",
"meta",
"meter",
"nav",
"noscript",
"object",
"ol",
"optgroup",
"option",
"output",
"p",
"picture",
"pre",
"progress",
"q",
"rp",
"rt",
"ruby",
"s",
"samp",
"script",
"section",
"select",
"slot",
"small",
"source",
"span",
"strong",
"style",
"sub",
"summary",
"sup",
"table",
"tbody",
"td",
"template",
"textarea",
"tfoot",
"th",
"thead",
"time",
"title",
"tr",
"track",
"u",
"ul",
"var",
"video",
"wbr"
];
const rule$5 = createEslintRule({
name: RULE_NAME$1,
meta: {
type: "suggestion",
docs: {
category: "format",
description: "Enforce Vue Vine component function name format"
},
fixable: "whitespace",
schema: [],
messages: {
[CONFLICT_WITH_HTML_BUILT_IN]: CONFLICT_WITH_HTML_BUILT_IN_MSG,
[NOT_PASCAL_CASE]: NOT_PASCAL_CASE_MSG
}
},
defaultOptions: [],
create(context) {
return { "FunctionDeclaration, FunctionExpression, ArrowFunctionExpression": (node) => {
if (notVineCompFn(node)) return;
const fnNameIdentifier = node.id;
if (!fnNameIdentifier || fnNameIdentifier.type !== "Identifier") return;
const fnName = fnNameIdentifier.name;
if (HTML_BUILT_IN_ELEMENTS.includes(fnName)) context.report({
node: fnNameIdentifier,
messageId: CONFLICT_WITH_HTML_BUILT_IN
});
if (!checkPascalCase(fnName)) context.report({
node: fnNameIdentifier,
messageId: NOT_PASCAL_CASE,
fix: (fixer) => {
const fixedName = fnName[0].toUpperCase() + fnName.slice(1);
return fixer.replaceText(fnNameIdentifier, fixedName);
}
});
} };
}
});
var format_vine_component_name_default = rule$5;
//#endregion
//#region ../../node_modules/.pnpm/@typescript-eslint+types@8.35.1/node_modules/@typescript-eslint/types/dist/generated/ast-spec.js
var require_ast_spec = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@typescript-eslint+types@8.35.1/node_modules/@typescript-eslint/types/dist/generated/ast-spec.js": ((exports) => {
/**********************************************
* DO NOT MODIFY THIS FILE MANUALLY *
* *
* THIS FILE HAS BEEN COPIED FROM ast-spec. *
* ANY CHANGES WILL BE LOST ON THE NEXT BUILD *
* *
* MAKE CHANGES TO ast-spec AND THEN RUN *
* yarn build *
**********************************************/
Object.defineProperty(exports, "__esModule", { value: true });
var AST_NODE_TYPES$1;
(function(AST_NODE_TYPES$2) {
AST_NODE_TYPES$2["AccessorProperty"] = "AccessorProperty";
AST_NODE_TYPES$2["ArrayExpression"] = "ArrayExpression";
AST_NODE_TYPES$2["ArrayPattern"] = "ArrayPattern";
AST_NODE_TYPES$2["ArrowFunctionExpression"] = "ArrowFunctionExpression";
AST_NODE_TYPES$2["AssignmentExpression"] = "AssignmentExpression";
AST_NODE_TYPES$2["AssignmentPattern"] = "AssignmentPattern";
AST_NODE_TYPES$2["AwaitExpression"] = "AwaitExpression";
AST_NODE_TYPES$2["BinaryExpression"] = "BinaryExpression";
AST_NODE_TYPES$2["BlockStatement"] = "BlockStatement";
AST_NODE_TYPES$2["BreakStatement"] = "BreakStatement";
AST_NODE_TYPES$2["CallExpression"] = "CallExpression";
AST_NODE_TYPES$2["CatchClause"] = "CatchClause";
AST_NODE_TYPES$2["ChainExpression"] = "ChainExpression";
AST_NODE_TYPES$2["ClassBody"] = "ClassBody";
AST_NODE_TYPES$2["ClassDeclaration"] = "ClassDeclaration";
AST_NODE_TYPES$2["ClassExpression"] = "ClassExpression";
AST_NODE_TYPES$2["ConditionalExpression"] = "ConditionalExpression";
AST_NODE_TYPES$2["ContinueStatement"] = "ContinueStatement";
AST_NODE_TYPES$2["DebuggerStatement"] = "DebuggerStatement";
AST_NODE_TYPES$2["Decorator"] = "Decorator";
AST_NODE_TYPES$2["DoWhileStatement"] = "DoWhileStatement";
AST_NODE_TYPES$2["EmptyStatement"] = "EmptyStatement";
AST_NODE_TYPES$2["ExportAllDeclaration"] = "ExportAllDeclaration";
AST_NODE_TYPES$2["ExportDefaultDeclaration"] = "ExportDefaultDeclaration";
AST_NODE_TYPES$2["ExportNamedDeclaration"] = "ExportNamedDeclaration";
AST_NODE_TYPES$2["ExportSpecifier"] = "ExportSpecifier";
AST_NODE_TYPES$2["ExpressionStatement"] = "ExpressionStatement";
AST_NODE_TYPES$2["ForInStatement"] = "ForInStatement";
AST_NODE_TYPES$2["ForOfStatement"] = "ForOfStatement";
AST_NODE_TYPES$2["ForStatement"] = "ForStatement";
AST_NODE_TYPES$2["FunctionDeclaration"] = "FunctionDeclaration";
AST_NODE_TYPES$2["FunctionExpression"] = "FunctionExpression";
AST_NODE_TYPES$2["Identifier"] = "Identifier";
AST_NODE_TYPES$2["IfStatement"] = "IfStatement";
AST_NODE_TYPES$2["ImportAttribute"] = "ImportAttribute";
AST_NODE_TYPES$2["ImportDeclaration"] = "ImportDeclaration";
AST_NODE_TYPES$2["ImportDefaultSpecifier"] = "ImportDefaultSpecifier";
AST_NODE_TYPES$2["ImportExpression"] = "ImportExpression";
AST_NODE_TYPES$2["ImportNamespaceSpecifier"] = "ImportNamespaceSpecifier";
AST_NODE_TYPES$2["ImportSpecifier"] = "ImportSpecifier";
AST_NODE_TYPES$2["JSXAttribute"] = "JSXAttribute";
AST_NODE_TYPES$2["JSXClosingElement"] = "JSXClosingElement";
AST_NODE_TYPES$2["JSXClosingFragment"] = "JSXClosingFragment";
AST_NODE_TYPES$2["JSXElement"] = "JSXElement";
AST_NODE_TYPES$2["JSXEmptyExpression"] = "JSXEmptyExpression";
AST_NODE_TYPES$2["JSXExpressionContainer"] = "JSXExpressionContainer";
AST_NODE_TYPES$2["JSXFragment"] = "JSXFragment";
AST_NODE_TYPES$2["JSXIdentifier"] = "JSXIdentifier";
AST_NODE_TYPES$2["JSXMemberExpression"] = "JSXMemberExpression";
AST_NODE_TYPES$2["JSXNamespacedName"] = "JSXNamespacedName";
AST_NODE_TYPES$2["JSXOpeningElement"] = "JSXOpeningElement";
AST_NODE_TYPES$2["JSXOpeningFragment"] = "JSXOpeningFragment";
AST_NODE_TYPES$2["JSXSpreadAttribute"] = "JSXSpreadAttribute";
AST_NODE_TYPES$2["JSXSpreadChild"] = "JSXSpreadChild";
AST_NODE_TYPES$2["JSXText"] = "JSXText";
AST_NODE_TYPES$2["LabeledStatement"] = "LabeledStatement";
AST_NODE_TYPES$2["Literal"] = "Literal";
AST_NODE_TYPES$2["LogicalExpression"] = "LogicalExpression";
AST_NODE_TYPES$2["MemberExpression"] = "MemberExpression";
AST_NODE_TYPES$2["MetaProperty"] = "MetaProperty";
AST_NODE_TYPES$2["MethodDefinition"] = "MethodDefinition";
AST_NODE_TYPES$2["NewExpression"] = "NewExpression";
AST_NODE_TYPES$2["ObjectExpression"] = "ObjectExpression";
AST_NODE_TYPES$2["ObjectPattern"] = "ObjectPattern";
AST_NODE_TYPES$2["PrivateIdentifier"] = "PrivateIdentifier";
AST_NODE_TYPES$2["Program"] = "Program";
AST_NODE_TYPES$2["Property"] = "Property";
AST_NODE_TYPES$2["PropertyDefinition"] = "PropertyDefinition";
AST_NODE_TYPES$2["RestElement"] = "RestElement";
AST_NODE_TYPES$2["ReturnStatement"] = "ReturnStatement";
AST_NODE_TYPES$2["SequenceExpression"] = "SequenceExpression";
AST_NODE_TYPES$2["SpreadElement"] = "SpreadElement";
AST_NODE_TYPES$2["StaticBlock"] = "StaticBlock";
AST_NODE_TYPES$2["Super"] = "Super";
AST_NODE_TYPES$2["SwitchCase"] = "SwitchCase";
AST_NODE_TYPES$2["SwitchStatement"] = "SwitchStatement";
AST_NODE_TYPES$2["TaggedTemplateExpression"] = "TaggedTemplateExpression";
AST_NODE_TYPES$2["TemplateElement"] = "TemplateElement";
AST_NODE_TYPES$2["TemplateLiteral"] = "TemplateLiteral";
AST_NODE_TYPES$2["ThisExpression"] = "ThisExpression";
AST_NODE_TYPES$2["ThrowStatement"] = "ThrowStatement";
AST_NODE_TYPES$2["TryStatement"] = "TryStatement";
AST_NODE_TYPES$2["UnaryExpression"] = "UnaryExpression";
AST_NODE_TYPES$2["UpdateExpression"] = "UpdateExpression";
AST_NODE_TYPES$2["VariableDeclaration"] = "VariableDeclaration";
AST_NODE_TYPES$2["VariableDeclarator"] = "VariableDeclarator";
AST_NODE_TYPES$2["WhileStatement"] = "WhileStatement";
AST_NODE_TYPES$2["WithStatement"] = "WithStatement";
AST_NODE_TYPES$2["YieldExpression"] = "YieldExpression";
AST_NODE_TYPES$2["TSAbstractAccessorProperty"] = "TSAbstractAccessorProperty";
AST_NODE_TYPES$2["TSAbstractKeyword"] = "TSAbstractKeyword";
AST_NODE_TYPES$2["TSAbstractMethodDefinition"] = "TSAbstractMethodDefinition";
AST_NODE_TYPES$2["TSAbstractPropertyDefinition"] = "TSAbstractPropertyDefinition";
AST_NODE_TYPES$2["TSAnyKeyword"] = "TSAnyKeyword";
AST_NODE_TYPES$2["TSArrayType"] = "TSArrayType";
AST_NODE_TYPES$2["TSAsExpression"] = "TSAsExpression";
AST_NODE_TYPES$2["TSAsyncKeyword"] = "TSAsyncKeyword";
AST_NODE_TYPES$2["TSBigIntKeyword"] = "TSBigIntKeyword";
AST_NODE_TYPES$2["TSBooleanKeyword"] = "TSBooleanKeyword";
AST_NODE_TYPES$2["TSCallSignatureDeclaration"] = "TSCallSignatureDeclaration";
AST_NODE_TYPES$2["TSClassImplements"] = "TSClassImplements";
AST_NODE_TYPES$2["TSConditionalType"] = "TSConditionalType";
AST_NODE_TYPES$2["TSConstructorType"] = "TSConstructorType";
AST_NODE_TYPES$2["TSConstructSignatureDeclaration"] = "TSConstructSignatureDeclaration";
AST_NODE_TYPES$2["TSDeclareFunction"] = "TSDeclareFunction";
AST_NODE_TYPES$2["TSDeclareKeyword"] = "TSDeclareKeyword";
AST_NODE_TYPES$2["TSEmptyBodyFunctionExpression"] = "TSEmptyBodyFunctionExpression";
AST_NODE_TYPES$2["TSEnumBody"] = "TSEnumBody";
AST_NODE_TYPES$2["TSEnumDeclaration"] = "TSEnumDeclaration";
AST_NODE_TYPES$2["TSEnumMember"] = "TSEnumMember";
AST_NODE_TYPES$2["TSExportAssignment"] = "TSExportAssignment";
AST_NODE_TYPES$2["TSExportKeyword"] = "TSExportKeyword";
AST_NODE_TYPES$2["TSExternalModuleReference"] = "TSExternalModuleReference";
AST_NODE_TYPES$2["TSFunctionType"] = "TSFunctionType";
AST_NODE_TYPES$2["TSImportEqualsDeclaration"] = "TSImportEqualsDeclaration";
AST_NODE_TYPES$2["TSImportType"] = "TSImportType";
AST_NODE_TYPES$2["TSIndexedAccessType"] = "TSIndexedAccessType";
AST_NODE_TYPES$2["TSIndexSignature"] = "TSIndexSignature";
AST_NODE_TYPES$2["TSInferType"] = "TSInferType";
AST_NODE_TYPES$2["TSInstantiationExpression"] = "TSInstantiationExpression";
AST_NODE_TYPES$2["TSInterfaceBody"] = "TSInterfaceBody";
AST_NODE_TYPES$2["TSInterfaceDeclaration"] = "TSInterfaceDeclaration";
AST_NODE_TYPES$2["TSInterfaceHeritage"] = "TSInterfaceHeritage";
AST_NODE_TYPES$2["TSIntersectionType"] = "TSIntersectionType";
AST_NODE_TYPES$2["TSIntrinsicKeyword"] = "TSIntrinsicKeyword";
AST_NODE_TYPES$2["TSLiteralType"] = "TSLiteralType";
AST_NODE_TYPES$2["TSMappedType"] = "TSMappedType";
AST_NODE_TYPES$2["TSMethodSignature"] = "TSMethodSignature";
AST_NODE_TYPES$2["TSModuleBlock"] = "TSModuleBlock";
AST_NODE_TYPES$2["TSModuleDeclaration"] = "TSModuleDeclaration";
AST_NODE_TYPES$2["TSNamedTupleMember"] = "TSNamedTupleMember";
AST_NODE_TYPES$2["TSNamespaceExportDeclaration"] = "TSNamespaceExportDeclaration";
AST_NODE_TYPES$2["TSNeverKeyword"] = "TSNeverKeyword";
AST_NODE_TYPES$2["TSNonNullExpression"] = "TSNonNullExpression";
AST_NODE_TYPES$2["TSNullKeyword"] = "TSNullKeyword";
AST_NODE_TYPES$2["TSNumberKeyword"] = "TSNumberKeyword";
AST_NODE_TYPES$2["TSObjectKeyword"] = "TSObjectKeyword";
AST_NODE_TYPES$2["TSOptionalType"] = "TSOptionalType";
AST_NODE_TYPES$2["TSParameterProperty"] = "TSParameterProperty";
AST_NODE_TYPES$2["TSPrivateKeyword"] = "TSPrivateKeyword";
AST_NODE_TYPES$2["TSPropertySignature"] = "TSPropertySignature";
AST_NODE_TYPES$2["TSProtectedKeyword"] = "TSProtectedKeyword";
AST_NODE_TYPES$2["TSPublicKeyword"] = "TSPublicKeyword";
AST_NODE_TYPES$2["TSQualifiedName"] = "TSQualifiedName";
AST_NODE_TYPES$2["TSReadonlyKeyword"] = "TSReadonlyKeyword";
AST_NODE_TYPES$2["TSRestType"] = "TSRestType";
AST_NODE_TYPES$2["TSSatisfiesExpression"] = "TSSatisfiesExpression";
AST_NODE_TYPES$2["TSStaticKeyword"] = "TSStaticKeyword";
AST_NODE_TYPES$2["TSStringKeyword"] = "TSStringKeyword";
AST_NODE_TYPES$2["TSSymbolKeyword"] = "TSSymbolKeyword";
AST_NODE_TYPES$2["TSTemplateLiteralType"] = "TSTemplateLiteralType";
AST_NODE_TYPES$2["TSThisType"] = "TSThisType";
AST_NODE_TYPES$2["TSTupleType"] = "TSTupleType";
AST_NODE_TYPES$2["TSTypeAliasDeclaration"] = "TSTypeAliasDeclaration";
AST_NODE_TYPES$2["TSTypeAnnotation"] = "TSTypeAnnotation";
AST_NODE_TYPES$2["TSTypeAssertion"] = "TSTypeAssertion";
AST_NODE_TYPES$2["TSTypeLiteral"] = "TSTypeLiteral";
AST_NODE_TYPES$2["TSTypeOperator"] = "TSTypeOperator";
AST_NODE_TYPES$2["TSTypeParameter"] = "TSTypeParameter";
AST_NODE_TYPES$2["TSTypeParameterDeclaration"] = "TSTypeParameterDeclaration";
AST_NODE_TYPES$2["TSTypeParameterInstantiation"] = "TSTypeParameterInstantiation";
AST_NODE_TYPES$2["TSTypePredicate"] = "TSTypePredicate";
AST_NODE_TYPES$2["TSTypeQuery"] = "TSTypeQuery";
AST_NODE_TYPES$2["TSTypeReference"] = "TSTypeReference";
AST_NODE_TYPES$2["TSUndefinedKeyword"] = "TSUndefinedKeyword";
AST_NODE_TYPES$2["TSUnionType"] = "TSUnionType";
AST_NODE_TYPES$2["TSUnknownKeyword"] = "TSUnknownKeyword";
AST_NODE_TYPES$2["TSVoidKeyword"] = "TSVoidKeyword";
})(AST_NODE_TYPES$1 || (exports.AST_NODE_TYPES = AST_NODE_TYPES$1 = {}));
var AST_TOKEN_TYPES;
(function(AST_TOKEN_TYPES$1) {
AST_TOKEN_TYPES$1["Boolean"] = "Boolean";
AST_TOKEN_TYPES$1["Identifier"] = "Identifier";
AST_TOKEN_TYPES$1["JSXIdentifier"] = "JSXIdentifier";
AST_TOKEN_TYPES$1["PrivateIdentifier"] = "PrivateIdentifier";
AST_TOKEN_TYPES$1["JSXText"] = "JSXText";
AST_TOKEN_TYPES$1["Keyword"] = "Keyword";
AST_TOKEN_TYPES$1["Null"] = "Null";
AST_TOKEN_TYPES$1["Numeric"] = "Numeric";
AST_TOKEN_TYPES$1["Punctuator"] = "Punctuator";
AST_TOKEN_TYPES$1["RegularExpression"] = "RegularExpression";
AST_TOKEN_TYPES$1["String"] = "String";
AST_TOKEN_TYPES$1["Template"] = "Template";
AST_TOKEN_TYPES$1["Block"] = "Block";
AST_TOKEN_TYPES$1["Line"] = "Line";
})(AST_TOKEN_TYPES || (exports.AST_TOKEN_TYPES = AST_TOKEN_TYPES = {}));
}) });
//#endregion
//#region ../../node_modules/.pnpm/@typescript-eslint+types@8.35.1/node_modules/@typescript-eslint/types/dist/lib.js
var require_lib = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@typescript-eslint+types@8.35.1/node_modules/@typescript-eslint/types/dist/lib.js": ((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
}) });
//#endregion
//#region ../../node_modules/.pnpm/@typescript-eslint+types@8.35.1/node_modules/@typescript-eslint/types/dist/parser-options.js
var require_parser_options = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@typescript-eslint+types@8.35.1/node_modules/@typescript-eslint/types/dist/parser-options.js": ((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
}) });
//#endregion
//#region ../../node_modules/.pnpm/@typescript-eslint+types@8.35.1/node_modules/@typescript-eslint/types/dist/ts-estree.js
var require_ts_estree = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@typescript-eslint+types@8.35.1/node_modules/@typescript-eslint/types/dist/ts-estree.js": ((exports) => {
var __createBinding$1 = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
if (k2 === void 0) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) desc = {
enumerable: true,
get: function() {
return m[k];
}
};
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === void 0) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", {
enumerable: true,
value: v
});
}) : function(o, v) {
o["default"] = v;
});
var __importStar = exports && exports.__importStar || (function() {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function(o$1) {
var ar = [];
for (var k in o$1) if (Object.prototype.hasOwnProperty.call(o$1, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function(mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) {
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding$1(result, mod, k[i]);
}
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.TSESTree = __importStar(require_ast_spec());
}) });
//#endregion
//#region ../../node_modules/.pnpm/@typescript-eslint+types@8.35.1/node_modules/@typescript-eslint/types/dist/index.js
var require_dist = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/@typescript-eslint+types@8.35.1/node_modules/@typescript-eslint/types/dist/index.js": ((exports) => {
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
if (k2 === void 0) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) desc = {
enumerable: true,
get: function() {
return m[k];
}
};
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === void 0) k2 = k;
o[k2] = m[k];
}));
var __exportStar = exports && exports.__exportStar || function(m, exports$1) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$1, p)) __createBinding(exports$1, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AST_TOKEN_TYPES = exports.AST_NODE_TYPES = void 0;
var ast_spec_1 = require_ast_spec();
Object.defineProperty(exports, "AST_NODE_TYPES", {
enumerable: true,
get: function() {
return ast_spec_1.AST_NODE_TYPES;
}
});
Object.defineProperty(exports, "AST_TOKEN_TYPES", {
enumerable: true,
get: function() {
return ast_spec_1.AST_TOKEN_TYPES;
}
});
__exportStar(require_lib(), exports);
__exportStar(require_parser_options(), exports);
__exportStar(require_ts_estree(), exports);
}) });
//#endregion
//#region src/rules/format/format-vine-emits-camel-case.ts
var import_dist$1 = /* @__PURE__ */ __toESM(require_dist(), 1);
const RULE_NAME = "format-vine-emits-camel-case";
const MESSAGE_ID = "preferCamelCase";
const CASE_REGEXP = /^[a-z][a-z0-9]*$/i;
/**
* Check if a string is in camelCase or PascalCase format.
* camelCase: starts with lowercase letter, e.g., 'clickTest', 'onChange'
* PascalCase: starts with uppercase letter, e.g., 'ClickTest', 'OnChange'
*/
function isCamelOrPascalCase(str) {
return CASE_REGEXP.test(str);
}
const rule$4 = createEslintRule({
name: RULE_NAME,
meta: {
type: "suggestion",
docs: {
category: "format",
description: "Recommend using camelCase for vineEmits event names to improve language service support"
},
schema: [],
messages: { [MESSAGE_ID]: "Event name \"{{eventName}}\" should be camelCase (e.g., \"{{suggestedName}}\") for better language service linking and navigation support." }
},
defaultOptions: [],
create(context) {
return { "FunctionDeclaration, FunctionExpression, ArrowFunctionExpression": (node) => {
if (notVineCompFn(node) || node.body.type !== import_dist$1.AST_NODE_TYPES.BlockStatement) return;
const bodyStatements = node.body.body;
for (const statement of bodyStatements) if (statement.type === import_dist$1.AST_NODE_TYPES.VariableDeclaration && statement.declarations[0]?.init?.type === import_dist$1.AST_NODE_TYPES.CallExpression) checkVineEmitsCall(statement.declarations[0].init);
else if (statement.type === import_dist$1.AST_NODE_TYPES.ExpressionStatement && statement.expression.type === import_dist$1.AST_NODE_TYPES.CallExpression) checkVineEmitsCall(statement.expression);
function checkVineEmitsCall(callExpr) {
if (callExpr.callee.type !== import_dist$1.AST_NODE_TYPES.Identifier || callExpr.callee.name !== "vineEmits") return;
const typeParams = callExpr.typeArguments;
if (!typeParams || typeParams.params.length === 0) return;
const typeArg = typeParams.params[0];
if (typeArg.type !== import_dist$1.AST_NODE_TYPES.TSTypeLiteral) return;
for (const member of typeArg.members) {
if (member.type !== import_dist$1.AST_NODE_TYPES.TSPropertySignature) continue;
let eventName = null;
let keyNode = member.key;
if (member.key.type === import_dist$1.AST_NODE_TYPES.Identifier) eventName = member.key.name;
else if (member.key.type === import_dist$1.AST_NODE_TYPES.Literal && typeof member.key.value === "string") {
eventName = member.key.value;
keyNode = member.key;
}
if (eventName && !isCamelOrPascalCase(eventName)) context.report({
node: keyNode,
messageId: MESSAGE_ID,
data: {
eventName,
suggestedName: toCamelCase(eventName)
}
});
}
}
} };
}
});
/**
* Convert a string to camelCase format.
* Handles kebab-case, snake_case, and PascalCase.
*/
function toCamelCase(str) {
if (str.includes("-") || str.includes("_")) return str.split(/[-_]/).map((part, index) => index === 0 ? part.toLowerCase() : part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
if (/^[A-Z]/.test(str)) return str.charAt(0).toLowerCase() + str.slice(1);
return str;
}
var format_vine_emits_camel_case_default = rule$4;
//#endregion
//#region src/rules/format/format-vine-expose-at-tail.ts
const messageId$3 = "format-vine-expose-at-tail ";
const rule$3 = createEslintRule({
name: messageId$3,
meta: {
type: "suggestion",
docs: {
category: "format",
description: "Enforce `vineExpose` to be at the tail of the component function body."
},
fixable: "code",
schema: [],
messages: { [messageId$3]: "`vineExpose` should be at the tail of the component function body." }
},
defaultOptions: [],
create(context) {
return { "FunctionDeclaration, FunctionExpression, ArrowFunctionExpression": (node) => {
if (notVineCompFn(node) || node.body.type !== "BlockStatement") return;
const bodyStatements = node.body.body.filter((stmt) => stmt.type !== "ReturnStatement");
const vineExposeIndex = bodyStateme