Files
SnowLuma/.pnpm-store/v11/files/ce/dabe522493d5da17a492e76c2478aa52a6717bf684d6dcef540115fa926fd6246a6c0c0ddd75f5c537427dd3ccc63929addd7172373b72b973c4585a93e5ef
TanTan 2a69b23b47
Dev Build / cleanup (push) Canceled after 0s
Dev Build / typecheck (push) Canceled after 0s
Dev Build / build (linux-arm64, ubuntu-24.04-arm, linux-arm64) (push) Canceled after 0s
Dev Build / build (linux-x64, ubuntu-latest, linux-x64) (push) Canceled after 0s
Dev Build / build (win-x64, windows-latest, win32-x64) (push) Canceled after 0s
Dev Build / dispatch-dev-docker (push) Skipped
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

268 lines
8.3 KiB
Plaintext

import { K as isSingleLine, M as getTokenBeforeClosingBracket, f as createRule, g as import_ast_utils } from "../utils.js";
function validateClosingSlash(context, node, option) {
const sourceCode = context.sourceCode;
let adjacent;
if ("selfClosing" in node && node.selfClosing) {
const lastTokens = sourceCode.getLastTokens(node, 2);
adjacent = !sourceCode.isSpaceBetween(lastTokens[0], lastTokens[1]);
if (option === "never") {
if (!adjacent) context.report({
node,
messageId: "selfCloseSlashNoSpace",
loc: {
start: lastTokens[0].loc.start,
end: lastTokens[1].loc.end
},
fix(fixer) {
return fixer.removeRange([lastTokens[0].range[1], lastTokens[1].range[0]]);
}
});
} else if (option === "always" && adjacent) context.report({
node,
messageId: "selfCloseSlashNeedSpace",
loc: {
start: lastTokens[0].loc.start,
end: lastTokens[1].loc.end
},
fix(fixer) {
return fixer.insertTextBefore(lastTokens[1], " ");
}
});
} else {
const firstTokens = sourceCode.getFirstTokens(node, 2);
adjacent = !sourceCode.isSpaceBetween(firstTokens[0], firstTokens[1]);
if (option === "never") {
if (!adjacent) context.report({
node,
messageId: "closeSlashNoSpace",
loc: {
start: firstTokens[0].loc.start,
end: firstTokens[1].loc.end
},
fix(fixer) {
return fixer.removeRange([firstTokens[0].range[1], firstTokens[1].range[0]]);
}
});
} else if (option === "always" && adjacent) context.report({
node,
messageId: "closeSlashNeedSpace",
loc: {
start: firstTokens[0].loc.start,
end: firstTokens[1].loc.end
},
fix(fixer) {
return fixer.insertTextBefore(firstTokens[1], " ");
}
});
}
}
function validateBeforeSelfClosing(context, node, option) {
const sourceCode = context.sourceCode;
const leftToken = getTokenBeforeClosingBracket(node);
const closingSlash = sourceCode.getTokenAfter(leftToken);
if (!isSingleLine(node) && option === "proportional-always") {
if ((0, import_ast_utils.isTokenOnSameLine)(leftToken, closingSlash)) {
context.report({
node,
messageId: "beforeSelfCloseNeedNewline",
loc: leftToken.loc.end,
fix(fixer) {
return fixer.insertTextBefore(closingSlash, "\n");
}
});
return;
}
}
if (!(0, import_ast_utils.isTokenOnSameLine)(leftToken, closingSlash)) return;
const adjacent = !sourceCode.isSpaceBetween(leftToken, closingSlash);
if ((option === "always" || option === "proportional-always") && adjacent) context.report({
node,
messageId: "beforeSelfCloseNeedSpace",
loc: closingSlash.loc.start,
fix(fixer) {
return fixer.insertTextBefore(closingSlash, " ");
}
});
else if (option === "never" && !adjacent) context.report({
node,
messageId: "beforeSelfCloseNoSpace",
loc: closingSlash.loc.start,
fix(fixer) {
const previousToken = sourceCode.getTokenBefore(closingSlash);
return fixer.removeRange([previousToken.range[1], closingSlash.range[0]]);
}
});
}
function validateAfterOpening(context, node, option) {
const sourceCode = context.sourceCode;
const openingToken = sourceCode.getTokenBefore(node.name);
if (option === "allow-multiline") {
if (openingToken.loc.start.line !== node.name.loc.start.line) return;
}
const adjacent = !sourceCode.isSpaceBetween(openingToken, node.name);
if (option === "never" || option === "allow-multiline") {
if (!adjacent) context.report({
node,
messageId: "afterOpenNoSpace",
loc: {
start: openingToken.loc.start,
end: node.name.loc.start
},
fix(fixer) {
return fixer.removeRange([openingToken.range[1], node.name.range[0]]);
}
});
} else if (option === "always" && adjacent) context.report({
node,
messageId: "afterOpenNeedSpace",
loc: {
start: openingToken.loc.start,
end: node.name.loc.start
},
fix(fixer) {
return fixer.insertTextBefore(node.name, " ");
}
});
}
function validateBeforeClosing(context, node, option) {
if (!("selfClosing" in node && node.selfClosing)) {
const sourceCode = context.sourceCode;
const leftToken = option === "proportional-always" ? getTokenBeforeClosingBracket(node) : sourceCode.getLastTokens(node, 2)[0];
const closingToken = sourceCode.getTokenAfter(leftToken);
if (!isSingleLine(node) && option === "proportional-always") {
if ((0, import_ast_utils.isTokenOnSameLine)(leftToken, closingToken)) {
context.report({
node,
messageId: "beforeCloseNeedNewline",
loc: leftToken.loc.end,
fix(fixer) {
return fixer.insertTextBefore(closingToken, "\n");
}
});
return;
}
}
if (leftToken.loc.start.line !== closingToken.loc.start.line) return;
const adjacent = !sourceCode.isSpaceBetween(leftToken, closingToken);
if (option === "never" && !adjacent) context.report({
node,
messageId: "beforeCloseNoSpace",
loc: {
start: leftToken.loc.end,
end: closingToken.loc.start
},
fix(fixer) {
return fixer.removeRange([leftToken.range[1], closingToken.range[0]]);
}
});
else if (option === "always" && adjacent) context.report({
node,
loc: {
start: leftToken.loc.end,
end: closingToken.loc.start
},
messageId: "beforeCloseNeedSpace",
fix(fixer) {
return fixer.insertTextBefore(closingToken, " ");
}
});
else if (option === "proportional-always" && node.type === "JSXOpeningElement" && adjacent !== isSingleLine(node)) context.report({
node,
messageId: "beforeCloseNeedSpace",
loc: {
start: leftToken.loc.end,
end: closingToken.loc.start
},
fix(fixer) {
return fixer.insertTextBefore(closingToken, " ");
}
});
}
}
var jsx_tag_spacing_default = createRule({
name: "jsx-tag-spacing",
meta: {
type: "layout",
docs: { description: "Enforce whitespace in and around the JSX opening and closing brackets" },
fixable: "whitespace",
schema: [{
type: "object",
properties: {
closingSlash: {
type: "string",
enum: [
"always",
"never",
"allow"
]
},
beforeSelfClosing: {
type: "string",
enum: [
"always",
"proportional-always",
"never",
"allow"
]
},
afterOpening: {
type: "string",
enum: [
"always",
"allow-multiline",
"never",
"allow"
]
},
beforeClosing: {
type: "string",
enum: [
"always",
"proportional-always",
"never",
"allow"
]
}
},
additionalProperties: false
}],
defaultOptions: [{
closingSlash: "never",
beforeSelfClosing: "always",
afterOpening: "never",
beforeClosing: "allow"
}],
messages: {
selfCloseSlashNoSpace: "Whitespace is forbidden between `/` and `>`; write `/>`",
selfCloseSlashNeedSpace: "Whitespace is required between `/` and `>`; write `/ >`",
closeSlashNoSpace: "Whitespace is forbidden between `<` and `/`; write `</`",
closeSlashNeedSpace: "Whitespace is required between `<` and `/`; write `< /`",
beforeSelfCloseNoSpace: "A space is forbidden before closing bracket",
beforeSelfCloseNeedSpace: "A space is required before closing bracket",
beforeSelfCloseNeedNewline: "A newline is required before closing bracket",
afterOpenNoSpace: "A space is forbidden after opening bracket",
afterOpenNeedSpace: "A space is required after opening bracket",
beforeCloseNoSpace: "A space is forbidden before closing bracket",
beforeCloseNeedSpace: "Whitespace is required before closing bracket",
beforeCloseNeedNewline: "A newline is required before closing bracket"
}
},
create(context, [options]) {
const { closingSlash, beforeSelfClosing, afterOpening, beforeClosing } = options;
return {
JSXOpeningElement(node) {
if (closingSlash !== "allow" && node.selfClosing) validateClosingSlash(context, node, closingSlash);
if (afterOpening !== "allow") validateAfterOpening(context, node, afterOpening);
if (beforeSelfClosing !== "allow" && node.selfClosing) validateBeforeSelfClosing(context, node, beforeSelfClosing);
if (beforeClosing !== "allow") validateBeforeClosing(context, node, beforeClosing);
},
JSXClosingElement(node) {
if (afterOpening !== "allow") validateAfterOpening(context, node, afterOpening);
if (closingSlash !== "allow") validateClosingSlash(context, node, closingSlash);
if (beforeClosing !== "allow") validateBeforeClosing(context, node, beforeClosing);
}
};
}
});
export { jsx_tag_spacing_default as t };