@taiga-ui/eslint-plugin-experience-next 0.412.0 → 0.414.0
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/README.md +1 -0
- package/index.d.ts +3 -0
- package/index.esm.js +106 -15
- package/package.json +4 -4
- package/rules/no-playwright-empty-fill.d.ts +5 -0
package/README.md
CHANGED
|
@@ -48,6 +48,7 @@ export default [
|
|
|
48
48
|
| no-deep-imports-to-indexed-packages | Disallow deep imports from packages that expose an index.ts next to ng-package.json or package.json | ✅ | 🔧 | |
|
|
49
49
|
| no-href-with-router-link | Do not use href and routerLink attributes together on the same element | | 🔧 | |
|
|
50
50
|
| no-implicit-public | Require explicit `public` modifier for class members and parameter properties | ✅ | 🔧 | |
|
|
51
|
+
| no-playwright-empty-fill | Enforce `clear()` over `fill('')` in Playwright tests | ✅ | 🔧 | |
|
|
51
52
|
| standalone-imports-sort | Sort imports alphabetically | ✅ | 🔧 | |
|
|
52
53
|
| prefer-deep-imports | Allow deep imports of Taiga UI packages | | 🔧 | |
|
|
53
54
|
| short-tui-imports | Shorten TuiXxxComponent / TuiYyyDirective in Angular metadata | ✅ | 🔧 | |
|
package/index.d.ts
CHANGED
|
@@ -37,6 +37,9 @@ declare const plugin: {
|
|
|
37
37
|
'no-implicit-public': import("@typescript-eslint/utils/ts-eslint").RuleModule<"implicitPublic", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
38
38
|
name: string;
|
|
39
39
|
};
|
|
40
|
+
'no-playwright-empty-fill': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useClear", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
41
|
+
name: string;
|
|
42
|
+
};
|
|
40
43
|
'object-single-line': import("@typescript-eslint/utils/ts-eslint").RuleModule<"oneLine", [{
|
|
41
44
|
printWidth: number;
|
|
42
45
|
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
package/index.esm.js
CHANGED
|
@@ -946,6 +946,7 @@ var recommended = defineConfig([
|
|
|
946
946
|
files: ['**/*.pw.spec.ts'],
|
|
947
947
|
extends: [playwright.configs['flat/recommended']],
|
|
948
948
|
rules: {
|
|
949
|
+
'@taiga-ui/experience-next/no-playwright-empty-fill': 'error',
|
|
949
950
|
'compat/compat': 'off',
|
|
950
951
|
'jest/prefer-importing-jest-globals': 'off',
|
|
951
952
|
'playwright/expect-expect': [
|
|
@@ -1242,8 +1243,8 @@ function intersect(a, b) {
|
|
|
1242
1243
|
return a.some((type) => origin.has(type));
|
|
1243
1244
|
}
|
|
1244
1245
|
|
|
1245
|
-
const createRule$
|
|
1246
|
-
var classPropertyNaming = createRule$
|
|
1246
|
+
const createRule$b = ESLintUtils.RuleCreator((name) => name);
|
|
1247
|
+
var classPropertyNaming = createRule$b({
|
|
1247
1248
|
create(context, [configs]) {
|
|
1248
1249
|
const parserServices = ESLintUtils.getParserServices(context);
|
|
1249
1250
|
const typeChecker = parserServices.program.getTypeChecker();
|
|
@@ -1412,9 +1413,9 @@ function isExternalPureTuple(typeChecker, type) {
|
|
|
1412
1413
|
return typeArgs.every((item) => isClassType(item));
|
|
1413
1414
|
}
|
|
1414
1415
|
|
|
1415
|
-
const createRule$
|
|
1416
|
+
const createRule$a = ESLintUtils.RuleCreator((name) => name);
|
|
1416
1417
|
const MESSAGE_ID$5 = 'spreadArrays';
|
|
1417
|
-
var flatExports = createRule$
|
|
1418
|
+
var flatExports = createRule$a({
|
|
1418
1419
|
create(context) {
|
|
1419
1420
|
const parserServices = ESLintUtils.getParserServices(context);
|
|
1420
1421
|
const typeChecker = parserServices.program.getTypeChecker();
|
|
@@ -1541,8 +1542,8 @@ var flatExports = createRule$9({
|
|
|
1541
1542
|
|
|
1542
1543
|
const MESSAGE_ID$4 = 'invalid-injection-token-description';
|
|
1543
1544
|
const ERROR_MESSAGE$3 = "InjectionToken's description should contain token's name";
|
|
1544
|
-
const createRule$
|
|
1545
|
-
const rule$
|
|
1545
|
+
const createRule$9 = ESLintUtils.RuleCreator((name) => name);
|
|
1546
|
+
const rule$6 = createRule$9({
|
|
1546
1547
|
create(context) {
|
|
1547
1548
|
return {
|
|
1548
1549
|
'NewExpression[callee.name="InjectionToken"]'(node) {
|
|
@@ -1600,8 +1601,8 @@ const DEFAULT_OPTIONS = {
|
|
|
1600
1601
|
importDeclaration: '^@taiga-ui*',
|
|
1601
1602
|
projectName: String.raw `(?<=^@taiga-ui/)([-\w]+)`,
|
|
1602
1603
|
};
|
|
1603
|
-
const createRule$
|
|
1604
|
-
const rule$
|
|
1604
|
+
const createRule$8 = ESLintUtils.RuleCreator((name) => name);
|
|
1605
|
+
const rule$5 = createRule$8({
|
|
1605
1606
|
create(context) {
|
|
1606
1607
|
const { currentProject, deepImport, ignoreImports, importDeclaration, projectName, } = { ...DEFAULT_OPTIONS, ...context.options[0] };
|
|
1607
1608
|
const isDeepImport = (source) => !!source && new RegExp(deepImport, 'g').test(source);
|
|
@@ -1680,13 +1681,13 @@ const rule$4 = createRule$7({
|
|
|
1680
1681
|
name: 'no-deep-imports',
|
|
1681
1682
|
});
|
|
1682
1683
|
|
|
1683
|
-
const createRule$
|
|
1684
|
+
const createRule$7 = ESLintUtils.RuleCreator((name) => name);
|
|
1684
1685
|
const resolveCacheByOptions = new WeakMap();
|
|
1685
1686
|
const nearestFileUpCache = new Map();
|
|
1686
1687
|
const markerCache = new Map();
|
|
1687
1688
|
const indexFileCache = new Map();
|
|
1688
1689
|
const indexExportsCache = new Map();
|
|
1689
|
-
var noDeepImportsToIndexedPackages = createRule$
|
|
1690
|
+
var noDeepImportsToIndexedPackages = createRule$7({
|
|
1690
1691
|
create(context) {
|
|
1691
1692
|
const parserServices = ESLintUtils.getParserServices(context);
|
|
1692
1693
|
const program = parserServices.program;
|
|
@@ -1929,8 +1930,8 @@ const config = {
|
|
|
1929
1930
|
},
|
|
1930
1931
|
};
|
|
1931
1932
|
|
|
1932
|
-
const createRule$
|
|
1933
|
-
const rule$
|
|
1933
|
+
const createRule$6 = ESLintUtils.RuleCreator((name) => name);
|
|
1934
|
+
const rule$4 = createRule$6({
|
|
1934
1935
|
create(context) {
|
|
1935
1936
|
const checkImplicitPublic = (node) => {
|
|
1936
1937
|
const classRef = getClass(node);
|
|
@@ -2002,6 +2003,95 @@ function getClass(node) {
|
|
|
2002
2003
|
return getClass(node.parent);
|
|
2003
2004
|
}
|
|
2004
2005
|
|
|
2006
|
+
const createRule$5 = ESLintUtils.RuleCreator((name) => name);
|
|
2007
|
+
const rule$3 = createRule$5({
|
|
2008
|
+
create(context) {
|
|
2009
|
+
const services = ESLintUtils.getParserServices(context);
|
|
2010
|
+
const checker = services.program.getTypeChecker();
|
|
2011
|
+
return {
|
|
2012
|
+
CallExpression(node) {
|
|
2013
|
+
const callee = node.callee;
|
|
2014
|
+
if (callee.type !== AST_NODE_TYPES$1.MemberExpression) {
|
|
2015
|
+
return;
|
|
2016
|
+
}
|
|
2017
|
+
const property = callee.property;
|
|
2018
|
+
if (property.type !== AST_NODE_TYPES$1.Identifier ||
|
|
2019
|
+
property.name !== 'fill' ||
|
|
2020
|
+
node.arguments.length !== 1) {
|
|
2021
|
+
return;
|
|
2022
|
+
}
|
|
2023
|
+
const [argument] = node.arguments;
|
|
2024
|
+
if (!argument || !isEmptyString(argument)) {
|
|
2025
|
+
return;
|
|
2026
|
+
}
|
|
2027
|
+
const objectExpression = callee.object;
|
|
2028
|
+
const tsNode = services.esTreeNodeToTSNodeMap.get(objectExpression);
|
|
2029
|
+
const type = checker.getTypeAtLocation(tsNode);
|
|
2030
|
+
if (!isPlaywrightLocator(type, checker)) {
|
|
2031
|
+
return;
|
|
2032
|
+
}
|
|
2033
|
+
context.report({
|
|
2034
|
+
fix(fixer) {
|
|
2035
|
+
const objectText = context.sourceCode.getText(objectExpression);
|
|
2036
|
+
return fixer.replaceText(node, `${objectText}.clear()`);
|
|
2037
|
+
},
|
|
2038
|
+
messageId: 'useClear',
|
|
2039
|
+
node,
|
|
2040
|
+
});
|
|
2041
|
+
},
|
|
2042
|
+
};
|
|
2043
|
+
},
|
|
2044
|
+
defaultOptions: [],
|
|
2045
|
+
meta: {
|
|
2046
|
+
docs: {
|
|
2047
|
+
description: "Enforce Playwright clear() instead of fill('') for emptying fields",
|
|
2048
|
+
},
|
|
2049
|
+
fixable: 'code',
|
|
2050
|
+
messages: { useClear: "Use clear() instead of fill('') when emptying a field" },
|
|
2051
|
+
schema: [],
|
|
2052
|
+
type: 'suggestion',
|
|
2053
|
+
},
|
|
2054
|
+
name: 'no-playwright-empty-fill',
|
|
2055
|
+
});
|
|
2056
|
+
function isEmptyString(node) {
|
|
2057
|
+
return ((node.type === AST_NODE_TYPES$1.Literal && node.value === '') ||
|
|
2058
|
+
(node.type === AST_NODE_TYPES$1.TemplateLiteral &&
|
|
2059
|
+
node.expressions.length === 0 &&
|
|
2060
|
+
node.quasis.length === 1 &&
|
|
2061
|
+
node.quasis[0]?.value.cooked === ''));
|
|
2062
|
+
}
|
|
2063
|
+
function isPlaywrightLocator(type, checker) {
|
|
2064
|
+
if (isPlaywrightLocatorType(type)) {
|
|
2065
|
+
return true;
|
|
2066
|
+
}
|
|
2067
|
+
const locatorProp = type.getProperty('locator');
|
|
2068
|
+
if (!locatorProp) {
|
|
2069
|
+
return false;
|
|
2070
|
+
}
|
|
2071
|
+
const decl = locatorProp.valueDeclaration ?? locatorProp.declarations?.[0];
|
|
2072
|
+
if (!decl) {
|
|
2073
|
+
return false;
|
|
2074
|
+
}
|
|
2075
|
+
const locatorType = checker.getTypeOfSymbolAtLocation(locatorProp, decl);
|
|
2076
|
+
return isPlaywrightLocatorType(locatorType);
|
|
2077
|
+
}
|
|
2078
|
+
function isPlaywrightLocatorType(type) {
|
|
2079
|
+
if (type.isUnionOrIntersection()) {
|
|
2080
|
+
return type.types.some(isPlaywrightLocatorType);
|
|
2081
|
+
}
|
|
2082
|
+
const symbol = type.getSymbol() ?? type.aliasSymbol;
|
|
2083
|
+
if (symbol?.getName() !== 'Locator') {
|
|
2084
|
+
return false;
|
|
2085
|
+
}
|
|
2086
|
+
const declarations = symbol.getDeclarations() ?? [];
|
|
2087
|
+
return declarations.some((decl) => {
|
|
2088
|
+
const fileName = decl.getSourceFile().fileName.replaceAll('\\', '/');
|
|
2089
|
+
return (fileName.includes('/node_modules/playwright/') ||
|
|
2090
|
+
fileName.includes('/node_modules/@playwright/test/') ||
|
|
2091
|
+
fileName.includes('/node_modules/playwright-core/'));
|
|
2092
|
+
});
|
|
2093
|
+
}
|
|
2094
|
+
|
|
2005
2095
|
const createRule$4 = ESLintUtils.RuleCreator((name) => name);
|
|
2006
2096
|
const rule$2 = createRule$4({
|
|
2007
2097
|
create(context, [{ printWidth }]) {
|
|
@@ -3105,11 +3195,12 @@ const plugin = {
|
|
|
3105
3195
|
'class-property-naming': classPropertyNaming,
|
|
3106
3196
|
'decorator-key-sort': config$1,
|
|
3107
3197
|
'flat-exports': flatExports,
|
|
3108
|
-
'injection-token-description': rule$
|
|
3109
|
-
'no-deep-imports': rule$
|
|
3198
|
+
'injection-token-description': rule$6,
|
|
3199
|
+
'no-deep-imports': rule$5,
|
|
3110
3200
|
'no-deep-imports-to-indexed-packages': noDeepImportsToIndexedPackages,
|
|
3111
3201
|
'no-href-with-router-link': config,
|
|
3112
|
-
'no-implicit-public': rule$
|
|
3202
|
+
'no-implicit-public': rule$4,
|
|
3203
|
+
'no-playwright-empty-fill': rule$3,
|
|
3113
3204
|
'object-single-line': rule$2,
|
|
3114
3205
|
'prefer-deep-imports': preferDeepImports,
|
|
3115
3206
|
'short-tui-imports': rule$1,
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taiga-ui/eslint-plugin-experience-next",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.414.0",
|
|
4
4
|
"description": "An ESLint plugin to enforce a consistent code styles across taiga-ui projects",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"devDependencies": {
|
|
8
8
|
"@typescript-eslint/rule-tester": "8.55.0",
|
|
9
|
-
"glob": "13.0.
|
|
9
|
+
"glob": "13.0.3"
|
|
10
10
|
},
|
|
11
11
|
"peerDependencies": {
|
|
12
12
|
"@eslint/compat": "^2.0.2",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"eslint-plugin-decorator-position": "^6.0.0",
|
|
26
26
|
"eslint-plugin-file-progress": "^3.0.2",
|
|
27
27
|
"eslint-plugin-import": "^2.32.0",
|
|
28
|
-
"eslint-plugin-jest": "^29.
|
|
28
|
+
"eslint-plugin-jest": "^29.14.0",
|
|
29
29
|
"eslint-plugin-package-json": "^0.88.2",
|
|
30
30
|
"eslint-plugin-perfectionist": "^5.5.0",
|
|
31
31
|
"eslint-plugin-playwright": "^2.5.1",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"eslint-plugin-promise": "^7.2.1",
|
|
34
34
|
"eslint-plugin-regexp": "^3.0.0",
|
|
35
35
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
36
|
-
"eslint-plugin-sonarjs": "^3.0.
|
|
36
|
+
"eslint-plugin-sonarjs": "^3.0.7",
|
|
37
37
|
"eslint-plugin-unicorn": "^62.0.0",
|
|
38
38
|
"eslint-plugin-unused-imports": "^4.4.1",
|
|
39
39
|
"glob": "*",
|