@siberiacancode/eslint 2.16.4 → 2.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +2 -137
- package/dist/esm/index.mjs +2 -135
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -36,10 +36,6 @@ let eslint_plugin_jsx_a11y = require("eslint-plugin-jsx-a11y");
|
|
|
36
36
|
eslint_plugin_jsx_a11y = __toESM(eslint_plugin_jsx_a11y);
|
|
37
37
|
let eslint_plugin_playwright = require("eslint-plugin-playwright");
|
|
38
38
|
eslint_plugin_playwright = __toESM(eslint_plugin_playwright);
|
|
39
|
-
let node_fs = require("node:fs");
|
|
40
|
-
node_fs = __toESM(node_fs);
|
|
41
|
-
let node_path = require("node:path");
|
|
42
|
-
node_path = __toESM(node_path);
|
|
43
39
|
|
|
44
40
|
//#region src/plugin/rules/function-component-definition.ts
|
|
45
41
|
const NAMED_TEMPLATES = {
|
|
@@ -252,131 +248,6 @@ const functionComponentDefinition = {
|
|
|
252
248
|
}
|
|
253
249
|
};
|
|
254
250
|
|
|
255
|
-
//#endregion
|
|
256
|
-
//#region src/plugin/rules/no-unused-class.ts
|
|
257
|
-
const STYLE_IMPORT_REGEXP = /\.(?:css|scss|less)$/u;
|
|
258
|
-
const toCamelCase = (value) => value.replace(/-([a-z])/gu, (_substring, letter) => letter.toUpperCase());
|
|
259
|
-
const extractClassNames = (source) => {
|
|
260
|
-
const classNames = /* @__PURE__ */ new Set();
|
|
261
|
-
const classNameRegExp = /\.([_a-zA-Z][\w-]*)/gu;
|
|
262
|
-
let match = classNameRegExp.exec(source);
|
|
263
|
-
while (match !== null) {
|
|
264
|
-
const className = match[1];
|
|
265
|
-
if (className !== void 0 && className !== "") classNames.add(className);
|
|
266
|
-
match = classNameRegExp.exec(source);
|
|
267
|
-
}
|
|
268
|
-
return [...classNames];
|
|
269
|
-
};
|
|
270
|
-
const buildClassesMap = (classNames, camelCaseOption) => {
|
|
271
|
-
const onlyCamelCase = camelCaseOption === "only" || camelCaseOption === "dashes-only";
|
|
272
|
-
const withCamelCase = camelCaseOption === true || camelCaseOption === "dashes" || onlyCamelCase;
|
|
273
|
-
const classesMap = {};
|
|
274
|
-
classNames.forEach((className) => {
|
|
275
|
-
if (!onlyCamelCase) classesMap[className] = className;
|
|
276
|
-
if (withCamelCase) classesMap[toCamelCase(className)] = className;
|
|
277
|
-
});
|
|
278
|
-
return classesMap;
|
|
279
|
-
};
|
|
280
|
-
const getStyleImportData = (node) => {
|
|
281
|
-
if (node.source.type !== "Literal" || typeof node.source.value !== "string") return void 0;
|
|
282
|
-
const source = node.source.value;
|
|
283
|
-
if (!STYLE_IMPORT_REGEXP.test(source)) return void 0;
|
|
284
|
-
const importSpecifier = node.specifiers.find((specifier) => specifier.type === "ImportDefaultSpecifier" || specifier.type === "ImportNamespaceSpecifier");
|
|
285
|
-
if (importSpecifier === void 0) return void 0;
|
|
286
|
-
return {
|
|
287
|
-
importName: importSpecifier.local.name,
|
|
288
|
-
importNode: importSpecifier,
|
|
289
|
-
styleFilePath: source
|
|
290
|
-
};
|
|
291
|
-
};
|
|
292
|
-
const getPropertyName = (node, camelCaseOption) => {
|
|
293
|
-
if (node.computed === false && node.property.type === "Identifier") return node.property.name;
|
|
294
|
-
if (node.computed === true && node.property.type === "Literal") {
|
|
295
|
-
if (typeof node.property.value !== "string" || node.property.value === "") return void 0;
|
|
296
|
-
return camelCaseOption === "only" ? toCamelCase(node.property.value) : node.property.value;
|
|
297
|
-
}
|
|
298
|
-
if (node.computed === true && node.property.type === "TemplateLiteral" && node.property.expressions.length === 0) {
|
|
299
|
-
const value = node.property.quasis[0]?.value.cooked;
|
|
300
|
-
if (typeof value !== "string" || value === "") return void 0;
|
|
301
|
-
return camelCaseOption === "only" ? toCamelCase(value) : value;
|
|
302
|
-
}
|
|
303
|
-
};
|
|
304
|
-
const getAbsoluteStylePath = (context, styleFilePath) => {
|
|
305
|
-
const filename = context.filename;
|
|
306
|
-
if (filename === "<input>") return void 0;
|
|
307
|
-
return node_path.default.resolve(node_path.default.dirname(filename), styleFilePath);
|
|
308
|
-
};
|
|
309
|
-
const noUnusedClass = {
|
|
310
|
-
meta: {
|
|
311
|
-
type: "problem",
|
|
312
|
-
docs: { description: "Checks that all CSS/SCSS/LESS classes imported as modules are used" },
|
|
313
|
-
schema: [{
|
|
314
|
-
type: "object",
|
|
315
|
-
properties: {
|
|
316
|
-
camelCase: { enum: [
|
|
317
|
-
true,
|
|
318
|
-
"dashes",
|
|
319
|
-
"only",
|
|
320
|
-
"dashes-only"
|
|
321
|
-
] },
|
|
322
|
-
markAsUsed: {
|
|
323
|
-
type: "array",
|
|
324
|
-
items: { type: "string" }
|
|
325
|
-
}
|
|
326
|
-
},
|
|
327
|
-
additionalProperties: false
|
|
328
|
-
}]
|
|
329
|
-
},
|
|
330
|
-
create(context) {
|
|
331
|
-
const options = context.options[0] ?? {};
|
|
332
|
-
const camelCaseOption = options.camelCase;
|
|
333
|
-
const markAsUsed = options.markAsUsed ?? [];
|
|
334
|
-
const importMap = {};
|
|
335
|
-
return {
|
|
336
|
-
ImportDeclaration(node) {
|
|
337
|
-
const styleImportData = getStyleImportData(node);
|
|
338
|
-
if (styleImportData === void 0) return;
|
|
339
|
-
const absoluteStylePath = getAbsoluteStylePath(context, styleImportData.styleFilePath);
|
|
340
|
-
if (absoluteStylePath === void 0 || !node_fs.default.existsSync(absoluteStylePath)) return;
|
|
341
|
-
const classNames = extractClassNames(node_fs.default.readFileSync(absoluteStylePath, "utf8"));
|
|
342
|
-
const classes = {};
|
|
343
|
-
classNames.forEach((className) => {
|
|
344
|
-
classes[className] = false;
|
|
345
|
-
});
|
|
346
|
-
importMap[styleImportData.importName] = {
|
|
347
|
-
classes,
|
|
348
|
-
classesMap: buildClassesMap(classNames, camelCaseOption),
|
|
349
|
-
filePath: styleImportData.styleFilePath,
|
|
350
|
-
node: styleImportData.importNode
|
|
351
|
-
};
|
|
352
|
-
},
|
|
353
|
-
MemberExpression(node) {
|
|
354
|
-
const typedNode = node;
|
|
355
|
-
if (typedNode.object.type !== "Identifier") return;
|
|
356
|
-
const entry = importMap[typedNode.object.name];
|
|
357
|
-
if (entry === void 0) return;
|
|
358
|
-
const propertyName = getPropertyName(typedNode, camelCaseOption);
|
|
359
|
-
if (propertyName === void 0 || propertyName === "") return;
|
|
360
|
-
const className = entry.classesMap[propertyName];
|
|
361
|
-
if (className === void 0 || className === "") return;
|
|
362
|
-
entry.classes[className] = true;
|
|
363
|
-
},
|
|
364
|
-
"Program:exit": () => {
|
|
365
|
-
Object.values(importMap).forEach((entry) => {
|
|
366
|
-
markAsUsed.forEach((usedClass) => {
|
|
367
|
-
if (usedClass !== "") entry.classes[usedClass] = true;
|
|
368
|
-
});
|
|
369
|
-
const unusedClasses = Object.entries(entry.classes).filter(([, used]) => used === false).map(([className]) => className);
|
|
370
|
-
if (unusedClasses.length > 0) context.report({
|
|
371
|
-
node: entry.node,
|
|
372
|
-
message: `Unused classes found in ${node_path.default.basename(entry.filePath)}: ${unusedClasses.join(", ")}`
|
|
373
|
-
});
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
};
|
|
379
|
-
|
|
380
251
|
//#endregion
|
|
381
252
|
//#region src/plugin/index.ts
|
|
382
253
|
const version = "1.0.0";
|
|
@@ -385,10 +256,7 @@ const siberiacancodePlugin = {
|
|
|
385
256
|
name: "@siberiacancode/eslint-plugin",
|
|
386
257
|
version
|
|
387
258
|
},
|
|
388
|
-
rules: {
|
|
389
|
-
"function-component-definition": functionComponentDefinition,
|
|
390
|
-
"no-unused-class": noUnusedClass
|
|
391
|
-
}
|
|
259
|
+
rules: { "function-component-definition": functionComponentDefinition }
|
|
392
260
|
};
|
|
393
261
|
|
|
394
262
|
//#endregion
|
|
@@ -492,10 +360,7 @@ const eslint = (inputOptions = {}, ...configs) => {
|
|
|
492
360
|
configs.unshift({
|
|
493
361
|
name: "siberiacancode",
|
|
494
362
|
plugins: { siberiacancode: siberiacancodePlugin },
|
|
495
|
-
rules: {
|
|
496
|
-
"siberiacancode/function-component-definition": ["error", { namedComponents: ["arrow-function"] }],
|
|
497
|
-
"siberiacancode/no-unused-class": "error"
|
|
498
|
-
}
|
|
363
|
+
rules: { "siberiacancode/function-component-definition": ["error", { namedComponents: ["arrow-function"] }] }
|
|
499
364
|
});
|
|
500
365
|
return (0, _antfu_eslint_config.default)({
|
|
501
366
|
...options,
|
package/dist/esm/index.mjs
CHANGED
|
@@ -3,8 +3,6 @@ import pluginCss from "@eslint/css";
|
|
|
3
3
|
import pluginBetterTailwindcss from "eslint-plugin-better-tailwindcss";
|
|
4
4
|
import pluginJsxA11y from "eslint-plugin-jsx-a11y";
|
|
5
5
|
import pluginPlaywright from "eslint-plugin-playwright";
|
|
6
|
-
import fs from "node:fs";
|
|
7
|
-
import path from "node:path";
|
|
8
6
|
|
|
9
7
|
//#region src/plugin/rules/function-component-definition.ts
|
|
10
8
|
const NAMED_TEMPLATES = {
|
|
@@ -217,131 +215,6 @@ const functionComponentDefinition = {
|
|
|
217
215
|
}
|
|
218
216
|
};
|
|
219
217
|
|
|
220
|
-
//#endregion
|
|
221
|
-
//#region src/plugin/rules/no-unused-class.ts
|
|
222
|
-
const STYLE_IMPORT_REGEXP = /\.(?:css|scss|less)$/u;
|
|
223
|
-
const toCamelCase = (value) => value.replace(/-([a-z])/gu, (_substring, letter) => letter.toUpperCase());
|
|
224
|
-
const extractClassNames = (source) => {
|
|
225
|
-
const classNames = /* @__PURE__ */ new Set();
|
|
226
|
-
const classNameRegExp = /\.([_a-zA-Z][\w-]*)/gu;
|
|
227
|
-
let match = classNameRegExp.exec(source);
|
|
228
|
-
while (match !== null) {
|
|
229
|
-
const className = match[1];
|
|
230
|
-
if (className !== void 0 && className !== "") classNames.add(className);
|
|
231
|
-
match = classNameRegExp.exec(source);
|
|
232
|
-
}
|
|
233
|
-
return [...classNames];
|
|
234
|
-
};
|
|
235
|
-
const buildClassesMap = (classNames, camelCaseOption) => {
|
|
236
|
-
const onlyCamelCase = camelCaseOption === "only" || camelCaseOption === "dashes-only";
|
|
237
|
-
const withCamelCase = camelCaseOption === true || camelCaseOption === "dashes" || onlyCamelCase;
|
|
238
|
-
const classesMap = {};
|
|
239
|
-
classNames.forEach((className) => {
|
|
240
|
-
if (!onlyCamelCase) classesMap[className] = className;
|
|
241
|
-
if (withCamelCase) classesMap[toCamelCase(className)] = className;
|
|
242
|
-
});
|
|
243
|
-
return classesMap;
|
|
244
|
-
};
|
|
245
|
-
const getStyleImportData = (node) => {
|
|
246
|
-
if (node.source.type !== "Literal" || typeof node.source.value !== "string") return void 0;
|
|
247
|
-
const source = node.source.value;
|
|
248
|
-
if (!STYLE_IMPORT_REGEXP.test(source)) return void 0;
|
|
249
|
-
const importSpecifier = node.specifiers.find((specifier) => specifier.type === "ImportDefaultSpecifier" || specifier.type === "ImportNamespaceSpecifier");
|
|
250
|
-
if (importSpecifier === void 0) return void 0;
|
|
251
|
-
return {
|
|
252
|
-
importName: importSpecifier.local.name,
|
|
253
|
-
importNode: importSpecifier,
|
|
254
|
-
styleFilePath: source
|
|
255
|
-
};
|
|
256
|
-
};
|
|
257
|
-
const getPropertyName = (node, camelCaseOption) => {
|
|
258
|
-
if (node.computed === false && node.property.type === "Identifier") return node.property.name;
|
|
259
|
-
if (node.computed === true && node.property.type === "Literal") {
|
|
260
|
-
if (typeof node.property.value !== "string" || node.property.value === "") return void 0;
|
|
261
|
-
return camelCaseOption === "only" ? toCamelCase(node.property.value) : node.property.value;
|
|
262
|
-
}
|
|
263
|
-
if (node.computed === true && node.property.type === "TemplateLiteral" && node.property.expressions.length === 0) {
|
|
264
|
-
const value = node.property.quasis[0]?.value.cooked;
|
|
265
|
-
if (typeof value !== "string" || value === "") return void 0;
|
|
266
|
-
return camelCaseOption === "only" ? toCamelCase(value) : value;
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
const getAbsoluteStylePath = (context, styleFilePath) => {
|
|
270
|
-
const filename = context.filename;
|
|
271
|
-
if (filename === "<input>") return void 0;
|
|
272
|
-
return path.resolve(path.dirname(filename), styleFilePath);
|
|
273
|
-
};
|
|
274
|
-
const noUnusedClass = {
|
|
275
|
-
meta: {
|
|
276
|
-
type: "problem",
|
|
277
|
-
docs: { description: "Checks that all CSS/SCSS/LESS classes imported as modules are used" },
|
|
278
|
-
schema: [{
|
|
279
|
-
type: "object",
|
|
280
|
-
properties: {
|
|
281
|
-
camelCase: { enum: [
|
|
282
|
-
true,
|
|
283
|
-
"dashes",
|
|
284
|
-
"only",
|
|
285
|
-
"dashes-only"
|
|
286
|
-
] },
|
|
287
|
-
markAsUsed: {
|
|
288
|
-
type: "array",
|
|
289
|
-
items: { type: "string" }
|
|
290
|
-
}
|
|
291
|
-
},
|
|
292
|
-
additionalProperties: false
|
|
293
|
-
}]
|
|
294
|
-
},
|
|
295
|
-
create(context) {
|
|
296
|
-
const options = context.options[0] ?? {};
|
|
297
|
-
const camelCaseOption = options.camelCase;
|
|
298
|
-
const markAsUsed = options.markAsUsed ?? [];
|
|
299
|
-
const importMap = {};
|
|
300
|
-
return {
|
|
301
|
-
ImportDeclaration(node) {
|
|
302
|
-
const styleImportData = getStyleImportData(node);
|
|
303
|
-
if (styleImportData === void 0) return;
|
|
304
|
-
const absoluteStylePath = getAbsoluteStylePath(context, styleImportData.styleFilePath);
|
|
305
|
-
if (absoluteStylePath === void 0 || !fs.existsSync(absoluteStylePath)) return;
|
|
306
|
-
const classNames = extractClassNames(fs.readFileSync(absoluteStylePath, "utf8"));
|
|
307
|
-
const classes = {};
|
|
308
|
-
classNames.forEach((className) => {
|
|
309
|
-
classes[className] = false;
|
|
310
|
-
});
|
|
311
|
-
importMap[styleImportData.importName] = {
|
|
312
|
-
classes,
|
|
313
|
-
classesMap: buildClassesMap(classNames, camelCaseOption),
|
|
314
|
-
filePath: styleImportData.styleFilePath,
|
|
315
|
-
node: styleImportData.importNode
|
|
316
|
-
};
|
|
317
|
-
},
|
|
318
|
-
MemberExpression(node) {
|
|
319
|
-
const typedNode = node;
|
|
320
|
-
if (typedNode.object.type !== "Identifier") return;
|
|
321
|
-
const entry = importMap[typedNode.object.name];
|
|
322
|
-
if (entry === void 0) return;
|
|
323
|
-
const propertyName = getPropertyName(typedNode, camelCaseOption);
|
|
324
|
-
if (propertyName === void 0 || propertyName === "") return;
|
|
325
|
-
const className = entry.classesMap[propertyName];
|
|
326
|
-
if (className === void 0 || className === "") return;
|
|
327
|
-
entry.classes[className] = true;
|
|
328
|
-
},
|
|
329
|
-
"Program:exit": () => {
|
|
330
|
-
Object.values(importMap).forEach((entry) => {
|
|
331
|
-
markAsUsed.forEach((usedClass) => {
|
|
332
|
-
if (usedClass !== "") entry.classes[usedClass] = true;
|
|
333
|
-
});
|
|
334
|
-
const unusedClasses = Object.entries(entry.classes).filter(([, used]) => used === false).map(([className]) => className);
|
|
335
|
-
if (unusedClasses.length > 0) context.report({
|
|
336
|
-
node: entry.node,
|
|
337
|
-
message: `Unused classes found in ${path.basename(entry.filePath)}: ${unusedClasses.join(", ")}`
|
|
338
|
-
});
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
};
|
|
344
|
-
|
|
345
218
|
//#endregion
|
|
346
219
|
//#region src/plugin/index.ts
|
|
347
220
|
const version = "1.0.0";
|
|
@@ -350,10 +223,7 @@ const siberiacancodePlugin = {
|
|
|
350
223
|
name: "@siberiacancode/eslint-plugin",
|
|
351
224
|
version
|
|
352
225
|
},
|
|
353
|
-
rules: {
|
|
354
|
-
"function-component-definition": functionComponentDefinition,
|
|
355
|
-
"no-unused-class": noUnusedClass
|
|
356
|
-
}
|
|
226
|
+
rules: { "function-component-definition": functionComponentDefinition }
|
|
357
227
|
};
|
|
358
228
|
|
|
359
229
|
//#endregion
|
|
@@ -457,10 +327,7 @@ const eslint = (inputOptions = {}, ...configs) => {
|
|
|
457
327
|
configs.unshift({
|
|
458
328
|
name: "siberiacancode",
|
|
459
329
|
plugins: { siberiacancode: siberiacancodePlugin },
|
|
460
|
-
rules: {
|
|
461
|
-
"siberiacancode/function-component-definition": ["error", { namedComponents: ["arrow-function"] }],
|
|
462
|
-
"siberiacancode/no-unused-class": "error"
|
|
463
|
-
}
|
|
330
|
+
rules: { "siberiacancode/function-component-definition": ["error", { namedComponents: ["arrow-function"] }] }
|
|
464
331
|
});
|
|
465
332
|
return antfu({
|
|
466
333
|
...options,
|