@taiga-ui/eslint-plugin-experience-next 0.483.0 → 0.485.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.
Files changed (2) hide show
  1. package/index.esm.js +50 -24
  2. package/package.json +2 -4
package/index.esm.js CHANGED
@@ -1304,6 +1304,7 @@ var recommended = defineConfig([
1304
1304
  extends: [playwright.configs['flat/recommended']],
1305
1305
  rules: {
1306
1306
  '@taiga-ui/experience-next/no-playwright-empty-fill': 'error',
1307
+ '@taiga-ui/experience-next/no-restricted-attr-values': 'off',
1307
1308
  'compat/compat': 'off',
1308
1309
  'jest/prefer-importing-jest-globals': 'off',
1309
1310
  'playwright/consistent-spacing-between-blocks': 'error',
@@ -1342,6 +1343,7 @@ var recommended = defineConfig([
1342
1343
  files: ['**/*.spec.ts'],
1343
1344
  extends: [jest.configs['flat/recommended']],
1344
1345
  rules: {
1346
+ '@taiga-ui/experience-next/no-restricted-attr-values': 'off',
1345
1347
  '@typescript-eslint/no-extraneous-class': 'off',
1346
1348
  'compat/compat': 'off',
1347
1349
  'jest/expect-expect': 'off',
@@ -1429,6 +1431,7 @@ var recommended = defineConfig([
1429
1431
  files: ['**/*.cy.ts'],
1430
1432
  plugins: { cypress },
1431
1433
  rules: {
1434
+ '@taiga-ui/experience-next/no-restricted-attr-values': 'off',
1432
1435
  'compat/compat': 'off',
1433
1436
  'cypress/no-unnecessary-waiting': 'off',
1434
1437
  'cypress/unsafe-to-chain-command': 'off',
@@ -1509,7 +1512,7 @@ var taigaSpecific = defineConfig([
1509
1512
  },
1510
1513
  },
1511
1514
  {
1512
- files: ['**/demo/**/*.html', '**/*.spec.ts', '**/*.cy.ts'],
1515
+ files: ['**/demo/**/*.html'],
1513
1516
  rules: { '@taiga-ui/experience-next/no-restricted-attr-values': 'off' },
1514
1517
  },
1515
1518
  {
@@ -250369,8 +250372,7 @@ function collectParts(node) {
250369
250372
  }
250370
250373
  function isRootConcat(node) {
250371
250374
  const { parent } = node;
250372
- return (parent.type !== dist$3.AST_NODE_TYPES.BinaryExpression ||
250373
- parent.operator !== '+');
250375
+ return parent.type !== dist$3.AST_NODE_TYPES.BinaryExpression || parent.operator !== '+';
250374
250376
  }
250375
250377
  function isStringType(type, checker) {
250376
250378
  if (type.isUnion()) {
@@ -251895,25 +251897,42 @@ const rule$e = createRule({
251895
251897
  if (!valueSpan) {
251896
251898
  continue;
251897
251899
  }
251898
- const rawValue = sourceText.slice(valueSpan.start.offset, valueSpan.end.offset);
251900
+ let openQuoteOffset = valueSpan.start.offset - 1;
251901
+ while (openQuoteOffset >= 0 &&
251902
+ (sourceText[openQuoteOffset] === ' ' ||
251903
+ sourceText[openQuoteOffset] === '\n' ||
251904
+ sourceText[openQuoteOffset] === '\r' ||
251905
+ sourceText[openQuoteOffset] === '\t')) {
251906
+ openQuoteOffset--;
251907
+ }
251908
+ const openingQuote = sourceText[openQuoteOffset];
251909
+ const isQuotedAttribute = openingQuote === SINGLE_QUOTE ||
251910
+ openingQuote === DOUBLE_QUOTE;
251911
+ let closeQuoteOffset = valueSpan.end.offset;
251912
+ if (isQuotedAttribute) {
251913
+ while (closeQuoteOffset < sourceText.length &&
251914
+ (sourceText[closeQuoteOffset] === ' ' ||
251915
+ sourceText[closeQuoteOffset] === '\n' ||
251916
+ sourceText[closeQuoteOffset] === '\r' ||
251917
+ sourceText[closeQuoteOffset] === '\t')) {
251918
+ closeQuoteOffset++;
251919
+ }
251920
+ }
251921
+ const closingQuote = sourceText[closeQuoteOffset];
251922
+ const hasMatchingQuotes = isQuotedAttribute && openingQuote === closingQuote;
251923
+ const rawValue = hasMatchingQuotes
251924
+ ? sourceText.slice(openQuoteOffset + 1, closeQuoteOffset)
251925
+ : sourceText.slice(valueSpan.start.offset, valueSpan.end.offset);
251899
251926
  if (rawValue.includes(EXPECTED_QUOTE)) {
251900
251927
  continue;
251901
251928
  }
251902
- const openingQuote = sourceText[valueSpan.start.offset - 1];
251903
- const closingQuote = sourceText[valueSpan.end.offset];
251904
- const hasMatchingQuotes = (openingQuote === SINGLE_QUOTE ||
251905
- openingQuote === DOUBLE_QUOTE) &&
251906
- openingQuote === closingQuote;
251907
251929
  if (hasMatchingQuotes && openingQuote !== EXPECTED_QUOTE) {
251908
251930
  context.report({
251909
251931
  data: {
251910
251932
  actual: `single(${openingQuote})`,
251911
251933
  expected: `double(${EXPECTED_QUOTE})`,
251912
251934
  },
251913
- fix: (fixer) => fixer.replaceTextRange([
251914
- valueSpan.start.offset - 1,
251915
- valueSpan.end.offset + 1,
251916
- ], `${EXPECTED_QUOTE}${rawValue}${EXPECTED_QUOTE}`),
251935
+ fix: (fixer) => fixer.replaceTextRange([openQuoteOffset, closeQuoteOffset + 1], `${EXPECTED_QUOTE}${rawValue}${EXPECTED_QUOTE}`),
251917
251936
  loc: sourceSpanToLoc(attr.sourceSpan),
251918
251937
  messageId: MESSAGE_IDS$2.UNEXPECTED,
251919
251938
  });
@@ -252057,17 +252076,24 @@ const rule$b = createRule({
252057
252076
 
252058
252077
  const MESSAGE_ID$4 = 'invalid';
252059
252078
  const VALID_CONTAINERS = new Set(['menu', 'ol', 'ul']);
252079
+ /**
252080
+ * Duck-type check for TmplAstElement — avoids instanceof which breaks when
252081
+ * the plugin's bundled-angular-compiler differs from the one used by the
252082
+ * template parser (e.g. when the plugin is consumed from a different project).
252083
+ */
252084
+ function isElement(node) {
252085
+ return (typeof node === 'object' &&
252086
+ node !== null &&
252087
+ typeof node['name'] === 'string' &&
252088
+ Array.isArray(node['children']));
252089
+ }
252060
252090
  function getClosestParentElement(node) {
252061
- let parent = node.parent;
252062
- while (parent) {
252063
- if (parent instanceof dist$4.TmplAstElement) {
252064
- return parent;
252065
- }
252066
- if (parent instanceof dist$4.TmplAstTemplate) {
252067
- parent = parent.parent;
252068
- continue;
252091
+ let current = node['parent'];
252092
+ while (current !== null && current !== undefined) {
252093
+ if (isElement(current)) {
252094
+ return current;
252069
252095
  }
252070
- break;
252096
+ current = current['parent'];
252071
252097
  }
252072
252098
  return null;
252073
252099
  }
@@ -252166,8 +252192,8 @@ const rule$9 = createRule({
252166
252192
  meta: {
252167
252193
  docs: { description: 'Require a non-empty title element inside head' },
252168
252194
  messages: {
252169
- [MESSAGE_IDS.EMPTY_TITLE]: 'Unexpected empty text in `<title><title/>`',
252170
- [MESSAGE_IDS.MISSING_TITLE]: 'Missing `<title><title/>` in the `<head><head/>`',
252195
+ [MESSAGE_IDS.EMPTY_TITLE]: 'Unexpected empty text in `<title></title>`',
252196
+ [MESSAGE_IDS.MISSING_TITLE]: 'Missing `<title></title>` in the `<head></head>`',
252171
252197
  },
252172
252198
  schema: [],
252173
252199
  type: 'problem',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taiga-ui/eslint-plugin-experience-next",
3
- "version": "0.483.0",
3
+ "version": "0.485.0",
4
4
  "description": "An ESLint plugin to enforce a consistent code styles across taiga-ui projects",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,7 +27,6 @@
27
27
  ],
28
28
  "type": "module",
29
29
  "devDependencies": {
30
- "@typescript-eslint/rule-tester": "8.58.1",
31
30
  "glob": "13.0.6"
32
31
  },
33
32
  "peerDependencies": {
@@ -36,7 +35,6 @@
36
35
  "@smarttools/eslint-plugin-rxjs": "^1.0.22",
37
36
  "@stylistic/eslint-plugin": "^5.10.0",
38
37
  "@types/glob": "*",
39
- "@typescript-eslint/eslint-plugin": "^8.58.1",
40
38
  "angular-eslint": "^20.7.0",
41
39
  "eslint": "^9.39.2",
42
40
  "eslint-config-prettier": "^10.1.7",
@@ -59,7 +57,7 @@
59
57
  "eslint-plugin-unused-imports": "^4.4.1",
60
58
  "glob": "*",
61
59
  "globals": "^17.5.0",
62
- "typescript-eslint": "^8.58.1"
60
+ "typescript-eslint": "^8.59.0"
63
61
  },
64
62
  "publishConfig": {
65
63
  "access": "public"