From a1181c3f83851911a512cbdde94dde62528932d2 Mon Sep 17 00:00:00 2001 From: Benjamin Ramser Date: Sat, 28 Sep 2024 14:50:20 +0200 Subject: [PATCH] =?UTF-8?q?chore(deps-dev):=20=F0=9F=94=A7=20fix=20linting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eslint.config.mjs | 21 +++ package.json | 29 +++- src/Client.ts | 9 +- src/Follower.ts | 4 +- src/Tile38.ts | 4 +- src/commands/Executable.ts | 1 - src/commands/Get.ts | 8 +- src/commands/Intersects.ts | 12 +- src/commands/Scan.ts | 6 +- src/commands/Search.ts | 2 +- src/commands/Set.ts | 3 + src/commands/Whereable.ts | 2 +- src/errors.ts | 1 - src/events.ts | 11 +- src/parseResponse.ts | 6 +- src/responses.ts | 17 ++- src/specs.ts | 61 ++------ src/tests/channel.test.ts | 52 +++---- src/tests/events.test.ts | 2 +- src/tests/intersects-all.test.ts | 2 +- src/tests/leader.test.ts | 2 +- yarn.lock | 239 ++++++++++++++++++------------- 22 files changed, 271 insertions(+), 223 deletions(-) create mode 100644 eslint.config.mjs diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..cb7246e --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,21 @@ +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + { + ignores: ['eslint.config.mjs', 'node_modules', 'dist'], + }, + { + languageOptions: { + parserOptions: { + warnOnUnsupportedTypeScriptVersion: false, + projectService: true, + tsconfigRootDir: import.meta.dirname, + project: ['./tsconfig.eslint.json'], + }, + }, + }, + eslint.configs.recommended, + ...tseslint.configs.strictTypeChecked, + ...tseslint.configs.stylisticTypeChecked +); diff --git a/package.json b/package.json index 358b991..3add7c2 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,9 @@ "version": "2.4.0", "description": "A Node.js Tile38 client written in TypeScript", "main": "dist/index.js", - "files": ["dist"], + "files": [ + "dist" + ], "typings": "dist/index.d.ts", "repository": { "type": "git", @@ -13,9 +15,16 @@ "access": "public" }, "author": "B. Ramser ", - "contributors": ["V. Priem "], + "contributors": [ + "V. Priem " + ], "license": "MIT", - "keywords": ["tile38", "geofence", "geo-spatial", "database"], + "keywords": [ + "tile38", + "geofence", + "geo-spatial", + "database" + ], "engines": { "node": ">=20.x", "yarn": "^1.22.x" @@ -28,7 +37,7 @@ "build": "tsc -p tsconfig.build.json", "build:watch": "tsc --watch -p tsconfig.build.json", "clean": "rimraf {dist,tsconfig.tsbuildinfo,yarn-error.log,coverage}", - "lint": "eslint --ext .ts ./src", + "lint": "eslint ./src", "test": "jest --runInBand", "format": "prettier --write src/{*.ts,**/*.ts}", "u": "yarn upgrade-interactive --latest", @@ -43,11 +52,13 @@ "devDependencies": { "@commitlint/cli": "19.5.0", "@commitlint/config-conventional": "19.5.0", + "@eslint/js": "9.11.1", "@semantic-release/changelog": "6.0.3", "@semantic-release/git": "10.0.1", "@semantic-release/github": "11.0.0", "@semantic-release/npm": "12.0.1", "@semantic-release/release-notes-generator": "14.0.1", + "@types/eslint__js": "8.42.3", "@types/jest": "29.5.13", "@types/node": "22.7.4", "@typescript-eslint/eslint-plugin": "8.7.0", @@ -55,7 +66,7 @@ "conventional-changelog-conventionalcommits": "8.0.0", "coveralls": "3.1.1", "devmoji": "2.3.0", - "eslint": "8.57.0", + "eslint": "9.11.1", "eslint-config-airbnb-base": "15.0.0", "eslint-config-prettier": "9.1.0", "eslint-import-resolver-typescript": "3.6.3", @@ -69,9 +80,13 @@ "rimraf": "6.0.1", "semantic-release": "24.1.2", "ts-jest": "29.2.5", - "typescript": "5.6.2" + "typescript": "5.6.2", + "typescript-eslint": "8.7.0" }, "lint-staged": { - "*.ts": ["eslint --fix", "prettier --write"] + "*.ts": [ + "eslint --fix", + "prettier --write" + ] } } diff --git a/src/Client.ts b/src/Client.ts index ec5af4c..0ccbed1 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -1,3 +1,6 @@ +/* eslint-disable @typescript-eslint/use-unknown-in-catch-callback-variable */ +/* eslint-disable @typescript-eslint/no-confusing-void-expression */ + import EventEmitter from 'events'; import { Redis, RedisOptions } from 'ioredis'; import { forwardEvents } from './events'; @@ -89,7 +92,7 @@ export enum SubCommand { export type ConstructorArgs = (string | number | RedisOptions | undefined)[]; -export type CommandArgs = Array; +export type CommandArgs = (SubCommand | string | number | object)[]; enum Format { RESP = 'resp', @@ -97,7 +100,7 @@ enum Format { } const toString = (s: string | number): string => - typeof s === 'string' ? s : `${s}`; + typeof s === 'string' ? s : s.toString(); const applyDefaults = (args: ConstructorArgs) => { const options = args.find((arg) => typeof arg === 'object'); @@ -153,7 +156,7 @@ export class Client extends EventEmitter { ): Promise { return this.redis.call( command, - ...(args || []).map(toString) + ...(args ?? []).map(toString) ) as Promise; } diff --git a/src/Follower.ts b/src/Follower.ts index 57960c3..23ce6aa 100644 --- a/src/Follower.ts +++ b/src/Follower.ts @@ -42,12 +42,10 @@ import { export class Follower extends EventEmitter implements FollowerInterface { readonly client: Client; - constructor(port: number, options?: Tile38Options); + constructor(port: string | number, options?: Tile38Options); constructor(port: number, host: string, options?: Tile38Options); - constructor(path: string, options?: Tile38Options); - constructor(options?: Tile38Options); constructor(...args: ConstructorArgs) { diff --git a/src/Tile38.ts b/src/Tile38.ts index 7e12f2f..61ac0dc 100644 --- a/src/Tile38.ts +++ b/src/Tile38.ts @@ -7,11 +7,9 @@ import { FollowerInterface, Tile38Options } from './specs'; export class Tile38 extends Leader { readonly _follower?: Follower; - constructor(port: number, options?: Tile38Options); - constructor(port: number, host: string, options?: Tile38Options); - constructor(path: string, options?: Tile38Options); + constructor(path: number | string, options?: Tile38Options); constructor(path?: string, followerPath?: string, options?: Tile38Options); diff --git a/src/commands/Executable.ts b/src/commands/Executable.ts index 8ddd5ed..b3e976c 100644 --- a/src/commands/Executable.ts +++ b/src/commands/Executable.ts @@ -8,7 +8,6 @@ export interface Compilable { export class Executable extends WithClient implements Compilable { // istanbul ignore next - // eslint-disable-next-line class-methods-use-this compile(): [Command, CommandArgs] { // istanbul ignore next throw new Error('Not implemented'); diff --git a/src/commands/Get.ts b/src/commands/Get.ts index 665fa4c..334c688 100644 --- a/src/commands/Get.ts +++ b/src/commands/Get.ts @@ -59,7 +59,11 @@ export class Get extends Executable implements GetInterface { if (format === SubCommand.OBJECT) { this._output = undefined; } else if (format === SubCommand.HASH) { - this._output = [format, precision as number]; + /* istanbul ignore if */ + if (typeof precision == 'undefined') { + throw Error('HASHES output requires hash precision'); + } + this._output = [format, precision]; } else { this._output = [format]; } @@ -103,7 +107,7 @@ export class Get extends Executable implements GetInterface { this._key, this._id, ...(this._withFields ? [SubCommand.WITHFIELDS] : []), - ...(this._output || []), + ...(this._output ?? []), ], ]; } diff --git a/src/commands/Intersects.ts b/src/commands/Intersects.ts index 9748cc8..e6ea00b 100644 --- a/src/commands/Intersects.ts +++ b/src/commands/Intersects.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-type-parameters */ + import { GeoJSON } from '@vpriem/geojson'; import { Compilable } from './Executable'; import { Whereable } from './Whereable'; @@ -213,7 +215,11 @@ export class Intersects extends Whereable implements IntersectsInterface { if (format === SubCommand.OBJECTS) { this._output = undefined; } else if (format === SubCommand.HASHES) { - this._output = [format, precision as number]; + /* istanbul ignore if */ + if (typeof precision == 'undefined') { + throw Error('HASHES output requires hash precision'); + } + this._output = [format, precision]; } else { this._output = [format]; } @@ -342,8 +348,8 @@ export class Intersects extends Whereable implements IntersectsInterface { ...this.compileFence(), ...super.compileWhere(), ...super.compileWherein(), - ...(this._output || []), - ...(this._query || []), + ...(this._output ?? []), + ...(this._query ?? []), ], ]; diff --git a/src/commands/Scan.ts b/src/commands/Scan.ts index 5211be5..7f0f2d6 100644 --- a/src/commands/Scan.ts +++ b/src/commands/Scan.ts @@ -28,7 +28,11 @@ export class Scan extends Search implements ScanInterface { if (format === SubCommand.OBJECTS) { this._output = undefined; } else if (format === SubCommand.HASHES) { - this._output = [format, precision as number]; + /* istanbul ignore if */ + if (typeof precision == 'undefined') { + throw Error('HASHES output requires hash precision'); + } + this._output = [format, precision]; } else { this._output = [format]; } diff --git a/src/commands/Search.ts b/src/commands/Search.ts index 6e5196a..99e3071 100644 --- a/src/commands/Search.ts +++ b/src/commands/Search.ts @@ -151,7 +151,7 @@ export class Search extends Whereable implements SearchInterface { ...this.compileOptions(), ...super.compileWhere(), ...super.compileWherein(), - ...(this._output || []), + ...(this._output ?? []), ], ]; } diff --git a/src/commands/Set.ts b/src/commands/Set.ts index 7db9c3a..e43ef26 100644 --- a/src/commands/Set.ts +++ b/src/commands/Set.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-type-parameters */ + import { GeoJSON } from '@vpriem/geojson'; import { Executable } from './Executable'; import { Client, Command, CommandArgs, SubCommand } from '../Client'; @@ -111,6 +113,7 @@ export class Set extends Executable implements SetInterface { ? [SubCommand.EX, this._ex] : []), ...(this._nxOrXx ? [this._nxOrXx] : []), + /* eslint-disable-next-line @typescript-eslint/no-unnecessary-condition */ ...(this._input || []), ], ]; diff --git a/src/commands/Whereable.ts b/src/commands/Whereable.ts index e6d8cad..2ba9cdb 100644 --- a/src/commands/Whereable.ts +++ b/src/commands/Whereable.ts @@ -23,7 +23,7 @@ export type WhereInValues = (number | string)[]; * @typedef {Array} WhereInType * @property {Array} 0 - SubCommand.WHEREIN with field name and values */ -type WhereInType = [SubCommand.WHEREIN, string, ...Array][]; +type WhereInType = [SubCommand.WHEREIN, string, ...(string | number)[]][]; export interface Where { /** diff --git a/src/errors.ts b/src/errors.ts index 0c006e1..f6232ed 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line max-classes-per-file export class Tile38Error extends Error {} export class Tile38KeyNotFoundError extends Tile38Error {} export class Tile38IdNotFoundError extends Tile38Error {} diff --git a/src/events.ts b/src/events.ts index a6b7235..43c6d9e 100644 --- a/src/events.ts +++ b/src/events.ts @@ -10,9 +10,10 @@ const events = [ 'wait', ]; -export const forwardEvents = (from: EventEmitter, to: EventEmitter): void => - events.forEach((event) => - from.on(event, (...eventArgs) => +export const forwardEvents = (from: EventEmitter, to: EventEmitter): void => { + events.forEach((event) => { + return from.on(event, (...eventArgs) => to.emit(event, ...(eventArgs as [Error])) - ) - ); + ); + }); +}; diff --git a/src/parseResponse.ts b/src/parseResponse.ts index d23cbb8..b6c51bd 100644 --- a/src/parseResponse.ts +++ b/src/parseResponse.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-type-parameters */ + import { Tile38Error, Tile38IdNotFoundError, @@ -12,11 +14,11 @@ export const parseResponse = (response: string): R => { try { obj = JSON.parse(response) as R; } catch (error) /* istanbul ignore next */ { - throw new Tile38Error((error as Error)?.message || 'unknown'); + throw new Tile38Error((error as Error).message || 'unknown'); } if (!obj.ok) { - const message = obj.err || /* istanbul ignore next */ 'unknown'; + const message = obj.err ?? /* istanbul ignore next */ 'unknown'; if (message.includes('key not found')) { throw new Tile38KeyNotFoundError(message); diff --git a/src/responses.ts b/src/responses.ts index 6653d1f..9f3a66a 100644 --- a/src/responses.ts +++ b/src/responses.ts @@ -1,20 +1,19 @@ -/* eslint-disable camelcase */ import { GeoJSON, Polygon } from '@vpriem/geojson'; -export type JSONResponse = { +export interface JSONResponse { ok: boolean; elapsed: string; err?: string; -}; +} type ExtendResponse = JSONResponse & E; -export type LatLon = { +export interface LatLon { lat: number; lon: number; -}; +} -export type Fields = Record< +export type Fields = Record< string, string | number | object | O >; @@ -149,12 +148,12 @@ export type TTLResponse = ExtendResponse<{ // STATS export type StatsResponse = ExtendResponse<{ - stats: Array<{ + stats: ({ in_memory_size: number; num_objects: number; num_points: number; num_strings: number; - } | null>; + } | null)[]; }>; // SERVER @@ -291,7 +290,7 @@ export interface InfoFollowerResponse extends InfoResponse { export interface InfoLeaderResponse extends InfoResponse { info: InfoResponse['info'] & { role: 'master'; - } & { [key: string]: string | number }; + } & Record; } // CONFIG diff --git a/src/specs.ts b/src/specs.ts index a45a00f..e98a65c 100644 --- a/src/specs.ts +++ b/src/specs.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-type-parameters */ + import { GeoJSON } from '@vpriem/geojson'; import { RedisOptions } from 'ioredis'; import { WhereInValues } from './commands/Whereable'; @@ -1337,6 +1339,15 @@ export interface SetHookInterface extends SetChanInterface { */ export type Tile38Options = RedisOptions; +enum ListenerEvent { + CONNECT = 'connect', + READY = 'ready', + ERROR = 'error', + CLOSE = 'close', + RECONNECTING = 'reconnecting', + WAIT = 'wait', +} + /** * Tile38BaseInterface provides methods for interacting with the Tile38 server */ @@ -1347,55 +1358,7 @@ interface Tile38BaseInterface { * @param {() => void} listener - The callback function * @returns {this} */ - on(event: 'connect', listener: () => void): this; - - /** - * Register an event listener for the 'ready' event - * @param {'ready'} event - The event type - * @param {() => void} listener - The callback function - * @returns {this} - */ - on(event: 'ready', listener: () => void): this; - - /** - * Register an event listener for the 'error' event - * @param {'error'} event - The event type - * @param {(error: Error) => void} listener - The callback function - * @returns {this} - */ - on(event: 'error', listener: (error: Error) => void): this; - - /** - * Register an event listener for the 'close' event - * @param {'close'} event - The event type - * @param {() => void} listener - The callback function - * @returns {this} - */ - on(event: 'close', listener: () => void): this; - - /** - * Register an event listener for the 'reconnecting' event - * @param {'reconnecting'} event - The event type - * @param {() => void} listener - The callback function - * @returns {this} - */ - on(event: 'reconnecting', listener: () => void): this; - - /** - * Register an event listener for the 'end' event - * @param {'end'} event - The event type - * @param {() => void} listener - The callback function - * @returns {this} - */ - on(event: 'end', listener: () => void): this; - - /** - * Register an event listener for the 'wait' event - * @param {'wait'} event - The event type - * @param {() => void} listener - The callback function - * @returns {this} - */ - on(event: 'wait', listener: () => void): this; + on(event: `${ListenerEvent}`, listener: () => void): this; /** * Get the bounds for a specific key diff --git a/src/tests/channel.test.ts b/src/tests/channel.test.ts index 14e9745..362c57b 100644 --- a/src/tests/channel.test.ts +++ b/src/tests/channel.test.ts @@ -63,12 +63,11 @@ describe('channel', () => { it('should receive set geofence', async () => { const promise = new Promise((resolve) => { - channel.on( - 'message', - (message, channelName) => - message.command === 'set' && - resolve({ message, channelName }) - ); + channel.on('message', (message, channelName) => { + if (message.command === 'set') { + resolve({ message, channelName }); + } + }); }); await tile38 @@ -104,12 +103,11 @@ describe('channel', () => { it('should receive set geofence on follower', async () => { const promise = new Promise((resolve) => { - followerChannel.on( - 'message', - (message, channelName) => - message.command === 'set' && - resolve({ message, channelName }) - ); + followerChannel.on('message', (message, channelName) => { + if (message.command === 'set') { + resolve({ message, channelName }); + } + }); }); await tile38 @@ -145,12 +143,11 @@ describe('channel', () => { it('should receive del geofence', async () => { const promise = new Promise((resolve) => { - channel.on( - 'message', - (message, channelName) => - message.command === 'del' && - resolve({ message, channelName }) - ); + channel.on('message', (message, channelName) => { + if (message.command === 'del') { + resolve({ message, channelName }); + } + }); }); await tile38 @@ -177,12 +174,11 @@ describe('channel', () => { it('should receive del geofence on follower', async () => { const promise = new Promise((resolve) => { - followerChannel.on( - 'message', - (message, channelName) => - message.command === 'del' && - resolve({ message, channelName }) - ); + followerChannel.on('message', (message, channelName) => { + if (message.command === 'del') { + resolve({ message, channelName }); + } + }); }); await tile38 @@ -230,7 +226,9 @@ describe('channel', () => { const promise = new Promise((resolve) => { channel.on( 'message', - (message, channelName) => resolve({ message, channelName }) + (message, channelName) => { + resolve({ message, channelName }); + } ); }); @@ -269,7 +267,9 @@ describe('channel', () => { const promise = new Promise((resolve) => { followerChannel.on( 'message', - (message, channelName) => resolve({ message, channelName }) + (message, channelName) => { + resolve({ message, channelName }); + } ); }); diff --git a/src/tests/events.test.ts b/src/tests/events.test.ts index a0e9a97..f1641f7 100644 --- a/src/tests/events.test.ts +++ b/src/tests/events.test.ts @@ -3,7 +3,7 @@ import { Tile38 } from '..'; describe('events', () => { let tile38: Tile38; - afterEach(() => tile38?.quit()); + afterEach(() => tile38.quit()); it('should emit connect/ready/close/end', async () => { const connect = jest.fn(); diff --git a/src/tests/intersects-all.test.ts b/src/tests/intersects-all.test.ts index 0c35439..c10d4ce 100644 --- a/src/tests/intersects-all.test.ts +++ b/src/tests/intersects-all.test.ts @@ -376,7 +376,7 @@ describe('intersects all', () => { 'truck1', 'truck2', 'truck3', - ]) as Array, + ]) as string[], count: 3, cursor: 0, }; diff --git a/src/tests/leader.test.ts b/src/tests/leader.test.ts index 4110521..9ef9d2d 100644 --- a/src/tests/leader.test.ts +++ b/src/tests/leader.test.ts @@ -3,7 +3,7 @@ import { Tile38 } from '..'; describe('leader', () => { let tile38: Tile38; - afterEach(() => tile38?.quit()); + afterEach(() => tile38.quit()); it('should create with no arguments', async () => { tile38 = new Tile38(); diff --git a/yarn.lock b/yarn.lock index 3795590..122ecc3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -465,49 +465,71 @@ dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.6.1": +"@eslint-community/regexpp@^4.10.0": version "4.10.0" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== -"@eslint/eslintrc@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" - integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== +"@eslint-community/regexpp@^4.11.0": + version "4.11.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" + integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== + +"@eslint/config-array@^0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.18.0.tgz#37d8fe656e0d5e3dbaea7758ea56540867fd074d" + integrity sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw== + dependencies: + "@eslint/object-schema" "^2.1.4" + debug "^4.3.1" + minimatch "^3.1.2" + +"@eslint/core@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.6.0.tgz#9930b5ba24c406d67a1760e94cdbac616a6eb674" + integrity sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg== + +"@eslint/eslintrc@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.1.0.tgz#dbd3482bfd91efa663cbe7aa1f506839868207b6" + integrity sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" + espree "^10.0.1" + globals "^14.0.0" ignore "^5.2.0" import-fresh "^3.2.1" js-yaml "^4.1.0" minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.57.0": - version "8.57.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" - integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== +"@eslint/js@9.11.1": + version "9.11.1" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.11.1.tgz#8bcb37436f9854b3d9a561440daf916acd940986" + integrity sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA== + +"@eslint/object-schema@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.4.tgz#9e69f8bb4031e11df79e03db09f9dbbae1740843" + integrity sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ== -"@humanwhocodes/config-array@^0.11.14": - version "0.11.14" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" - integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== +"@eslint/plugin-kit@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz#8712dccae365d24e9eeecb7b346f85e750ba343d" + integrity sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig== dependencies: - "@humanwhocodes/object-schema" "^2.0.2" - debug "^4.3.1" - minimatch "^3.0.5" + levn "^0.4.1" "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^2.0.2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" - integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== +"@humanwhocodes/retry@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.0.tgz#6d86b8cb322660f03d3f0aa94b99bdd8e172d570" + integrity sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew== "@ioredis/commands@^1.1.1": version "1.2.0" @@ -1366,6 +1388,26 @@ dependencies: "@types/node" "*" +"@types/eslint@*": + version "9.6.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584" + integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/eslint__js@8.42.3": + version "8.42.3" + resolved "https://registry.yarnpkg.com/@types/eslint__js/-/eslint__js-8.42.3.tgz#d1fa13e5c1be63a10b4e3afe992779f81c1179a0" + integrity sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw== + dependencies: + "@types/eslint" "*" + +"@types/estree@*", "@types/estree@^1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== + "@types/geojson@7946.0.11": version "7946.0.11" resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.11.tgz#012c17cb2256ad8de78560da851ab914a7b9b40e" @@ -1405,6 +1447,11 @@ expect "^29.0.0" pretty-format "^29.0.0" +"@types/json-schema@*", "@types/json-schema@^7.0.15": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" @@ -1532,11 +1579,6 @@ "@typescript-eslint/types" "8.7.0" eslint-visitor-keys "^3.4.3" -"@ungap/structured-clone@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" - integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== - "@vpriem/geojson@1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@vpriem/geojson/-/geojson-1.3.0.tgz#26b195bd4e7b79def276afda553cadf1c8071f2b" @@ -1562,10 +1604,10 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.9.0: - version "8.11.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" - integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== +acorn@^8.12.0: + version "8.12.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== agent-base@^7.0.2, agent-base@^7.1.0, agent-base@^7.1.1: version "7.1.1" @@ -2543,13 +2585,6 @@ doctrine@^2.1.0: dependencies: esutils "^2.0.2" -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - dot-prop@^5.1.0: version "5.3.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" @@ -2857,56 +2892,60 @@ eslint-plugin-prettier@5.2.1: prettier-linter-helpers "^1.0.0" synckit "^0.9.1" -eslint-scope@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== +eslint-scope@^8.0.2: + version "8.1.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.1.0.tgz#70214a174d4cbffbc3e8a26911d8bf51b9ae9d30" + integrity sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint@8.57.0: - version "8.57.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668" - integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== +eslint-visitor-keys@^4.0.0, eslint-visitor-keys@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz#1f785cc5e81eb7534523d85922248232077d2f8c" + integrity sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg== + +eslint@9.11.1: + version "9.11.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.11.1.tgz#701e5fc528990153f9cef696d8427003b5206567" + integrity sha512-MobhYKIoAO1s1e4VUrgx1l1Sk2JBR/Gqjjgw8+mfgoLE2xwsHur4gdfTxyTgShrhvdVFTaJSgMiQBl1jv/AWxg== dependencies: "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.4" - "@eslint/js" "8.57.0" - "@humanwhocodes/config-array" "^0.11.14" + "@eslint-community/regexpp" "^4.11.0" + "@eslint/config-array" "^0.18.0" + "@eslint/core" "^0.6.0" + "@eslint/eslintrc" "^3.1.0" + "@eslint/js" "9.11.1" + "@eslint/plugin-kit" "^0.2.0" "@humanwhocodes/module-importer" "^1.0.1" + "@humanwhocodes/retry" "^0.3.0" "@nodelib/fs.walk" "^1.2.8" - "@ungap/structured-clone" "^1.2.0" + "@types/estree" "^1.0.6" + "@types/json-schema" "^7.0.15" ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" debug "^4.3.2" - doctrine "^3.0.0" escape-string-regexp "^4.0.0" - eslint-scope "^7.2.2" - eslint-visitor-keys "^3.4.3" - espree "^9.6.1" - esquery "^1.4.2" + eslint-scope "^8.0.2" + eslint-visitor-keys "^4.0.0" + espree "^10.1.0" + esquery "^1.5.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" + file-entry-cache "^8.0.0" find-up "^5.0.0" glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" ignore "^5.2.0" imurmurhash "^0.1.4" is-glob "^4.0.0" is-path-inside "^3.0.3" - js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" lodash.merge "^4.6.2" minimatch "^3.1.2" natural-compare "^1.4.0" @@ -2914,24 +2953,24 @@ eslint@8.57.0: strip-ansi "^6.0.1" text-table "^0.2.0" -espree@^9.6.0, espree@^9.6.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== +espree@^10.0.1, espree@^10.1.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.2.0.tgz#f4bcead9e05b0615c968e85f83816bc386a45df6" + integrity sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g== dependencies: - acorn "^8.9.0" + acorn "^8.12.0" acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" + eslint-visitor-keys "^4.1.0" esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== +esquery@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== dependencies: estraverse "^5.1.0" @@ -3105,12 +3144,12 @@ figures@^6.0.0, figures@^6.1.0: dependencies: is-unicode-supported "^2.0.0" -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== +file-entry-cache@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" + integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== dependencies: - flat-cache "^3.0.4" + flat-cache "^4.0.0" filelist@^1.0.4: version "1.0.4" @@ -3178,14 +3217,13 @@ find-versions@^6.0.0: semver-regex "^4.0.5" super-regex "^1.0.0" -flat-cache@^3.0.4: - version "3.2.0" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" - integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== +flat-cache@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c" + integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== dependencies: flatted "^3.2.9" - keyv "^4.5.3" - rimraf "^3.0.2" + keyv "^4.5.4" flatted@^3.2.9: version "3.3.1" @@ -3446,12 +3484,10 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^13.19.0: - version "13.24.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" - integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== - dependencies: - type-fest "^0.20.2" +globals@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" + integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== globalthis@^1.0.3: version "1.0.4" @@ -4636,7 +4672,7 @@ just-diff@^6.0.0: resolved "https://registry.yarnpkg.com/just-diff/-/just-diff-6.0.2.tgz#03b65908543ac0521caf6d8eb85035f7d27ea285" integrity sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA== -keyv@^4.5.3: +keyv@^4.5.4: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== @@ -5113,7 +5149,7 @@ minimatch@^10.0.0: dependencies: brace-expansion "^2.0.1" -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -6258,13 +6294,6 @@ rimraf@6.0.1: glob "^11.0.0" package-json-from-dist "^1.0.0" -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -7023,11 +7052,6 @@ type-detect@4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" @@ -7104,6 +7128,15 @@ typedarray.prototype.slice@^1.0.3: typed-array-buffer "^1.0.2" typed-array-byte-offset "^1.0.2" +typescript-eslint@8.7.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.7.0.tgz#6c84f94013a0cc0074da7d639c2644eae20c3171" + integrity sha512-nEHbEYJyHwsuf7c3V3RS7Saq+1+la3i0ieR3qP0yjqWSzVmh8Drp47uOl9LjbPANac4S7EFSqvcYIKXUUwIfIQ== + dependencies: + "@typescript-eslint/eslint-plugin" "8.7.0" + "@typescript-eslint/parser" "8.7.0" + "@typescript-eslint/utils" "8.7.0" + typescript@5.6.2: version "5.6.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0"