Compare commits

..

1 Commits

Author SHA1 Message Date
Justin Greywolf
81d00bd4e4 fix: prevent arrow markers from consuming node names starting with o/x
Fixes #2492

The flowchart parser was incorrectly consuming 'o' or 'x' characters from
node names when they appeared after arrows without spaces. For example,
`dev---ops` was parsed as "dev" → "ps" instead of "dev" → "ops".

Changes:
- Modified lexer patterns in flow.jison to distinguish between:
  - Intentional arrow markers (--o, --x) followed by whitespace or uppercase
  - Node names starting with 'o' or 'x' (lowercase continuation)
- Added 10 comprehensive tests to flow-arrows.spec.js covering:
  - Bug cases (dev---ops, dev---xerxes)
  - Backwards compatibility (A--oB, A --o B, etc.)
  - All arrow types (solid, thick, dotted)

The fix uses smart pattern matching:
- `--o ` (with space) → circle arrow marker
- `--oB` (uppercase) → circle arrow marker
- `--ops` (lowercase) → plain arrow, 'ops' is node name

All 24 new tests pass. All 293 existing edge tests pass.
2025-10-17 18:30:18 -07:00
4 changed files with 262 additions and 195 deletions

View File

@@ -69,7 +69,7 @@
"@changesets/cli": "^2.29.7",
"@cspell/eslint-plugin": "^8.19.4",
"@cypress/code-coverage": "^3.14.6",
"@eslint/js": "^9.37.0",
"@eslint/js": "^9.26.0",
"@rollup/plugin-typescript": "^12.1.4",
"@types/cors": "^2.8.19",
"@types/express": "^5.0.3",
@@ -93,7 +93,7 @@
"cypress-image-snapshot": "^4.0.1",
"cypress-split": "^1.24.23",
"esbuild": "^0.25.10",
"eslint": "^9.37.0",
"eslint": "^9.26.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-cypress": "^4.3.0",
"eslint-plugin-html": "^8.1.3",
@@ -126,7 +126,7 @@
"tslib": "^2.8.1",
"tsx": "^4.20.5",
"typescript": "~5.7.3",
"typescript-eslint": "^8.46.1",
"typescript-eslint": "^8.38.0",
"vite": "^7.0.7",
"vite-plugin-istanbul": "^7.0.0",
"vitest": "^3.2.4"

View File

