From 055bc230971066694bdfd6af7be4eeffe18d922c Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Sat, 20 Jun 2026 21:42:33 +0300 Subject: [PATCH] refactor(frontend): migrate auth/portfolio pages to FSD, add layer boundaries - Convert LoginPage, RegisterPage, ProfilePage to FSD structure (index.ts + ui/) - Convert PortfoliosListPage, PortfolioDetailPage to FSD structure - Replace relative imports with @/ aliases in portfolio pages - Add ESLint import/no-restricted-paths for FSD layer boundaries - Refactor useSession test to mock context instead of import from app/ - Mark frontend-fsd-screener tasks as complete --- apps/frontend/.eslintrc.cjs | 42 +- apps/frontend/package.json | 3 + apps/frontend/src/app/routing/AppRoutes.tsx | 9 +- .../session/model/useSession.test.tsx | 55 +- .../src/pages/{ => login}/LoginPage.test.tsx | 6 +- apps/frontend/src/pages/login/index.ts | 1 + .../src/pages/{ => login/ui}/LoginPage.tsx | 0 apps/frontend/src/pages/portfolios/index.ts | 2 + .../{ => ui}/PortfolioDetailPage.tsx | 16 +- .../{ => ui}/PortfoliosListPage.tsx | 6 +- .../pages/{ => profile}/ProfilePage.test.tsx | 6 +- apps/frontend/src/pages/profile/index.ts | 1 + .../pages/{ => profile/ui}/ProfilePage.tsx | 0 .../{ => register}/RegisterPage.test.tsx | 6 +- apps/frontend/src/pages/register/index.ts | 1 + .../pages/{ => register/ui}/RegisterPage.tsx | 0 docs/features/frontend-fsd-screener/tasks.md | 46 +- package-lock.json | 728 ++++++++++++++++++ 18 files changed, 844 insertions(+), 84 deletions(-) rename apps/frontend/src/pages/{ => login}/LoginPage.test.tsx (95%) create mode 100644 apps/frontend/src/pages/login/index.ts rename apps/frontend/src/pages/{ => login/ui}/LoginPage.tsx (100%) create mode 100644 apps/frontend/src/pages/portfolios/index.ts rename apps/frontend/src/pages/portfolios/{ => ui}/PortfolioDetailPage.tsx (94%) rename apps/frontend/src/pages/portfolios/{ => ui}/PortfoliosListPage.tsx (92%) rename apps/frontend/src/pages/{ => profile}/ProfilePage.test.tsx (93%) create mode 100644 apps/frontend/src/pages/profile/index.ts rename apps/frontend/src/pages/{ => profile/ui}/ProfilePage.tsx (100%) rename apps/frontend/src/pages/{ => register}/RegisterPage.test.tsx (95%) create mode 100644 apps/frontend/src/pages/register/index.ts rename apps/frontend/src/pages/{ => register/ui}/RegisterPage.tsx (100%) diff --git a/apps/frontend/.eslintrc.cjs b/apps/frontend/.eslintrc.cjs index bb2d3ac..7b78313 100644 --- a/apps/frontend/.eslintrc.cjs +++ b/apps/frontend/.eslintrc.cjs @@ -1,10 +1,13 @@ +const path = require('path'); +const src = path.resolve(__dirname, 'src'); + module.exports = { parser: '@typescript-eslint/parser', parserOptions: { sourceType: 'module', ecmaFeatures: { jsx: true }, }, - plugins: ['@typescript-eslint/eslint-plugin', 'react', 'react-hooks'], + plugins: ['@typescript-eslint/eslint-plugin', 'react', 'react-hooks', 'import'], extends: [ 'plugin:@typescript-eslint/recommended', 'plugin:react/recommended', @@ -17,11 +20,48 @@ module.exports = { }, settings: { react: { version: 'detect' }, + 'import/resolver': { + typescript: { + alwaysTryTypes: true, + project: './tsconfig.json', + }, + }, }, ignorePatterns: ['.eslintrc.cjs', 'vite.config.ts', 'vitest.config.ts', 'dist/'], rules: { '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], '@typescript-eslint/no-explicit-any': 'off', 'react/react-in-jsx-scope': 'off', + + // FSD layer boundaries + // NOTE: `from` = what's being imported, `target` = the file doing the import + 'import/no-restricted-paths': [ + 'error', + { + zones: [ + // shared/ cannot import from entities/, features/, widgets/, pages/, app/ + { from: `${src}/entities`, target: `${src}/shared` }, + { from: `${src}/features`, target: `${src}/shared` }, + { from: `${src}/widgets`, target: `${src}/shared` }, + { from: `${src}/pages`, target: `${src}/shared` }, + { from: `${src}/app`, target: `${src}/shared` }, + // entities/ cannot import from features/, widgets/, pages/, app/ + { from: `${src}/features`, target: `${src}/entities` }, + { from: `${src}/widgets`, target: `${src}/entities` }, + { from: `${src}/pages`, target: `${src}/entities` }, + { from: `${src}/app`, target: `${src}/entities` }, + // features/ cannot import from widgets/, pages/, app/ + { from: `${src}/widgets`, target: `${src}/features` }, + { from: `${src}/pages`, target: `${src}/features` }, + { from: `${src}/app`, target: `${src}/features` }, + // widgets/ cannot import from pages/, app/ + { from: `${src}/pages`, target: `${src}/widgets` }, + { from: `${src}/app`, target: `${src}/widgets` }, + // pages/ cannot import from app/ + { from: `${src}/app`, target: `${src}/pages` }, + + ], + }, + ], }, }; diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 4165e45..b50d1ae 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -31,6 +31,9 @@ "@typescript-eslint/parser": "^7.0.0", "@vitejs/plugin-react": "^4.2.0", "eslint": "^8.0.0", + "eslint-import-resolver-alias": "^1.1.2", + "eslint-import-resolver-typescript": "^4.4.5", + "eslint-plugin-import": "^2.32.0", "eslint-plugin-react": "^7.34.0", "eslint-plugin-react-hooks": "^4.6.0", "jsdom": "^29.1.1", diff --git a/apps/frontend/src/app/routing/AppRoutes.tsx b/apps/frontend/src/app/routing/AppRoutes.tsx index 3f38091..3fdd335 100644 --- a/apps/frontend/src/app/routing/AppRoutes.tsx +++ b/apps/frontend/src/app/routing/AppRoutes.tsx @@ -4,11 +4,10 @@ import { ProtectedRoute } from './ProtectedRoute'; import { HomePage } from '@/pages/home'; import { StockPage } from '@/pages/stock'; import { BondPage } from '@/pages/bond'; -import { LoginPage } from '@/pages/LoginPage'; -import { RegisterPage } from '@/pages/RegisterPage'; -import { ProfilePage } from '@/pages/ProfilePage'; -import { PortfoliosListPage } from '@/pages/portfolios/PortfoliosListPage'; -import { PortfolioDetailPage } from '@/pages/portfolios/PortfolioDetailPage'; +import { LoginPage } from '@/pages/login'; +import { RegisterPage } from '@/pages/register'; +import { ProfilePage } from '@/pages/profile'; +import { PortfoliosListPage, PortfolioDetailPage } from '@/pages/portfolios'; import { ScreenerPage } from '@/pages/screener'; import { BrokerAccountsPage } from '@/pages/broker-accounts'; import { BrokerAccountLayout } from '@/entities/broker-account/ui/BrokerAccountLayout'; diff --git a/apps/frontend/src/entities/session/model/useSession.test.tsx b/apps/frontend/src/entities/session/model/useSession.test.tsx index 0abf982..2e4652a 100644 --- a/apps/frontend/src/entities/session/model/useSession.test.tsx +++ b/apps/frontend/src/entities/session/model/useSession.test.tsx @@ -1,62 +1,53 @@ import { describe, it, expect } from 'vitest'; -import { renderHook, waitFor } from '@testing-library/react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { SessionProvider } from '../../../app/providers/SessionProvider'; +import { renderHook } from '@testing-library/react'; +import { SessionContext, type SessionState } from './sessionContext'; import { useSession } from './useSession'; -import { type ReactNode } from 'react'; +import type { ReactNode } from 'react'; -function createWrapper() { - const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } }); +const mockSession: SessionState = { + user: { id: 1, email: 'user@test.com', name: 'Test User', role: 'user' }, + accessToken: 'mock-access-token', + isAuthenticated: true, + login: vi.fn().mockResolvedValue(undefined), + logout: vi.fn(), + register: vi.fn().mockResolvedValue(undefined), + updateProfile: vi.fn().mockResolvedValue(undefined), + refreshSession: vi.fn().mockResolvedValue(undefined), +}; + +function createWrapper(session: SessionState = mockSession) { return function Wrapper({ children }: { children: ReactNode }) { - return ( - - {children} - - ); + return {children}; }; } describe('useSession', () => { - afterEach(() => { - vi.restoreAllMocks(); - }); - - it('returns session context with user after mount', async () => { + it('returns session context with user', () => { const { result } = renderHook(() => useSession(), { wrapper: createWrapper() }); - await waitFor(() => { - expect(result.current.isAuthenticated).toBe(true); - }); + expect(result.current.isAuthenticated).toBe(true); expect(result.current.user?.email).toBe('user@test.com'); expect(result.current.accessToken).toBe('mock-access-token'); }); - it('provides login function', async () => { + it('provides login function', () => { const { result } = renderHook(() => useSession(), { wrapper: createWrapper() }); - await waitFor(() => expect(result.current.isAuthenticated).toBe(true)); expect(typeof result.current.login).toBe('function'); }); - it('provides logout function', async () => { + it('provides logout function', () => { const { result } = renderHook(() => useSession(), { wrapper: createWrapper() }); - await waitFor(() => expect(result.current.isAuthenticated).toBe(true)); expect(typeof result.current.logout).toBe('function'); }); - it('provides register function', async () => { + it('provides register function', () => { const { result } = renderHook(() => useSession(), { wrapper: createWrapper() }); - await waitFor(() => expect(result.current.isAuthenticated).toBe(true)); expect(typeof result.current.register).toBe('function'); }); - it('throws when used without AuthProvider', () => { - vi.spyOn(process.stderr, 'write').mockImplementation(() => true); - vi.spyOn(console, 'error').mockImplementation(() => {}); - const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } }); + it('throws when used without SessionProvider', () => { expect(() => { renderHook(() => useSession(), { - wrapper: ({ children }) => ( - {children} - ), + wrapper: ({ children }: { children: ReactNode }) => <>{children}, }); }).toThrow('useSession must be used within a SessionProvider'); }); diff --git a/apps/frontend/src/pages/LoginPage.test.tsx b/apps/frontend/src/pages/login/LoginPage.test.tsx similarity index 95% rename from apps/frontend/src/pages/LoginPage.test.tsx rename to apps/frontend/src/pages/login/LoginPage.test.tsx index 2b1e9bb..4932b74 100644 --- a/apps/frontend/src/pages/LoginPage.test.tsx +++ b/apps/frontend/src/pages/login/LoginPage.test.tsx @@ -3,9 +3,9 @@ import { screen } from '@testing-library/react'; import { Routes, Route } from 'react-router-dom'; import userEvent from '@testing-library/user-event'; import { http, HttpResponse } from 'msw'; -import { server } from '../test/server'; -import { LoginPage } from './LoginPage'; -import { renderWithProviders } from '../test/test-utils'; +import { server } from '../../test/server'; +import { LoginPage } from './ui/LoginPage'; +import { renderWithProviders } from '../../test/test-utils'; const API = '/api/v1'; diff --git a/apps/frontend/src/pages/login/index.ts b/apps/frontend/src/pages/login/index.ts new file mode 100644 index 0000000..3935214 --- /dev/null +++ b/apps/frontend/src/pages/login/index.ts @@ -0,0 +1 @@ +export { LoginPage } from './ui/LoginPage'; diff --git a/apps/frontend/src/pages/LoginPage.tsx b/apps/frontend/src/pages/login/ui/LoginPage.tsx similarity index 100% rename from apps/frontend/src/pages/LoginPage.tsx rename to apps/frontend/src/pages/login/ui/LoginPage.tsx diff --git a/apps/frontend/src/pages/portfolios/index.ts b/apps/frontend/src/pages/portfolios/index.ts new file mode 100644 index 0000000..34e0478 --- /dev/null +++ b/apps/frontend/src/pages/portfolios/index.ts @@ -0,0 +1,2 @@ +export { PortfoliosListPage } from './ui/PortfoliosListPage'; +export { PortfolioDetailPage } from './ui/PortfolioDetailPage'; diff --git a/apps/frontend/src/pages/portfolios/PortfolioDetailPage.tsx b/apps/frontend/src/pages/portfolios/ui/PortfolioDetailPage.tsx similarity index 94% rename from apps/frontend/src/pages/portfolios/PortfolioDetailPage.tsx rename to apps/frontend/src/pages/portfolios/ui/PortfolioDetailPage.tsx index 7ea257c..9ec841f 100644 --- a/apps/frontend/src/pages/portfolios/PortfolioDetailPage.tsx +++ b/apps/frontend/src/pages/portfolios/ui/PortfolioDetailPage.tsx @@ -1,15 +1,11 @@ import { useState } from 'react'; import { useParams, Link } from 'react-router-dom'; -import { - usePortfolio, - usePortfolioMutations, - usePositionMutations, -} from '../../entities/portfolio'; -import { PortfolioForm } from '../../widgets/portfolio-form'; -import { PortfolioSummary } from '../../widgets/portfolio-summary'; -import { AnalyticsSummary } from '../../widgets/portfolio-analytics'; -import { SharePositionTable } from '../../widgets/share-positions-table'; -import { BondPositionTable } from '../../widgets/bond-positions-table'; +import { usePortfolio, usePortfolioMutations, usePositionMutations } from '@/entities/portfolio'; +import { PortfolioForm } from '@/widgets/portfolio-form'; +import { PortfolioSummary } from '@/widgets/portfolio-summary'; +import { AnalyticsSummary } from '@/widgets/portfolio-analytics'; +import { SharePositionTable } from '@/widgets/share-positions-table'; +import { BondPositionTable } from '@/widgets/bond-positions-table'; export function PortfolioDetailPage() { const { id } = useParams<{ id: string }>(); diff --git a/apps/frontend/src/pages/portfolios/PortfoliosListPage.tsx b/apps/frontend/src/pages/portfolios/ui/PortfoliosListPage.tsx similarity index 92% rename from apps/frontend/src/pages/portfolios/PortfoliosListPage.tsx rename to apps/frontend/src/pages/portfolios/ui/PortfoliosListPage.tsx index 0bd4cc6..9f8fc28 100644 --- a/apps/frontend/src/pages/portfolios/PortfoliosListPage.tsx +++ b/apps/frontend/src/pages/portfolios/ui/PortfoliosListPage.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; -import { usePortfolios, usePortfolioMutations } from '../../entities/portfolio'; -import { PortfolioCard } from '../../widgets/portfolio-card'; -import { PortfolioForm } from '../../widgets/portfolio-form'; +import { usePortfolios, usePortfolioMutations } from '@/entities/portfolio'; +import { PortfolioCard } from '@/widgets/portfolio-card'; +import { PortfolioForm } from '@/widgets/portfolio-form'; export function PortfoliosListPage() { const { data: portfolios, isLoading, error } = usePortfolios(); diff --git a/apps/frontend/src/pages/ProfilePage.test.tsx b/apps/frontend/src/pages/profile/ProfilePage.test.tsx similarity index 93% rename from apps/frontend/src/pages/ProfilePage.test.tsx rename to apps/frontend/src/pages/profile/ProfilePage.test.tsx index 1575afc..e4bc956 100644 --- a/apps/frontend/src/pages/ProfilePage.test.tsx +++ b/apps/frontend/src/pages/profile/ProfilePage.test.tsx @@ -2,9 +2,9 @@ import { describe, it, expect } from 'vitest'; import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { http, HttpResponse } from 'msw'; -import { server } from '../test/server'; -import { ProfilePage } from './ProfilePage'; -import { renderWithProviders } from '../test/test-utils'; +import { server } from '../../test/server'; +import { ProfilePage } from './ui/ProfilePage'; +import { renderWithProviders } from '../../test/test-utils'; const API = '/api/v1'; diff --git a/apps/frontend/src/pages/profile/index.ts b/apps/frontend/src/pages/profile/index.ts new file mode 100644 index 0000000..7d9c888 --- /dev/null +++ b/apps/frontend/src/pages/profile/index.ts @@ -0,0 +1 @@ +export { ProfilePage } from './ui/ProfilePage'; diff --git a/apps/frontend/src/pages/ProfilePage.tsx b/apps/frontend/src/pages/profile/ui/ProfilePage.tsx similarity index 100% rename from apps/frontend/src/pages/ProfilePage.tsx rename to apps/frontend/src/pages/profile/ui/ProfilePage.tsx diff --git a/apps/frontend/src/pages/RegisterPage.test.tsx b/apps/frontend/src/pages/register/RegisterPage.test.tsx similarity index 95% rename from apps/frontend/src/pages/RegisterPage.test.tsx rename to apps/frontend/src/pages/register/RegisterPage.test.tsx index cc080b7..832cb29 100644 --- a/apps/frontend/src/pages/RegisterPage.test.tsx +++ b/apps/frontend/src/pages/register/RegisterPage.test.tsx @@ -3,9 +3,9 @@ import { screen } from '@testing-library/react'; import { Routes, Route } from 'react-router-dom'; import userEvent from '@testing-library/user-event'; import { http, HttpResponse } from 'msw'; -import { server } from '../test/server'; -import { RegisterPage } from './RegisterPage'; -import { renderWithProviders } from '../test/test-utils'; +import { server } from '../../test/server'; +import { RegisterPage } from './ui/RegisterPage'; +import { renderWithProviders } from '../../test/test-utils'; const API = '/api/v1'; diff --git a/apps/frontend/src/pages/register/index.ts b/apps/frontend/src/pages/register/index.ts new file mode 100644 index 0000000..2c39f32 --- /dev/null +++ b/apps/frontend/src/pages/register/index.ts @@ -0,0 +1 @@ +export { RegisterPage } from './ui/RegisterPage'; diff --git a/apps/frontend/src/pages/RegisterPage.tsx b/apps/frontend/src/pages/register/ui/RegisterPage.tsx similarity index 100% rename from apps/frontend/src/pages/RegisterPage.tsx rename to apps/frontend/src/pages/register/ui/RegisterPage.tsx diff --git a/docs/features/frontend-fsd-screener/tasks.md b/docs/features/frontend-fsd-screener/tasks.md index 5a51cfe..622bfef 100644 --- a/docs/features/frontend-fsd-screener/tasks.md +++ b/docs/features/frontend-fsd-screener/tasks.md @@ -1,47 +1,45 @@ # Frontend FSD Screener — задачи -Статус: в работе - -Подробные шаги, карта файлов и verification-команды находятся в [plan.md](plan.md). +Статус: выполнено ## 1. API слой -- [ ] Создать `features/screener/api/screenerApi.ts` — перенос `ScreenerQuery` + `getScreenerResults` -- [ ] Обновить импорты: `@/shared/api/client`, `@/shared/api/responses` +- [x] Создать `features/screener/api/screenerApi.ts` — перенос `ScreenerQuery` + `getScreenerResults` +- [x] Обновить импорты: `@/shared/api/client`, `@/shared/api/responses` ## 2. Модель -- [ ] Создать `features/screener/model/useScreener.ts` — перенос хука -- [ ] Создать `features/screener/model/index.ts` +- [x] Создать `features/screener/model/useScreener.ts` — перенос хука +- [x] Создать `features/screener/model/index.ts` ## 3. UI компоненты -- [ ] Перенести `FilterPanel.tsx` в `features/screener/ui/` -- [ ] Перенести `FilterPanelShare.tsx` в `features/screener/ui/` -- [ ] Перенести `FilterPanelBond.tsx` в `features/screener/ui/` -- [ ] Перенести `ScreenerTable.tsx` в `features/screener/ui/` -- [ ] Создать `features/screener/ui/index.ts` -- [ ] Создать `features/screener/index.ts` +- [x] Перенести `FilterPanel.tsx` в `features/screener/ui/` +- [x] Перенести `FilterPanelShare.tsx` в `features/screener/ui/` +- [x] Перенести `FilterPanelBond.tsx` в `features/screener/ui/` +- [x] Перенести `ScreenerTable.tsx` в `features/screener/ui/` +- [x] Создать `features/screener/ui/index.ts` +- [x] Создать `features/screener/index.ts` ## 4. Pages -- [ ] Создать `pages/screener/ui/ScreenerPage.tsx` — обновить импорты на `@/features/screener` -- [ ] Создать `pages/screener/index.ts` +- [x] Создать `pages/screener/ui/ScreenerPage.tsx` — обновить импорты на `@/features/screener` +- [x] Создать `pages/screener/index.ts` ## 5. Роутинг -- [ ] Обновить `app/routing/AppRoutes.tsx` — import from `@/pages/screener` +- [x] Обновить `app/routing/AppRoutes.tsx` — import from `@/pages/screener` ## 6. Удаление legacy -- [ ] Удалить `api/screener.ts` -- [ ] Удалить `hooks/useScreener.ts` -- [ ] Удалить `components/screener/` (директория) +- [x] Удалить `api/screener.ts` +- [x] Удалить `hooks/useScreener.ts` +- [x] Удалить `components/screener/` (директория) ## 7. Verification -- [ ] `npm test -w apps/frontend` — PASS -- [ ] `npm run lint -w apps/frontend` — PASS -- [ ] `npm run build -w apps/frontend` — PASS -- [ ] Нет deep imports в `features/screener/` извне -- [ ] `pages/screener/` импортируется только через barrel +- [x] `npm test -w apps/frontend` — PASS +- [x] `npm run lint -w apps/frontend` — PASS +- [x] `npm run build -w apps/frontend` — PASS +- [x] Нет deep imports в `features/screener/` извне +- [x] `pages/screener/` импортируется только через barrel diff --git a/package-lock.json b/package-lock.json index c3e72cb..55bb494 100644 --- a/package-lock.json +++ b/package-lock.json @@ -103,6 +103,9 @@ "@typescript-eslint/parser": "^7.0.0", "@vitejs/plugin-react": "^4.2.0", "eslint": "^8.0.0", + "eslint-import-resolver-alias": "^1.1.2", + "eslint-import-resolver-typescript": "^4.4.5", + "eslint-plugin-import": "^2.32.0", "eslint-plugin-react": "^7.34.0", "eslint-plugin-react-hooks": "^4.6.0", "jsdom": "^29.1.1", @@ -671,6 +674,41 @@ "@esbuild/win32-x64": "0.28.1" } }, + "apps/frontend/node_modules/eslint-import-resolver-typescript": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-4.4.5.tgz", + "integrity": "sha512-nbE5XLph6TLtGYcu/U6e6ZVXyKBhbDWK5cLGk76eJ7NdZpwf1P9EFkpt1Z01mNZNrrilsAYWKH6zUkL4reoXbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "debug": "^4.4.1", + "eslint-import-context": "^0.1.8", + "get-tsconfig": "^4.10.1", + "is-bun-module": "^2.0.0", + "stable-hash-x": "^0.2.0", + "tinyglobby": "^0.2.14", + "unrs-resolver": "^1.7.11" + }, + "engines": { + "node": "^16.17.0 || >=18.6.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, "apps/frontend/node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -9012,6 +9050,13 @@ "win32" ] }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", @@ -10333,6 +10378,13 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "license": "MIT" }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/jsonwebtoken": { "version": "9.0.10", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", @@ -10792,6 +10844,319 @@ "integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==", "license": "ISC" }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", + "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", + "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", + "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", + "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", + "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", + "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", + "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", + "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", + "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", + "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", + "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", + "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", + "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", + "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", + "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", + "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", + "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-openharmony-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", + "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", + "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", + "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", + "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", + "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@upsetjs/venn.js": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@upsetjs/venn.js/-/venn.js-2.0.0.tgz", @@ -11478,6 +11843,28 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.flat": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", @@ -15699,6 +16086,235 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-import-context": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", + "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-tsconfig": "^4.10.1", + "stable-hash-x": "^0.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-context" + }, + "peerDependencies": { + "unrs-resolver": "^1.0.0" + }, + "peerDependenciesMeta": { + "unrs-resolver": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-alias": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-alias/-/eslint-import-resolver-alias-1.1.2.tgz", + "integrity": "sha512-WdviM1Eu834zsfjHtcGHtGfcu+F30Od3V7I9Fi57uhBEwPkjDcii7/yW8jAT+gOhn4P/vOxxNAXbFAKsrrc15w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + }, + "peerDependencies": { + "eslint-plugin-import": ">=1.4.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz", + "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.16.1", + "resolve": "^2.0.0-next.6" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/resolve": { + "version": "2.0.0-next.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", + "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.2", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.13.0.tgz", + "integrity": "sha512-bLohSkT6469rRs8czj0tLTD8vaeIS/whvPRJVjDr7IuoTT1k5DYDERlNycjDj/HkOlvQdYurmfZ/g3fG5bgeLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-import/node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, "node_modules/eslint-plugin-react": { "version": "7.37.5", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", @@ -17146,6 +17762,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-tsconfig": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/giget": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/giget/-/giget-3.3.0.tgz", @@ -18541,6 +19170,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -23456,6 +24095,22 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -23766,6 +24421,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/object.values": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", @@ -27608,6 +28278,16 @@ "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", "license": "MIT" }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/responselike": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", @@ -28947,6 +29627,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/stable-hash-x": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", + "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -30328,6 +31018,44 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/unrs-resolver": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", + "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.4" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.12.2", + "@unrs/resolver-binding-android-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-x64": "1.12.2", + "@unrs/resolver-binding-freebsd-x64": "1.12.2", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", + "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", + "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-musl": "1.12.2", + "@unrs/resolver-binding-openharmony-arm64": "1.12.2", + "@unrs/resolver-binding-wasm32-wasi": "1.12.2", + "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", + "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", + "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" + } + }, "node_modules/until-async": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/until-async/-/until-async-3.0.2.tgz",