diff --git a/packages/angular/cli/BUILD.bazel b/packages/angular/cli/BUILD.bazel index 613785018402..cf913b933bf4 100644 --- a/packages/angular/cli/BUILD.bazel +++ b/packages/angular/cli/BUILD.bazel @@ -61,7 +61,6 @@ ts_project( ":node_modules/@inquirer/prompts", ":node_modules/@listr2/prompt-adapter-inquirer", ":node_modules/@modelcontextprotocol/sdk", - ":node_modules/algoliasearch", ":node_modules/jsonc-parser", ":node_modules/listr2", ":node_modules/npm-package-arg", diff --git a/packages/angular/cli/package.json b/packages/angular/cli/package.json index 749193c32ba8..1d458f516d06 100644 --- a/packages/angular/cli/package.json +++ b/packages/angular/cli/package.json @@ -19,7 +19,6 @@ "@listr2/prompt-adapter-inquirer": "4.2.4", "@modelcontextprotocol/sdk": "1.29.0", "@schematics/angular": "workspace:0.0.0-PLACEHOLDER", - "algoliasearch": "5.56.0", "jsonc-parser": "3.3.1", "listr2": "10.2.2", "npm-package-arg": "14.0.0", diff --git a/packages/angular/cli/src/commands/mcp/tools/doc-search.ts b/packages/angular/cli/src/commands/mcp/tools/doc-search.ts index 145d819f278b..310dd4809067 100644 --- a/packages/angular/cli/src/commands/mcp/tools/doc-search.ts +++ b/packages/angular/cli/src/commands/mcp/tools/doc-search.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.dev/license */ -import type { LegacySearchMethodProps, SearchResponse } from 'algoliasearch'; import { createDecipheriv } from 'node:crypto'; import { Readable } from 'node:stream'; import { z } from 'zod'; @@ -32,7 +31,7 @@ const MIN_SUPPORTED_DOCS_VERSION = 17; * condition where a newly released CLI might default to searching for a documentation index that * doesn't exist yet. */ -const LATEST_KNOWN_DOCS_VERSION = 20; +const LATEST_KNOWN_DOCS_VERSION = 22; const docSearchInputSchema = z.object({ query: z @@ -99,41 +98,86 @@ Searches the official Angular documentation (angular.dev) to answer questions ab }); function createDocSearchHandler({ logger }: McpToolContext) { - let client: import('algoliasearch').SearchClient | undefined; + let apiKey: string | undefined; - return async ({ query, includeTopContent, version }: DocSearchInput) => { - if (!client) { + async function performSearch(query: string, version: number) { + if (!apiKey) { const dcip = createDecipheriv( 'aes-256-gcm', (k1 + ALGOLIA_APP_ID).padEnd(32, '^'), iv, ).setAuthTag(Buffer.from(at, 'base64')); - const { searchClient } = await import('algoliasearch'); - client = searchClient( - ALGOLIA_APP_ID, - dcip.update(ALGOLIA_API_E, 'hex', 'utf-8') + dcip.final('utf-8'), + apiKey = dcip.update(ALGOLIA_API_E, 'hex', 'utf-8') + dcip.final('utf-8'); + } + + const url = `https://${ALGOLIA_APP_ID}-dsn.algolia.net/1/indexes/angular_v${version}/query`; + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Algolia-Application-Id': ALGOLIA_APP_ID, + 'X-Algolia-API-Key': apiKey, + }, + body: JSON.stringify({ + query, + attributesToRetrieve: [ + 'hierarchy.lvl0', + 'hierarchy.lvl1', + 'hierarchy.lvl2', + 'hierarchy.lvl3', + 'hierarchy.lvl4', + 'hierarchy.lvl5', + 'hierarchy.lvl6', + 'content', + 'type', + 'url', + ], + hitsPerPage: 10, + }), + signal: AbortSignal.timeout(5000), // Timeout after 5 seconds + }); + + if (!response.ok) { + throw new Error( + `Search request failed with status ${response.status} (${response.statusText})`, ); } + const data = (await response.json()) as { hits: Record[] }; + + return data.hits; + } + + return async ({ query, includeTopContent, version }: DocSearchInput) => { let finalSearchedVersion = Math.max( version ?? LATEST_KNOWN_DOCS_VERSION, MIN_SUPPORTED_DOCS_VERSION, ); - let searchResults; + + let allHits: Record[] | undefined; try { - searchResults = await client.search(createSearchArguments(query, finalSearchedVersion)); - } catch {} + allHits = await performSearch(query, finalSearchedVersion); + } catch (error) { + logger.warn(`Error searching Angular v${finalSearchedVersion} documentation: ${error}`); + } // If the initial search for a newer-than-stable version returns no results, it may be because // the index for that version doesn't exist yet. In this case, fall back to the latest known // stable version. - if (!searchResults && finalSearchedVersion > LATEST_KNOWN_DOCS_VERSION) { + if ((!allHits || allHits.length === 0) && finalSearchedVersion > LATEST_KNOWN_DOCS_VERSION) { + logger.warn( + `Documentation index for v${finalSearchedVersion} not found or empty. Falling back to v${LATEST_KNOWN_DOCS_VERSION}.`, + ); finalSearchedVersion = LATEST_KNOWN_DOCS_VERSION; - searchResults = await client.search(createSearchArguments(query, finalSearchedVersion)); + try { + allHits = await performSearch(query, finalSearchedVersion); + } catch (error) { + logger.warn( + `Error searching fallback Angular v${finalSearchedVersion} documentation: ${error}`, + ); + } } - const allHits = searchResults?.results.flatMap((result) => (result as SearchResponse).hits); - if (!allHits?.length) { return { content: [ @@ -282,38 +326,3 @@ function formatHitToParts(hit: Record): { title: string; breadc return { title, breadcrumb }; } - -/** - * Creates the search arguments for an Algolia search. - * - * The arguments are based on the search implementation in `adev`. - * - * @param query The search query string. - * @returns The search arguments for the Algolia client. - */ -function createSearchArguments(query: string, version: number): LegacySearchMethodProps { - // Search arguments are based on adev's search service: - // https://github.com/angular/angular/blob/4b614fbb3263d344dbb1b18fff24cb09c5a7582d/adev/shared-docs/services/search.service.ts#L58 - return [ - { - indexName: `angular_v${version}`, - params: { - query, - attributesToRetrieve: [ - 'hierarchy.lvl0', - 'hierarchy.lvl1', - 'hierarchy.lvl2', - 'hierarchy.lvl3', - 'hierarchy.lvl4', - 'hierarchy.lvl5', - 'hierarchy.lvl6', - 'content', - 'type', - 'url', - ], - hitsPerPage: 10, - }, - type: 'default', - }, - ]; -} diff --git a/packages/angular/cli/src/commands/mcp/tools/doc-search_spec.ts b/packages/angular/cli/src/commands/mcp/tools/doc-search_spec.ts new file mode 100644 index 000000000000..b07bec0e9cf6 --- /dev/null +++ b/packages/angular/cli/src/commands/mcp/tools/doc-search_spec.ts @@ -0,0 +1,107 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { createMockContext } from '../testing/test-utils'; +import { DOC_SEARCH_TOOL } from './doc-search'; + +describe('Doc Search Tool', () => { + let mockContext: ReturnType['context']; + let fetchSpy: jasmine.Spy; + + beforeEach(() => { + const { context } = createMockContext(); + mockContext = context; + + fetchSpy = spyOn(globalThis, 'fetch'); + }); + + it('should query the correct Algolia endpoint with headers and payload', async () => { + fetchSpy.and.resolveTo( + new Response( + JSON.stringify({ + hits: [ + { + hierarchy: { + lvl0: 'Docs', + lvl1: 'Standalone Components', + }, + url: 'https://angular.dev/guide/standalone-components', + }, + ], + }), + { status: 200, statusText: 'OK' }, + ), + ); + + const handler = DOC_SEARCH_TOOL.factory(mockContext); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const result = await (handler as any)({ + query: 'standalone', + version: 22, + }); + + expect(fetchSpy).toHaveBeenCalledTimes(1); + const [calledUrl, calledInit] = fetchSpy.calls.first().args; + expect(calledUrl).toBe('https://L1XWT2UJ7F-dsn.algolia.net/1/indexes/angular_v22/query'); + expect(calledInit.method).toBe('POST'); + expect(calledInit.headers['X-Algolia-Application-Id']).toBe('L1XWT2UJ7F'); + expect(calledInit.headers['X-Algolia-API-Key']).toBeDefined(); + + const body = JSON.parse(calledInit.body); + expect(body.query).toBe('standalone'); + + expect(result.structuredContent.searchedVersion).toBe(22); + expect(result.structuredContent.results.length).toBe(1); + expect(result.structuredContent.results[0].title).toBe('Standalone Components'); + }); + + it('should fallback to latest known version if initial search returns no hits', async () => { + // First call returns empty hits + fetchSpy.and.returnValues( + Promise.resolve( + new Response(JSON.stringify({ hits: [] }), { status: 200, statusText: 'OK' }), + ), + // Second fallback call returns a hit + Promise.resolve( + new Response( + JSON.stringify({ + hits: [ + { + hierarchy: { + lvl0: 'Docs', + lvl1: 'Fallback Guide', + }, + url: 'https://angular.dev/guide/fallback', + }, + ], + }), + { status: 200, statusText: 'OK' }, + ), + ), + ); + + const handler = DOC_SEARCH_TOOL.factory(mockContext); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const result = await (handler as any)({ + query: 'some-query', + version: 24, + }); + + expect(fetchSpy).toHaveBeenCalledTimes(2); + expect(fetchSpy.calls.first().args[0]).toBe( + 'https://L1XWT2UJ7F-dsn.algolia.net/1/indexes/angular_v24/query', + ); + expect(fetchSpy.calls.mostRecent().args[0]).toBe( + 'https://L1XWT2UJ7F-dsn.algolia.net/1/indexes/angular_v22/query', + ); + + expect(result.structuredContent.searchedVersion).toBe(22); + expect(result.structuredContent.results.length).toBe(1); + expect(result.structuredContent.results[0].title).toBe('Fallback Guide'); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0cd0711c3395..c3ba8e7810a2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -78,13 +78,13 @@ importers: version: 0.28.0 '@eslint/compat': specifier: 2.1.0 - version: 2.1.0(eslint@10.7.0(jiti@2.7.0)) + version: 2.1.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2)) '@eslint/eslintrc': specifier: 3.3.6 - version: 3.3.6 + version: 3.3.6(supports-color@10.2.2) '@eslint/js': specifier: 10.0.1 - version: 10.0.1(eslint@10.7.0(jiti@2.7.0)) + version: 10.0.1(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2)) '@rollup/plugin-alias': specifier: ^6.0.0 version: 6.0.0(rollup@4.62.2) @@ -102,10 +102,10 @@ importers: version: 4.62.2 '@stylistic/eslint-plugin': specifier: ^5.0.0 - version: 5.10.0(eslint@10.7.0(jiti@2.7.0)) + version: 5.10.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2)) '@tony.ganchev/eslint-plugin-header': specifier: ~3.4.0 - version: 3.4.4(eslint@10.7.0(jiti@2.7.0)) + version: 3.4.4(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2)) '@types/babel__core': specifier: 7.20.5 version: 7.20.5 @@ -165,10 +165,10 @@ importers: version: 21.0.3 '@typescript-eslint/eslint-plugin': specifier: 8.64.0 - version: 8.64.0(@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) + version: 8.64.0(@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) '@typescript-eslint/parser': specifier: 8.64.0 - version: 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) + version: 8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) ajv: specifier: 8.20.0 version: 8.20.0 @@ -183,13 +183,13 @@ importers: version: 0.28.1 eslint: specifier: 10.7.0 - version: 10.7.0(jiti@2.7.0) + version: 10.7.0(jiti@2.7.0)(supports-color@10.2.2) eslint-config-prettier: specifier: 10.1.8 - version: 10.1.8(eslint@10.7.0(jiti@2.7.0)) + version: 10.1.8(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2)) eslint-plugin-import: specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.7.0(jiti@2.7.0)) + version: 2.32.0(@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2)) express: specifier: 5.2.1 version: 5.2.1(supports-color@10.2.2) @@ -282,7 +282,7 @@ importers: version: 1.10.0 verdaccio: specifier: 6.8.0 - version: 6.8.0(encoding@0.1.13) + version: 6.8.0(encoding@0.1.13)(supports-color@10.2.2) verdaccio-auth-memory: specifier: ^13.0.0 version: 13.0.3(supports-color@10.2.2) @@ -468,9 +468,6 @@ importers: '@schematics/angular': specifier: workspace:0.0.0-PLACEHOLDER version: link:../../schematics/angular - algoliasearch: - specifier: 5.56.0 - version: 5.56.0 jsonc-parser: specifier: 3.3.1 version: 3.3.1 @@ -863,62 +860,6 @@ packages: '@actions/io@3.0.2': resolution: {integrity: sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==} - '@algolia/abtesting@1.22.0': - resolution: {integrity: sha512-BFR6zNowNKcY7Ou7TaJc9QWexES4YKPbmf/OTFofpdsdhz4x6q0lbxp3duO0EHnyrN7rE4ba/TSXuY+BDGu4+g==} - engines: {node: '>= 14.0.0'} - - '@algolia/client-abtesting@5.56.0': - resolution: {integrity: sha512-7r4Z3NC7yU1oAQVWJNA2HX7tX481F3pJvCGyLIXiTdBcthz4Q/o21jwcMYDFkuI92UWTNBQQmHYgwHo1zS5dzg==} - engines: {node: '>= 14.0.0'} - - '@algolia/client-analytics@5.56.0': - resolution: {integrity: sha512-avmjXQSq+jadFO8Xl2em05/uQdQnEmHsJyOAdVbZkmVgpMfxL12aJwVVfGNwYr9nulcpuJN1X0lTaQ5wxuNGcA==} - engines: {node: '>= 14.0.0'} - - '@algolia/client-common@5.56.0': - resolution: {integrity: sha512-v2TPStUhY//ripPjIVclZ8AWc7DEGooXULZGFlFu37zNatgHjw34oZZ+OSbbc/YHO+xZwPl62I1k8xH1m4S2eg==} - engines: {node: '>= 14.0.0'} - - '@algolia/client-insights@5.56.0': - resolution: {integrity: sha512-P0ehROpM4Sem3Sqo5x2cKPgj67D3G3jy0rh1Amwkcvsfr6tkvIcdCmerieanqTF7NxUMPNFLkpIFeMO8Rpa50w==} - engines: {node: '>= 14.0.0'} - - '@algolia/client-personalization@5.56.0': - resolution: {integrity: sha512-SXK3Vn3WVxyzbm31oePZBJkp1wpOyuWdd4B/Pv7n0aXDxmeSWhC1R1FC1517mMrFAIaPH4Rt0x6RUe7ZNjz8FA==} - engines: {node: '>= 14.0.0'} - - '@algolia/client-query-suggestions@5.56.0': - resolution: {integrity: sha512-5+ZdX8garFnmycnZgKhtXHePEaLj5zqDxI/0lkhhluzCcvTn0/PvvTirTg8hHYetQHvn7GDyeAiqTAieMvMW4A==} - engines: {node: '>= 14.0.0'} - - '@algolia/client-search@5.56.0': - resolution: {integrity: sha512-+mKUdYvqOi0BcvpAEyCEw49vSBptufIcfibtHz2bdr1pI789M46Yt0uQEk/sxtK3teh71OQvVFHaTDzShUWewQ==} - engines: {node: '>= 14.0.0'} - - '@algolia/ingestion@1.56.0': - resolution: {integrity: sha512-9g/zj+AZx5moFcdFIrYQoVrueXivjUcc3MQHtCYT8WhIuk1lUh1AyEhvJCS0XBZld09cLvd1AZ3BvDBpVpX2UA==} - engines: {node: '>= 14.0.0'} - - '@algolia/monitoring@1.56.0': - resolution: {integrity: sha512-Qf3Sr6f9A9uxCZUf3MXS0d2b877uYzEB5yxqpVGXAhcJnBCQjrRRon0KvefpGkxy+BshrIJs96OUoMtGqXTFDA==} - engines: {node: '>= 14.0.0'} - - '@algolia/recommend@5.56.0': - resolution: {integrity: sha512-GXWG1rWc5wu8hY4N33Y3b6ernY6sAdAvmKWN/zHAiACOx40WnpG0TVX5YazCAr/9gOYGInSiM2A0y2jy2xbiDA==} - engines: {node: '>= 14.0.0'} - - '@algolia/requester-browser-xhr@5.56.0': - resolution: {integrity: sha512-7t24cBxaInS3mZb7ddEaZT/tp6q+/aR4YttsQVyP1/i+LmwPR34atO35KjaLFCcRVrlP7sYOAqkCfg6lIRB+ew==} - engines: {node: '>= 14.0.0'} - - '@algolia/requester-fetch@5.56.0': - resolution: {integrity: sha512-R7ePHgVYmDFjZpvrsVAfbDz/d4RxKAYZ5/vgLfIsCVRZRryjWl/3INOxpOICzitehQ5FjNtNjcLQTrmHPTcHBQ==} - engines: {node: '>= 14.0.0'} - - '@algolia/requester-node-http@5.56.0': - resolution: {integrity: sha512-PIOUXlSnrqM0S+WOgDRb4RzotydJH7ZoT6tOyL7tAO7qJOfvX5wsEW8Pe+PMKMwvuI4/gIyK9cg2H7lJXqnc4Q==} - engines: {node: '>= 14.0.0'} - '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -4103,10 +4044,6 @@ packages: ajv@8.20.0: resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} - algoliasearch@5.56.0: - resolution: {integrity: sha512-PrqppUmhT4ENdas2pH9caE7efUcxy6EcSFhWzosiVuQBzu2tQ5yLTI6jwomT/1cuBnivzGfxiJCqDNN9FRRh+Q==} - engines: {node: '>= 14.0.0'} - ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -8489,90 +8426,6 @@ snapshots: '@actions/io@3.0.2': {} - '@algolia/abtesting@1.22.0': - dependencies: - '@algolia/client-common': 5.56.0 - '@algolia/requester-browser-xhr': 5.56.0 - '@algolia/requester-fetch': 5.56.0 - '@algolia/requester-node-http': 5.56.0 - - '@algolia/client-abtesting@5.56.0': - dependencies: - '@algolia/client-common': 5.56.0 - '@algolia/requester-browser-xhr': 5.56.0 - '@algolia/requester-fetch': 5.56.0 - '@algolia/requester-node-http': 5.56.0 - - '@algolia/client-analytics@5.56.0': - dependencies: - '@algolia/client-common': 5.56.0 - '@algolia/requester-browser-xhr': 5.56.0 - '@algolia/requester-fetch': 5.56.0 - '@algolia/requester-node-http': 5.56.0 - - '@algolia/client-common@5.56.0': {} - - '@algolia/client-insights@5.56.0': - dependencies: - '@algolia/client-common': 5.56.0 - '@algolia/requester-browser-xhr': 5.56.0 - '@algolia/requester-fetch': 5.56.0 - '@algolia/requester-node-http': 5.56.0 - - '@algolia/client-personalization@5.56.0': - dependencies: - '@algolia/client-common': 5.56.0 - '@algolia/requester-browser-xhr': 5.56.0 - '@algolia/requester-fetch': 5.56.0 - '@algolia/requester-node-http': 5.56.0 - - '@algolia/client-query-suggestions@5.56.0': - dependencies: - '@algolia/client-common': 5.56.0 - '@algolia/requester-browser-xhr': 5.56.0 - '@algolia/requester-fetch': 5.56.0 - '@algolia/requester-node-http': 5.56.0 - - '@algolia/client-search@5.56.0': - dependencies: - '@algolia/client-common': 5.56.0 - '@algolia/requester-browser-xhr': 5.56.0 - '@algolia/requester-fetch': 5.56.0 - '@algolia/requester-node-http': 5.56.0 - - '@algolia/ingestion@1.56.0': - dependencies: - '@algolia/client-common': 5.56.0 - '@algolia/requester-browser-xhr': 5.56.0 - '@algolia/requester-fetch': 5.56.0 - '@algolia/requester-node-http': 5.56.0 - - '@algolia/monitoring@1.56.0': - dependencies: - '@algolia/client-common': 5.56.0 - '@algolia/requester-browser-xhr': 5.56.0 - '@algolia/requester-fetch': 5.56.0 - '@algolia/requester-node-http': 5.56.0 - - '@algolia/recommend@5.56.0': - dependencies: - '@algolia/client-common': 5.56.0 - '@algolia/requester-browser-xhr': 5.56.0 - '@algolia/requester-fetch': 5.56.0 - '@algolia/requester-node-http': 5.56.0 - - '@algolia/requester-browser-xhr@5.56.0': - dependencies: - '@algolia/client-common': 5.56.0 - - '@algolia/requester-fetch@5.56.0': - dependencies: - '@algolia/client-common': 5.56.0 - - '@algolia/requester-node-http@5.56.0': - dependencies: - '@algolia/client-common': 5.56.0 - '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.13 @@ -9612,20 +9465,20 @@ snapshots: '@esbuild/win32-x64@0.28.1': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@10.7.0(jiti@2.7.0))': + '@eslint-community/eslint-utils@4.9.1(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))': dependencies: - eslint: 10.7.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0)(supports-color@10.2.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.1.0(eslint@10.7.0(jiti@2.7.0))': + '@eslint/compat@2.1.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))': dependencies: '@eslint/core': 1.2.1 optionalDependencies: - eslint: 10.7.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0)(supports-color@10.2.2) - '@eslint/config-array@0.23.5': + '@eslint/config-array@0.23.5(supports-color@10.2.2)': dependencies: '@eslint/object-schema': 3.0.5 debug: 4.4.3(supports-color@10.2.2) @@ -9641,7 +9494,7 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.6': + '@eslint/eslintrc@3.3.6(supports-color@10.2.2)': dependencies: ajv: 6.15.0 debug: 4.4.3(supports-color@10.2.2) @@ -9655,9 +9508,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@10.0.1(eslint@10.7.0(jiti@2.7.0))': + '@eslint/js@10.0.1(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))': optionalDependencies: - eslint: 10.7.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0)(supports-color@10.2.2) '@eslint/object-schema@3.0.5': {} @@ -11217,11 +11070,11 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@5.10.0(eslint@10.7.0(jiti@2.7.0))': + '@stylistic/eslint-plugin@5.10.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.7.0(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2)) '@typescript-eslint/types': 8.64.0 - eslint: 10.7.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0)(supports-color@10.2.2) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 @@ -11231,9 +11084,9 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.7.0(jiti@2.7.0))': + '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))': dependencies: - eslint: 10.7.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0)(supports-color@10.2.2) '@tybys/wasm-util@0.10.3': dependencies: @@ -11503,15 +11356,15 @@ snapshots: '@types/yarnpkg__lockfile@1.1.9': {} - '@typescript-eslint/eslint-plugin@8.64.0(@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.64.0(@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/parser': 8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) '@typescript-eslint/scope-manager': 8.64.0 - '@typescript-eslint/type-utils': 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/utils': 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/type-utils': 8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/utils': 8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.64.0 - eslint: 10.7.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0)(supports-color@10.2.2) ignore: 7.0.6 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -11519,19 +11372,19 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: '@typescript-eslint/scope-manager': 8.64.0 '@typescript-eslint/types': 8.64.0 - '@typescript-eslint/typescript-estree': 8.64.0(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.64.0(supports-color@10.2.2)(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.64.0 debug: 4.4.3(supports-color@10.2.2) - eslint: 10.7.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0)(supports-color@10.2.2) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.64.0(typescript@6.0.3)': + '@typescript-eslint/project-service@8.64.0(supports-color@10.2.2)(typescript@6.0.3)': dependencies: '@typescript-eslint/tsconfig-utils': 8.64.0(typescript@6.0.3) '@typescript-eslint/types': 8.64.0 @@ -11549,13 +11402,13 @@ snapshots: dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: '@typescript-eslint/types': 8.64.0 - '@typescript-eslint/typescript-estree': 8.64.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.64.0(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/utils': 8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(typescript@6.0.3) debug: 4.4.3(supports-color@10.2.2) - eslint: 10.7.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0)(supports-color@10.2.2) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: @@ -11563,9 +11416,9 @@ snapshots: '@typescript-eslint/types@8.64.0': {} - '@typescript-eslint/typescript-estree@8.64.0(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.64.0(supports-color@10.2.2)(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.64.0(typescript@6.0.3) + '@typescript-eslint/project-service': 8.64.0(supports-color@10.2.2)(typescript@6.0.3) '@typescript-eslint/tsconfig-utils': 8.64.0(typescript@6.0.3) '@typescript-eslint/types': 8.64.0 '@typescript-eslint/visitor-keys': 8.64.0 @@ -11578,13 +11431,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/utils@8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.7.0(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2)) '@typescript-eslint/scope-manager': 8.64.0 '@typescript-eslint/types': 8.64.0 - '@typescript-eslint/typescript-estree': 8.64.0(typescript@6.0.3) - eslint: 10.7.0(jiti@2.7.0) + '@typescript-eslint/typescript-estree': 8.64.0(supports-color@10.2.2)(typescript@6.0.3) + eslint: 10.7.0(jiti@2.7.0)(supports-color@10.2.2) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -11594,7 +11447,7 @@ snapshots: '@typescript-eslint/types': 8.64.0 eslint-visitor-keys: 5.0.1 - '@verdaccio/auth@8.0.4': + '@verdaccio/auth@8.0.4(supports-color@10.2.2)': dependencies: '@verdaccio/config': 8.1.2 '@verdaccio/core': 8.1.2 @@ -11628,7 +11481,7 @@ snapshots: dependencies: lockfile: 1.0.4 - '@verdaccio/hooks@8.0.4': + '@verdaccio/hooks@8.0.4(supports-color@10.2.2)': dependencies: '@verdaccio/core': 8.1.2 '@verdaccio/logger': 8.0.3 @@ -11646,7 +11499,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/local-storage-legacy@11.3.4': + '@verdaccio/local-storage-legacy@11.3.4(supports-color@10.2.2)': dependencies: '@verdaccio/core': 8.1.2 '@verdaccio/file-locking': 13.0.1 @@ -11685,7 +11538,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/middleware@8.0.5': + '@verdaccio/middleware@8.0.5(supports-color@10.2.2)': dependencies: '@verdaccio/config': 8.1.2 '@verdaccio/core': 8.1.2 @@ -11698,7 +11551,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/package-filter@13.0.3': + '@verdaccio/package-filter@13.0.3(supports-color@10.2.2)': dependencies: '@verdaccio/core': 8.1.2 debug: 4.4.3(supports-color@10.2.2) @@ -11706,7 +11559,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/search-indexer@8.0.2': + '@verdaccio/search-indexer@8.0.2(supports-color@10.2.2)': dependencies: debug: 4.4.3(supports-color@10.2.2) fuse.js: 7.3.0 @@ -11724,7 +11577,7 @@ snapshots: '@verdaccio/streams@10.2.5': {} - '@verdaccio/tarball@13.0.3': + '@verdaccio/tarball@13.0.3(supports-color@10.2.2)': dependencies: '@verdaccio/core': 8.1.2 '@verdaccio/url': 13.0.3 @@ -11736,7 +11589,7 @@ snapshots: - react-native-b4a - supports-color - '@verdaccio/ui-theme@9.0.0-next-9.21': + '@verdaccio/ui-theme@9.0.0-next-9.21(supports-color@10.2.2)': dependencies: debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: @@ -11933,7 +11786,7 @@ snapshots: loader-utils: 2.0.4 regex-parser: 2.3.1 - agent-base@6.0.2: + agent-base@6.0.2(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: @@ -11977,23 +11830,6 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - algoliasearch@5.56.0: - dependencies: - '@algolia/abtesting': 1.22.0 - '@algolia/client-abtesting': 5.56.0 - '@algolia/client-analytics': 5.56.0 - '@algolia/client-common': 5.56.0 - '@algolia/client-insights': 5.56.0 - '@algolia/client-personalization': 5.56.0 - '@algolia/client-query-suggestions': 5.56.0 - '@algolia/client-search': 5.56.0 - '@algolia/ingestion': 1.56.0 - '@algolia/monitoring': 1.56.0 - '@algolia/recommend': 5.56.0 - '@algolia/requester-browser-xhr': 5.56.0 - '@algolia/requester-fetch': 5.56.0 - '@algolia/requester-node-http': 5.56.0 - ansi-colors@4.1.3: {} ansi-escapes@7.3.0: @@ -13072,9 +12908,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.7.0(jiti@2.7.0)): + eslint-config-prettier@10.1.8(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2)): dependencies: - eslint: 10.7.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0)(supports-color@10.2.2) eslint-import-resolver-node@0.3.10: dependencies: @@ -13084,17 +12920,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.7.0(jiti@2.7.0)): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) - eslint: 10.7.0(jiti@2.7.0) + '@typescript-eslint/parser': 8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + eslint: 10.7.0(jiti@2.7.0)(supports-color@10.2.2) eslint-import-resolver-node: 0.3.10 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.7.0(jiti@2.7.0)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -13103,9 +12939,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 10.7.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0)(supports-color@10.2.2) eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.7.0(jiti@2.7.0)) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2)) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -13117,7 +12953,7 @@ snapshots: string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/parser': 8.64.0(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -13141,11 +12977,11 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.7.0(jiti@2.7.0): + eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.7.0(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.7.0(jiti@2.7.0)(supports-color@10.2.2)) '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.23.5 + '@eslint/config-array': 0.23.5(supports-color@10.2.2) '@eslint/config-helpers': 0.6.0 '@eslint/core': 1.2.1 '@eslint/plugin-kit': 0.7.2 @@ -13937,9 +13773,9 @@ snapshots: quick-lru: 5.1.1 resolve-alpn: 1.2.1 - https-proxy-agent@5.0.1: + https-proxy-agent@5.0.1(supports-color@10.2.2): dependencies: - agent-base: 6.0.2 + agent-base: 6.0.2(supports-color@10.2.2) debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -16568,12 +16404,12 @@ snapshots: vary@1.1.2: {} - verdaccio-audit@13.0.3(encoding@0.1.13): + verdaccio-audit@13.0.3(encoding@0.1.13)(supports-color@10.2.2): dependencies: '@verdaccio/config': 8.1.2 '@verdaccio/core': 8.1.2 express: 4.22.1 - https-proxy-agent: 5.0.1 + https-proxy-agent: 5.0.1(supports-color@10.2.2) node-fetch: 2.6.7(encoding@0.1.13) transitivePeerDependencies: - encoding @@ -16598,23 +16434,23 @@ snapshots: transitivePeerDependencies: - supports-color - verdaccio@6.8.0(encoding@0.1.13): + verdaccio@6.8.0(encoding@0.1.13)(supports-color@10.2.2): dependencies: '@cypress/request': 3.0.10 - '@verdaccio/auth': 8.0.4 + '@verdaccio/auth': 8.0.4(supports-color@10.2.2) '@verdaccio/config': 8.1.2 '@verdaccio/core': 8.1.2 - '@verdaccio/hooks': 8.0.4 + '@verdaccio/hooks': 8.0.4(supports-color@10.2.2) '@verdaccio/loaders': 8.0.3 - '@verdaccio/local-storage-legacy': 11.3.4 + '@verdaccio/local-storage-legacy': 11.3.4(supports-color@10.2.2) '@verdaccio/logger': 8.0.3 - '@verdaccio/middleware': 8.0.5 - '@verdaccio/package-filter': 13.0.3 - '@verdaccio/search-indexer': 8.0.2 + '@verdaccio/middleware': 8.0.5(supports-color@10.2.2) + '@verdaccio/package-filter': 13.0.3(supports-color@10.2.2) + '@verdaccio/search-indexer': 8.0.2(supports-color@10.2.2) '@verdaccio/signature': 8.0.3 '@verdaccio/streams': 10.2.5 - '@verdaccio/tarball': 13.0.3 - '@verdaccio/ui-theme': 9.0.0-next-9.21 + '@verdaccio/tarball': 13.0.3(supports-color@10.2.2) + '@verdaccio/ui-theme': 9.0.0-next-9.21(supports-color@10.2.2) '@verdaccio/url': 13.0.3 '@verdaccio/utils': 8.1.3 JSONStream: 1.3.5 @@ -16629,7 +16465,7 @@ snapshots: lru-cache: 7.18.3 mime: 3.0.0 semver: 7.8.5 - verdaccio-audit: 13.0.3(encoding@0.1.13) + verdaccio-audit: 13.0.3(encoding@0.1.13)(supports-color@10.2.2) verdaccio-htpasswd: 13.0.3 transitivePeerDependencies: - bare-abort-controller