@@ -266,4 +266,156 @@ describe('[Arrows] when parsing', () => {
});
});
});
describe('Issue #2492: Node names starting with o/x should not be consumed by arrow markers', () => {
it('should handle node names starting with "o" after plain arrows', function () {
const res = flow.parser.parse('graph TD;\ndev---ops;');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert.get('dev').id).toBe('dev');
expect(vert.get('ops').id).toBe('ops');
expect(edges.length).toBe(1);
expect(edges[0].start).toBe('dev');
expect(edges[0].end).toBe('ops');
expect(edges[0].type).toBe('arrow_open');
expect(edges[0].stroke).toBe('normal');
});
it('should handle node names starting with "x" after plain arrows', function () {
const res = flow.parser.parse('graph TD;\ndev---xerxes;');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert.get('dev').id).toBe('dev');
expect(vert.get('xerxes').id).toBe('xerxes');
expect(edges.length).toBe(1);
expect(edges[0].start).toBe('dev');
expect(edges[0].end).toBe('xerxes');
expect(edges[0].type).toBe('arrow_open');
expect(edges[0].stroke).toBe('normal');
});
it('should still support circle arrows with spaces', function () {
const res = flow.parser.parse('graph TD;\nA --o B;');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert.get('A').id).toBe('A');
expect(vert.get('B').id).toBe('B');
expect(edges.length).toBe(1);
expect(edges[0].start).toBe('A');
expect(edges[0].end).toBe('B');
expect(edges[0].type).toBe('arrow_circle');
expect(edges[0].stroke).toBe('normal');
});
it('should still support cross arrows with spaces', function () {
const res = flow.parser.parse('graph TD;\nC --x D;');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert.get('C').id).toBe('C');
expect(vert.get('D').id).toBe('D');
expect(edges.length).toBe(1);
expect(edges[0].start).toBe('C');
expect(edges[0].end).toBe('D');
expect(edges[0].type).toBe('arrow_cross');
expect(edges[0].stroke).toBe('normal');
});
it('should support circle arrows to uppercase nodes without spaces', function () {
const res = flow.parser.parse('graph TD;\nA--oB;');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert.get('A').id).toBe('A');
expect(vert.get('B').id).toBe('B');
expect(edges.length).toBe(1);
expect(edges[0].start).toBe('A');
expect(edges[0].end).toBe('B');
expect(edges[0].type).toBe('arrow_circle');
expect(edges[0].stroke).toBe('normal');
});
it('should support cross arrows to uppercase nodes without spaces', function () {
const res = flow.parser.parse('graph TD;\nA--xBar;');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert.get('A').id).toBe('A');
expect(vert.get('Bar').id).toBe('Bar');
expect(edges.length).toBe(1);
expect(edges[0].start).toBe('A');
expect(edges[0].end).toBe('Bar');
expect(edges[0].type).toBe('arrow_cross');
expect(edges[0].stroke).toBe('normal');
});
it('should handle thick arrows with lowercase node names starting with "o"', function () {
const res = flow.parser.parse('graph TD;\nalpha===omega;');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert.get('alpha').id).toBe('alpha');
expect(vert.get('omega').id).toBe('omega');
expect(edges.length).toBe(1);
expect(edges[0].start).toBe('alpha');
expect(edges[0].end).toBe('omega');
expect(edges[0].type).toBe('arrow_open');
expect(edges[0].stroke).toBe('thick');
});
it('should handle dotted arrows with lowercase node names starting with "o"', function () {
const res = flow.parser.parse('graph TD;\nfoo-.-opus;');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert.get('foo').id).toBe('foo');
expect(vert.get('opus').id).toBe('opus');
expect(edges.length).toBe(1);
expect(edges[0].start).toBe('foo');
expect(edges[0].end).toBe('opus');
expect(edges[0].type).toBe('arrow_open');
expect(edges[0].stroke).toBe('dotted');
});
it('should still support dotted circle arrows with spaces', function () {
const res = flow.parser.parse('graph TD;\nB -.-o C;');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert.get('B').id).toBe('B');
expect(vert.get('C').id).toBe('C');
expect(edges.length).toBe(1);
expect(edges[0].start).toBe('B');
expect(edges[0].end).toBe('C');
expect(edges[0].type).toBe('arrow_circle');
expect(edges[0].stroke).toBe('dotted');
});
it('should still support thick cross arrows with spaces', function () {
const res = flow.parser.parse('graph TD;\nC ==x D;');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert.get('C').id).toBe('C');
expect(vert.get('D').id).toBe('D');
expect(edges.length).toBe(1);
expect(edges[0].start).toBe('C');
expect(edges[0].end).toBe('D');
expect(edges[0].type).toBe('arrow_cross');
expect(edges[0].stroke).toBe('thick');
});
});
});

View File

