@blueprintjs/eslint-plugin
Advanced tools
Comparing version 0.3.5 to 0.3.6
@@ -27,3 +27,3 @@ "use strict"; | ||
// currently support pt- and bp3- prefixes. | ||
const BLUEPRINT_CLASSNAME_PATTERN = /[^\w-<.]?((pt|bp3)-(?!icon-?)[\w-]+)/g; | ||
const BLUEPRINT_CLASSNAME_PATTERN = /(?<![\w])((?:pt|bp3)-(?!icon)[\w-]+)/g; | ||
exports.classesConstantsRule = createRule_1.createRule({ | ||
@@ -51,2 +51,8 @@ name: "classes-constants", | ||
function create(context, node) { | ||
var _a, _b; | ||
// We shouldn't lint on strings from imports/exports | ||
if (((_a = node.parent) === null || _a === void 0 ? void 0 : _a.type) === experimental_utils_1.AST_NODE_TYPES.ImportDeclaration || | ||
((_b = node.parent) === null || _b === void 0 ? void 0 : _b.type) === experimental_utils_1.AST_NODE_TYPES.ExportNamedDeclaration) { | ||
return; | ||
} | ||
const nodeValue = node.type === experimental_utils_1.AST_NODE_TYPES.Literal ? node.raw : node.value.raw; | ||
@@ -58,3 +64,3 @@ const prefixMatches = getAllMatches(nodeValue); | ||
? // "string literal" likely becomes `${template} string` so we may need to change how it is assigned | ||
wrapForParent(getLiteralReplacement(nodeValue, ptClassStrings), node) | ||
wrapForParent(getLiteralReplacement(nodeValue, prefixMatches), node) | ||
: getTemplateReplacement(nodeValue, ptClassStrings); | ||
@@ -87,16 +93,32 @@ context.report({ | ||
/** Produce replacement text for a string literal that contains invalid classes. */ | ||
function getLiteralReplacement(className, ptClassStrings) { | ||
// remove all illegal classnames, then slice off the quotes, then merge & trim any remaining white space | ||
const stringWithoutPtClasses = ptClassStrings | ||
.reduce((value, cssClass) => value.replace(cssClass, ""), className) | ||
.slice(1, -1) | ||
.replace(/(\s)+/, "$1") | ||
.trim(); | ||
// special case: only one invalid class name | ||
if (stringWithoutPtClasses.length === 0 && ptClassStrings.length === 1) { | ||
return convertPtClassName(ptClassStrings[0]); | ||
function getLiteralReplacement(className, prefixMatches) { | ||
// Special case: the string consists entirely of the invalid class name (ignoring quotes/spaces) | ||
// In this scenario, we just want to return the converted classnames without surrounding with ${} for interpolation | ||
if (prefixMatches.length === 1) { | ||
const remainingString = className | ||
.replace(prefixMatches[0].match, "") | ||
.slice(1, -1) | ||
.replace(/(\s)+/, "$1") | ||
.trim(); | ||
if (remainingString.length === 0) { | ||
return convertPtClassName(prefixMatches[0].match); | ||
} | ||
} | ||
// otherwise produce a `template string` | ||
const templateStrings = ptClassStrings.map(n => `\${${convertPtClassName(n)}}`).join(" "); | ||
return `\`${[templateStrings, stringWithoutPtClasses].join(" ").trim()}\``; | ||
// Start with the beginning of the string until the first match of an invalid classname | ||
let newString = ""; | ||
let currentIndex = 0; | ||
for (const { match, index } of prefixMatches) { | ||
// Add the strings between the currentIndex and this invalid class name's index | ||
newString += className.slice(currentIndex, index); | ||
// Add the converted string instead of the original string | ||
newString += `\${${convertPtClassName(match)}}`; | ||
// Update the index to immediately after this invalid class name | ||
currentIndex = index + match.length; | ||
} | ||
// Add remaining parts of string that occurred after the last invalid class name | ||
newString += className.slice(currentIndex, className.length); | ||
// Slice off the quotes, and merge & trim any remaining white space | ||
newString = newString.slice(1, -1).replace(/(\s)+/, "$1").trim(); | ||
// Surround with backticks instead for the newly added template strings | ||
return `\`${newString}\``; | ||
} | ||
@@ -103,0 +125,0 @@ /** Produce replacement text for a `template string` that contains invalid classes. */ |
{ | ||
"name": "@blueprintjs/eslint-plugin", | ||
"version": "0.3.5", | ||
"version": "0.3.6", | ||
"description": "ESLint rules for use with @blueprintjs packages", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -28,3 +28,3 @@ /* | ||
// currently support pt- and bp3- prefixes. | ||
const BLUEPRINT_CLASSNAME_PATTERN = /[^\w-<.]?((pt|bp3)-(?!icon-?)[\w-]+)/g; | ||
const BLUEPRINT_CLASSNAME_PATTERN = /(?<![\w])((?:pt|bp3)-(?!icon)[\w-]+)/g; | ||
@@ -56,2 +56,9 @@ type MessageIds = "useBlueprintClasses"; | ||
function create(context: RuleContext<MessageIds, []>, node: TSESTree.Literal | TSESTree.TemplateElement): void { | ||
// We shouldn't lint on strings from imports/exports | ||
if ( | ||
node.parent?.type === AST_NODE_TYPES.ImportDeclaration || | ||
node.parent?.type === AST_NODE_TYPES.ExportNamedDeclaration | ||
) { | ||
return; | ||
} | ||
const nodeValue = node.type === AST_NODE_TYPES.Literal ? node.raw : node.value.raw; | ||
@@ -64,5 +71,4 @@ const prefixMatches = getAllMatches(nodeValue); | ||
? // "string literal" likely becomes `${template} string` so we may need to change how it is assigned | ||
wrapForParent(getLiteralReplacement(nodeValue, ptClassStrings), node) | ||
wrapForParent(getLiteralReplacement(nodeValue, prefixMatches), node) | ||
: getTemplateReplacement(nodeValue, ptClassStrings); | ||
context.report({ | ||
@@ -99,16 +105,33 @@ messageId: "useBlueprintClasses", | ||
/** Produce replacement text for a string literal that contains invalid classes. */ | ||
function getLiteralReplacement(className: string, ptClassStrings: string[]) { | ||
// remove all illegal classnames, then slice off the quotes, then merge & trim any remaining white space | ||
const stringWithoutPtClasses = ptClassStrings | ||
.reduce((value, cssClass) => value.replace(cssClass, ""), className) | ||
.slice(1, -1) | ||
.replace(/(\s)+/, "$1") | ||
.trim(); | ||
// special case: only one invalid class name | ||
if (stringWithoutPtClasses.length === 0 && ptClassStrings.length === 1) { | ||
return convertPtClassName(ptClassStrings[0]); | ||
function getLiteralReplacement(className: string, prefixMatches: Array<{ match: string; index: number }>) { | ||
// Special case: the string consists entirely of the invalid class name (ignoring quotes/spaces) | ||
// In this scenario, we just want to return the converted classnames without surrounding with ${} for interpolation | ||
if (prefixMatches.length === 1) { | ||
const remainingString = className | ||
.replace(prefixMatches[0].match, "") | ||
.slice(1, -1) | ||
.replace(/(\s)+/, "$1") | ||
.trim(); | ||
if (remainingString.length === 0) { | ||
return convertPtClassName(prefixMatches[0].match); | ||
} | ||
} | ||
// otherwise produce a `template string` | ||
const templateStrings = ptClassStrings.map(n => `\${${convertPtClassName(n)}}`).join(" "); | ||
return `\`${[templateStrings, stringWithoutPtClasses].join(" ").trim()}\``; | ||
// Start with the beginning of the string until the first match of an invalid classname | ||
let newString = ""; | ||
let currentIndex = 0; | ||
for (const { match, index } of prefixMatches) { | ||
// Add the strings between the currentIndex and this invalid class name's index | ||
newString += className.slice(currentIndex, index); | ||
// Add the converted string instead of the original string | ||
newString += `\${${convertPtClassName(match)}}`; | ||
// Update the index to immediately after this invalid class name | ||
currentIndex = index + match.length; | ||
} | ||
// Add remaining parts of string that occurred after the last invalid class name | ||
newString += className.slice(currentIndex, className.length); | ||
// Slice off the quotes, and merge & trim any remaining white space | ||
newString = newString.slice(1, -1).replace(/(\s)+/, "$1").trim(); | ||
// Surround with backticks instead for the newly added template strings | ||
return `\`${newString}\``; | ||
} | ||
@@ -115,0 +138,0 @@ |
@@ -112,2 +112,35 @@ /* | ||
// function usage with literal string and preceding period | ||
{ | ||
code: `myFunction(".pt-fill");`, | ||
errors: [{ messageId: "useBlueprintClasses", column: 12, line: 1 }], | ||
output: dedent` | ||
import { Classes } from "@blueprintjs/core"; | ||
myFunction(${"`.${Classes.FILL}`"}); | ||
`, | ||
}, | ||
// function usage literal string with preceding period and preceding class | ||
{ | ||
code: `myFunction("my-class .pt-fill");`, | ||
errors: [{ messageId: "useBlueprintClasses", column: 12, line: 1 }], | ||
output: dedent` | ||
import { Classes } from "@blueprintjs/core"; | ||
myFunction(${"`my-class .${Classes.FILL}`"}); | ||
`, | ||
}, | ||
// function usage with template string and preceding period | ||
{ | ||
code: "myFunction(`my-class .pt-fill`);", | ||
errors: [{ messageId: "useBlueprintClasses", column: 12, line: 1 }], | ||
output: dedent` | ||
import { Classes } from "@blueprintjs/core"; | ||
myFunction(${"`my-class .${Classes.FILL}`"}); | ||
`, | ||
}, | ||
// array index usage | ||
@@ -166,3 +199,11 @@ { | ||
'<div className="pt-icon-folder-open" />', | ||
// don't flag strings in export/import statements | ||
'import { test } from "packagewithpt-thatshouldnterror";', | ||
'export { test } from "packagewithpt-thatshouldnterror";', | ||
// don't flag non applicable strings in function calls | ||
`myFunction("stringwithpt-thatshouldnt-error");`, | ||
"myFunction(`stringwithpt-thatshouldnt-error`);", | ||
], | ||
}); |
Sorry, the diff of this file is not supported yet
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
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
82054
1551