@@ -152,17 +152,23 @@ that id.
"," return 'COMMA';
"*" return 'MULT';
<INITIAL,edgeText>\s*[xo<]?\-\-+[-xo>]\s* { this.popState(); return 'LINK'; }
<INITIAL>\s*[xo<]?\-\-\s* { this.pushState("edgeText"); return 'START_LINK'; }
<edgeText>[^-]|\-(?!\-)+ return 'EDGE_TEXT';
<INITIAL,edgeText>\s*[xo<]?\-\-+[xo>]\s+ { this.popState(); return 'LINK'; }
<INITIAL,edgeText>\s*[xo<]?\-\-+[xo>](?=[A-Z]) { this.popState(); return 'LINK'; }
<INITIAL,edgeText>\s*[xo<]?\-\-+[-]\s* { this.popState(); return 'LINK'; }
<INITIAL>\s*[xo<]?\-\-\s* { this.pushState("edgeText"); return 'START_LINK'; }
<edgeText>[^-]|\-(?!\-)+ return 'EDGE_TEXT';
<INITIAL,thickEdgeText>\s*[xo<]?\=\=+[=xo>]\s* { this.popState(); return 'LINK'; }
<INITIAL>\s*[xo<]?\=\=\s* { this.pushState("thickEdgeText"); return 'START_LINK'; }
<thickEdgeText>[^=]|\=(?!=) return 'EDGE_TEXT';
<INITIAL,thickEdgeText>\s*[xo<]?\=\=+[xo>]\s+ { this.popState(); return 'LINK'; }
<INITIAL,thickEdgeText>\s*[xo<]?\=\=+[xo>](?=[A-Z]) { this.popState(); return 'LINK'; }
<INITIAL,thickEdgeText>\s*[xo<]?\=\=+[=]\s* { this.popState(); return 'LINK'; }
<INITIAL>\s*[xo<]?\=\=\s* { this.pushState("thickEdgeText"); return 'START_LINK'; }
<thickEdgeText>[^=]|\=(?!=) return 'EDGE_TEXT';
<INITIAL,dottedEdgeText>\s*[xo<]?\-?\.+\-[xo>]?\s* { this.popState(); return 'LINK'; }
<INITIAL>\s*[xo<]?\-\.\s* { this.pushState("dottedEdgeText"); return 'START_LINK'; }
<dottedEdgeText>[^\.]|\.(?!-) return 'EDGE_TEXT';
<INITIAL,dottedEdgeText>\s*[xo<]?\-?\.+\-[xo>]\s+ { this.popState(); return 'LINK'; }
<INITIAL,dottedEdgeText>\s*[xo<]?\-?\.+\-[xo>](?=[A-Z]) { this.popState(); return 'LINK'; }
<INITIAL,dottedEdgeText>\s*[xo<]?\-?\.+\-\s* { this.popState(); return 'LINK'; }
<INITIAL>\s*[xo<]?\-\.\s* { this.pushState("dottedEdgeText"); return 'START_LINK'; }
<dottedEdgeText>[^\.]|\.(?!-) return 'EDGE_TEXT';
<*>\s*\~\~[\~]+\s* return 'LINK';

275
pnpm-lock.yaml generated
View File

@@ -27,13 +27,13 @@ importers:
version: 2.29.7(@types/node@22.18.6)
'@cspell/eslint-plugin':
specifier: ^8.19.4
version: 8.19.4(eslint@9.37.0(jiti@2.5.1))
version: 8.19.4(eslint@9.35.0(jiti@2.5.1))
'@cypress/code-coverage':
specifier: ^3.14.6
version: 3.14.6(@babel/core@7.28.4)(@babel/preset-env@7.28.3(@babel/core@7.28.4))(babel-loader@10.0.0(@babel/core@7.28.4)(webpack@5.101.3(esbuild@0.25.10)))(cypress@14.5.4)(webpack@5.101.3(esbuild@0.25.10))
'@eslint/js':
specifier: ^9.37.0
version: 9.37.0
specifier: ^9.26.0
version: 9.35.0
'@rollup/plugin-typescript':
specifier: ^12.1.4
version: 12.1.4(rollup@4.50.2)(tslib@2.8.1)(typescript@5.7.3)
@@ -104,32 +104,32 @@ importers:
specifier: ^0.25.10
version: 0.25.10
eslint:
specifier: ^9.37.0
version: 9.37.0(jiti@2.5.1)
specifier: ^9.26.0
version: 9.35.0(jiti@2.5.1)
eslint-config-prettier:
specifier: ^10.1.8
version: 10.1.8(eslint@9.37.0(jiti@2.5.1))
version: 10.1.8(eslint@9.35.0(jiti@2.5.1))
eslint-plugin-cypress:
specifier: ^4.3.0
version: 4.3.0(eslint@9.37.0(jiti@2.5.1))
version: 4.3.0(eslint@9.35.0(jiti@2.5.1))
eslint-plugin-html:
specifier: ^8.1.3
version: 8.1.3
eslint-plugin-jest:
specifier: ^28.14.0
version: 28.14.0(@typescript-eslint/eslint-plugin@8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.37.0(jiti@2.5.1))(jest@30.1.3(@types/node@22.18.6))(typescript@5.7.3)
version: 28.14.0(@typescript-eslint/eslint-plugin@8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.35.0(jiti@2.5.1))(jest@30.1.3(@types/node@22.18.6))(typescript@5.7.3)
eslint-plugin-jsdoc:
specifier: ^50.8.0
version: 50.8.0(eslint@9.37.0(jiti@2.5.1))
version: 50.8.0(eslint@9.35.0(jiti@2.5.1))
eslint-plugin-json:
specifier: ^4.0.1
version: 4.0.1
eslint-plugin-lodash:
specifier: ^8.0.0
version: 8.0.0(eslint@9.37.0(jiti@2.5.1))
version: 8.0.0(eslint@9.35.0(jiti@2.5.1))
eslint-plugin-markdown:
specifier: ^5.1.0
version: 5.1.0(eslint@9.37.0(jiti@2.5.1))
version: 5.1.0(eslint@9.35.0(jiti@2.5.1))
eslint-plugin-no-only-tests:
specifier: ^3.3.0
version: 3.3.0
@@ -138,7 +138,7 @@ importers:
version: 0.4.0
eslint-plugin-unicorn:
specifier: ^59.0.1
version: 59.0.1(eslint@9.37.0(jiti@2.5.1))
version: 59.0.1(eslint@9.35.0(jiti@2.5.1))
express:
specifier: ^5.1.0
version: 5.1.0
@@ -203,8 +203,8 @@ importers:
specifier: ~5.7.3
version: 5.7.3
typescript-eslint:
specifier: ^8.46.1
version: 8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)
specifier: ^8.38.0
version: 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)
vite:
specifier: ^7.0.7
version: 7.1.5(@types/node@22.18.6)(jiti@2.5.1)(terser@5.44.0)(tsx@4.20.5)(yaml@2.8.1)
@@ -2161,24 +2161,24 @@ packages:
resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/config-helpers@0.4.0':
resolution: {integrity: sha512-WUFvV4WoIwW8Bv0KeKCIIEgdSiFOsulyN0xrMu+7z43q/hkOLXjvb5u7UC9jDxvRzcrbEmuZBX5yJZz1741jog==}
'@eslint/config-helpers@0.3.1':
resolution: {integrity: sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/core@0.13.0':
resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/core@0.16.0':
resolution: {integrity: sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==}
'@eslint/core@0.15.2':
resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/eslintrc@3.3.1':
resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/js@9.37.0':
resolution: {integrity: sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==}
'@eslint/js@9.35.0':
resolution: {integrity: sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/object-schema@2.1.6':
@@ -2189,8 +2189,8 @@ packages:
resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/plugin-kit@0.4.0':
resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==}
'@eslint/plugin-kit@0.3.5':
resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@fastify/ajv-compiler@3.6.0':
@@ -3242,16 +3242,16 @@ packages:
'@types/yauzl@2.10.3':
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
'@typescript-eslint/eslint-plugin@8.46.1':
resolution: {integrity: sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==}
'@typescript-eslint/eslint-plugin@8.43.0':
resolution: {integrity: sha512-8tg+gt7ENL7KewsKMKDHXR1vm8tt9eMxjJBYINf6swonlWgkYn5NwyIgXpbbDxTNU5DgpDFfj95prcTq2clIQQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
'@typescript-eslint/parser': ^8.46.1
'@typescript-eslint/parser': ^8.43.0
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/parser@8.46.1':
resolution: {integrity: sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==}
'@typescript-eslint/parser@8.43.0':
resolution: {integrity: sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@@ -3263,34 +3263,18 @@ packages:
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/project-service@8.46.1':
resolution: {integrity: sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/scope-manager@8.43.0':
resolution: {integrity: sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/scope-manager@8.46.1':
resolution: {integrity: sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/tsconfig-utils@8.43.0':
resolution: {integrity: sha512-ALC2prjZcj2YqqL5X/bwWQmHA2em6/94GcbB/KKu5SX3EBDOsqztmmX1kMkvAJHzxk7TazKzJfFiEIagNV3qEA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/tsconfig-utils@8.46.1':
resolution: {integrity: sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/type-utils@8.46.1':
resolution: {integrity: sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw==}
'@typescript-eslint/type-utils@8.43.0':
resolution: {integrity: sha512-qaH1uLBpBuBBuRf8c1mLJ6swOfzCXryhKND04Igr4pckzSEW9JX5Aw9AgW00kwfjWJF0kk0ps9ExKTfvXfw4Qg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@@ -3300,22 +3284,12 @@ packages:
resolution: {integrity: sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/types@8.46.1':
resolution: {integrity: sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/typescript-estree@8.43.0':
resolution: {integrity: sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/typescript-estree@8.46.1':
resolution: {integrity: sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/utils@8.43.0':
resolution: {integrity: sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -3323,21 +3297,10 @@ packages:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/utils@8.46.1':
resolution: {integrity: sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/visitor-keys@8.43.0':
resolution: {integrity: sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/visitor-keys@8.46.1':
resolution: {integrity: sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@ungap/structured-clone@1.3.0':
resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
@@ -5476,8 +5439,8 @@ packages:
resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
eslint@9.37.0:
resolution: {integrity: sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==}
eslint@9.35.0:
resolution: {integrity: sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
hasBin: true
peerDependencies:
@@ -9182,8 +9145,8 @@ packages:
peerDependencies:
typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x
typescript-eslint@8.46.1:
resolution: {integrity: sha512-VHgijW803JafdSsDO8I761r3SHrgk4T00IdyQ+/UsthtgPRsBWQLqoSxOolxTpxRKi1kGXK0bSz4CoAc9ObqJA==}
typescript-eslint@8.43.0:
resolution: {integrity: sha512-FyRGJKUGvcFekRRcBKFBlAhnp4Ng8rhe8tuvvkR9OiU0gfd4vyvTRQHEckO6VDlH57jbeUQem2IpqPq9kLJH+w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@@ -11591,12 +11554,12 @@ snapshots:
'@cspell/url': 9.2.1
import-meta-resolve: 4.2.0
'@cspell/eslint-plugin@8.19.4(eslint@9.37.0(jiti@2.5.1))':
'@cspell/eslint-plugin@8.19.4(eslint@9.35.0(jiti@2.5.1))':
dependencies:
'@cspell/cspell-types': 8.19.4
'@cspell/url': 8.19.4
cspell-lib: 8.19.4
eslint: 9.37.0(jiti@2.5.1)
eslint: 9.35.0(jiti@2.5.1)
synckit: 0.11.11
'@cspell/filetypes@8.19.4': {}
@@ -11893,9 +11856,9 @@ snapshots:
'@esbuild/win32-x64@0.25.10':
optional: true
'@eslint-community/eslint-utils@4.9.0(eslint@9.37.0(jiti@2.5.1))':
'@eslint-community/eslint-utils@4.9.0(eslint@9.35.0(jiti@2.5.1))':
dependencies:
eslint: 9.37.0(jiti@2.5.1)
eslint: 9.35.0(jiti@2.5.1)
eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.12.1': {}
@@ -11908,15 +11871,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@eslint/config-helpers@0.4.0':
dependencies:
'@eslint/core': 0.16.0
'@eslint/config-helpers@0.3.1': {}
'@eslint/core@0.13.0':
dependencies:
'@types/json-schema': 7.0.15
'@eslint/core@0.16.0':
'@eslint/core@0.15.2':
dependencies:
'@types/json-schema': 7.0.15
@@ -11934,7 +11895,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@eslint/js@9.37.0': {}
'@eslint/js@9.35.0': {}
'@eslint/object-schema@2.1.6': {}
@@ -11943,9 +11904,9 @@ snapshots:
'@eslint/core': 0.13.0
levn: 0.4.1
'@eslint/plugin-kit@0.4.0':
'@eslint/plugin-kit@0.3.5':
dependencies:
'@eslint/core': 0.16.0
'@eslint/core': 0.15.2
levn: 0.4.1
'@fastify/ajv-compiler@3.6.0':
@@ -13158,15 +13119,15 @@ snapshots:
'@types/node': 22.18.6
optional: true
'@typescript-eslint/eslint-plugin@8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)':
'@typescript-eslint/eslint-plugin@8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)':
dependencies:
'@eslint-community/regexpp': 4.12.1
'@typescript-eslint/parser': 8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)
'@typescript-eslint/scope-manager': 8.46.1
'@typescript-eslint/type-utils': 8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)
'@typescript-eslint/utils': 8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)
'@typescript-eslint/visitor-keys': 8.46.1
eslint: 9.37.0(jiti@2.5.1)
'@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)
'@typescript-eslint/scope-manager': 8.43.0
'@typescript-eslint/type-utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)
'@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)
'@typescript-eslint/visitor-keys': 8.43.0
eslint: 9.35.0(jiti@2.5.1)
graphemer: 1.4.0
ignore: 7.0.5
natural-compare: 1.4.0
@@ -13175,14 +13136,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)':
'@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)':
dependencies:
'@typescript-eslint/scope-manager': 8.46.1
'@typescript-eslint/types': 8.46.1
'@typescript-eslint/typescript-estree': 8.46.1(typescript@5.7.3)
'@typescript-eslint/visitor-keys': 8.46.1
'@typescript-eslint/scope-manager': 8.43.0
'@typescript-eslint/types': 8.43.0
'@typescript-eslint/typescript-estree': 8.43.0(typescript@5.7.3)
'@typescript-eslint/visitor-keys': 8.43.0
debug: 4.4.3(supports-color@8.1.1)
eslint: 9.37.0(jiti@2.5.1)
eslint: 9.35.0(jiti@2.5.1)
typescript: 5.7.3
transitivePeerDependencies:
- supports-color
@@ -13196,40 +13157,22 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/project-service@8.46.1(typescript@5.7.3)':
dependencies:
'@typescript-eslint/tsconfig-utils': 8.46.1(typescript@5.7.3)
'@typescript-eslint/types': 8.46.1
debug: 4.4.3(supports-color@8.1.1)
typescript: 5.7.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/scope-manager@8.43.0':
dependencies:
'@typescript-eslint/types': 8.43.0
'@typescript-eslint/visitor-keys': 8.43.0
'@typescript-eslint/scope-manager@8.46.1':
dependencies:
'@typescript-eslint/types': 8.46.1
'@typescript-eslint/visitor-keys': 8.46.1
'@typescript-eslint/tsconfig-utils@8.43.0(typescript@5.7.3)':
dependencies:
typescript: 5.7.3
'@typescript-eslint/tsconfig-utils@8.46.1(typescript@5.7.3)':
'@typescript-eslint/type-utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)':
dependencies:
typescript: 5.7.3
'@typescript-eslint/type-utils@8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)':
dependencies:
'@typescript-eslint/types': 8.46.1
'@typescript-eslint/typescript-estree': 8.46.1(typescript@5.7.3)
'@typescript-eslint/utils': 8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)
'@typescript-eslint/types': 8.43.0
'@typescript-eslint/typescript-estree': 8.43.0(typescript@5.7.3)
'@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)
debug: 4.4.3(supports-color@8.1.1)
eslint: 9.37.0(jiti@2.5.1)
eslint: 9.35.0(jiti@2.5.1)
ts-api-utils: 2.1.0(typescript@5.7.3)
typescript: 5.7.3
transitivePeerDependencies:
@@ -13237,8 +13180,6 @@ snapshots:
'@typescript-eslint/types@8.43.0': {}
'@typescript-eslint/types@8.46.1': {}
'@typescript-eslint/typescript-estree@8.43.0(typescript@5.7.3)':
dependencies:
'@typescript-eslint/project-service': 8.43.0(typescript@5.7.3)
@@ -13255,40 +13196,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/typescript-estree@8.46.1(typescript@5.7.3)':
'@typescript-eslint/utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)':
dependencies:
'@typescript-eslint/project-service': 8.46.1(typescript@5.7.3)
'@typescript-eslint/tsconfig-utils': 8.46.1(typescript@5.7.3)
'@typescript-eslint/types': 8.46.1
'@typescript-eslint/visitor-keys': 8.46.1
debug: 4.4.3(supports-color@8.1.1)
fast-glob: 3.3.3
is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.7.2
ts-api-utils: 2.1.0(typescript@5.7.3)
typescript: 5.7.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@8.43.0(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)':
dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.5.1))
'@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1))
'@typescript-eslint/scope-manager': 8.43.0
'@typescript-eslint/types': 8.43.0
'@typescript-eslint/typescript-estree': 8.43.0(typescript@5.7.3)
eslint: 9.37.0(jiti@2.5.1)
typescript: 5.7.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)':
dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.5.1))
'@typescript-eslint/scope-manager': 8.46.1
'@typescript-eslint/types': 8.46.1
'@typescript-eslint/typescript-estree': 8.46.1(typescript@5.7.3)
eslint: 9.37.0(jiti@2.5.1)
eslint: 9.35.0(jiti@2.5.1)
typescript: 5.7.3
transitivePeerDependencies:
- supports-color
@@ -13298,11 +13212,6 @@ snapshots:
'@typescript-eslint/types': 8.43.0
eslint-visitor-keys: 4.2.1
'@typescript-eslint/visitor-keys@8.46.1':
dependencies:
'@typescript-eslint/types': 8.46.1
eslint-visitor-keys: 4.2.1
'@ungap/structured-clone@1.3.0': {}
'@unocss/astro@66.5.1(vite@7.1.5(@types/node@22.18.6)(jiti@2.5.1)(terser@5.44.0)(tsx@4.20.5)(yaml@2.8.1))':
@@ -15779,38 +15688,38 @@ snapshots:
optionalDependencies:
source-map: 0.6.1
eslint-config-prettier@10.1.8(eslint@9.37.0(jiti@2.5.1)):
eslint-config-prettier@10.1.8(eslint@9.35.0(jiti@2.5.1)):
dependencies:
eslint: 9.37.0(jiti@2.5.1)
eslint: 9.35.0(jiti@2.5.1)
eslint-plugin-cypress@4.3.0(eslint@9.37.0(jiti@2.5.1)):
eslint-plugin-cypress@4.3.0(eslint@9.35.0(jiti@2.5.1)):
dependencies:
eslint: 9.37.0(jiti@2.5.1)
eslint: 9.35.0(jiti@2.5.1)
globals: 15.15.0
eslint-plugin-html@8.1.3:
dependencies:
htmlparser2: 10.0.0
eslint-plugin-jest@28.14.0(@typescript-eslint/eslint-plugin@8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.37.0(jiti@2.5.1))(jest@30.1.3(@types/node@22.18.6))(typescript@5.7.3):
eslint-plugin-jest@28.14.0(@typescript-eslint/eslint-plugin@8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.35.0(jiti@2.5.1))(jest@30.1.3(@types/node@22.18.6))(typescript@5.7.3):
dependencies:
'@typescript-eslint/utils': 8.43.0(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)
eslint: 9.37.0(jiti@2.5.1)
'@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)
eslint: 9.35.0(jiti@2.5.1)
optionalDependencies:
'@typescript-eslint/eslint-plugin': 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)
'@typescript-eslint/eslint-plugin': 8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)
jest: 30.1.3(@types/node@22.18.6)
transitivePeerDependencies:
- supports-color
- typescript
eslint-plugin-jsdoc@50.8.0(eslint@9.37.0(jiti@2.5.1)):
eslint-plugin-jsdoc@50.8.0(eslint@9.35.0(jiti@2.5.1)):
dependencies:
'@es-joy/jsdoccomment': 0.50.2
are-docs-informative: 0.0.2
comment-parser: 1.4.1
debug: 4.4.3(supports-color@8.1.1)
escape-string-regexp: 4.0.0
eslint: 9.37.0(jiti@2.5.1)
eslint: 9.35.0(jiti@2.5.1)
espree: 10.4.0
esquery: 1.6.0
parse-imports-exports: 0.2.4
@@ -15824,14 +15733,14 @@ snapshots:
lodash: 4.17.21
vscode-json-languageservice: 4.2.1
eslint-plugin-lodash@8.0.0(eslint@9.37.0(jiti@2.5.1)):
eslint-plugin-lodash@8.0.0(eslint@9.35.0(jiti@2.5.1)):
dependencies:
eslint: 9.37.0(jiti@2.5.1)
eslint: 9.35.0(jiti@2.5.1)
lodash: 4.17.21
eslint-plugin-markdown@5.1.0(eslint@9.37.0(jiti@2.5.1)):
eslint-plugin-markdown@5.1.0(eslint@9.35.0(jiti@2.5.1)):
dependencies:
eslint: 9.37.0(jiti@2.5.1)
eslint: 9.35.0(jiti@2.5.1)
mdast-util-from-markdown: 0.8.5
transitivePeerDependencies:
- supports-color
@@ -15843,15 +15752,15 @@ snapshots:
'@microsoft/tsdoc': 0.15.1
'@microsoft/tsdoc-config': 0.17.1
eslint-plugin-unicorn@59.0.1(eslint@9.37.0(jiti@2.5.1)):
eslint-plugin-unicorn@59.0.1(eslint@9.35.0(jiti@2.5.1)):
dependencies:
'@babel/helper-validator-identifier': 7.27.1
'@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.5.1))
'@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1))
'@eslint/plugin-kit': 0.2.8
ci-info: 4.3.0
clean-regexp: 1.0.0
core-js-compat: 3.45.1
eslint: 9.37.0(jiti@2.5.1)
eslint: 9.35.0(jiti@2.5.1)
esquery: 1.6.0
find-up-simple: 1.0.1
globals: 16.4.0
@@ -15878,16 +15787,16 @@ snapshots:
eslint-visitor-keys@4.2.1: {}
eslint@9.37.0(jiti@2.5.1):
eslint@9.35.0(jiti@2.5.1):
dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.5.1))
'@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1))
'@eslint-community/regexpp': 4.12.1
'@eslint/config-array': 0.21.0
'@eslint/config-helpers': 0.4.0
'@eslint/core': 0.16.0
'@eslint/config-helpers': 0.3.1
'@eslint/core': 0.15.2
'@eslint/eslintrc': 3.3.1
'@eslint/js': 9.37.0
'@eslint/plugin-kit': 0.4.0
'@eslint/js': 9.35.0
'@eslint/plugin-kit': 0.3.5
'@humanfs/node': 0.16.7
'@humanwhocodes/module-importer': 1.0.1
'@humanwhocodes/retry': 0.4.3
@@ -20357,13 +20266,13 @@ snapshots:
typescript: 5.7.3
yaml: 2.8.1
typescript-eslint@8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3):
typescript-eslint@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3):
dependencies:
'@typescript-eslint/eslint-plugin': 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)
'@typescript-eslint/parser': 8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)
'@typescript-eslint/typescript-estree': 8.46.1(typescript@5.7.3)
'@typescript-eslint/utils': 8.46.1(eslint@9.37.0(jiti@2.5.1))(typescript@5.7.3)
eslint: 9.37.0(jiti@2.5.1)
'@typescript-eslint/eslint-plugin': 8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3))(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)
'@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)
'@typescript-eslint/typescript-estree': 8.43.0(typescript@5.7.3)
'@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.7.3)
eslint: 9.35.0(jiti@2.5.1)
typescript: 5.7.3
transitivePeerDependencies:
- supports-color