diff --git a/.env.example b/.env.example index 27268fe28..2c4be9065 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,8 @@ -ALGOLIA_API_KEY=algolia_api_key -ALGOLIA_APPLICATION_ID=algolia_application_id +TYPESENSE_URL=https://your-cluster.a1.typesense.net +TYPESENSE_PUBLIC_API_KEY=your_search_only_api_key +TYPESENSE_PRIVATE_API_KEY=typesense_private_api_key_required_for_indexing_only +# Optional. Overrides the branch-derived read alias. +# TYPESENSE_COLLECTION=directus-docs DIRECTUS_URL=https://marketing-directus-url.com GOOGLE_TAG_MANAGER_ID=GTM-PTLT3GH POSTHOG_API_HOST=https://directus.io/ingest diff --git a/.github/workflows/search-index.yml b/.github/workflows/search-index.yml new file mode 100644 index 000000000..e292f2f91 --- /dev/null +++ b/.github/workflows/search-index.yml @@ -0,0 +1,80 @@ +name: Search Index + +on: + push: + branches: + - main + paths: &index-paths + - 'content/**' + - 'scripts/index-docs.ts' + - 'scripts/index-docs-chunker.ts' + - 'shared/utils/parseTypesenseUrl.ts' + - 'shared/utils/docsSections.ts' + - 'app/utils/slugify.ts' + - 'server/data/synonyms.ts' + - 'lib/typesenseAlias.ts' + - 'pnpm-lock.yaml' + - '.github/workflows/search-index.yml' + pull_request: + branches: + - main + paths: *index-paths + workflow_dispatch: + +concurrency: + group: search-index-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +permissions: + contents: read + +jobs: + preview-index: + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + env: + TYPESENSE_URL: ${{ secrets.TYPESENSE_URL }} + TYPESENSE_PUBLIC_API_KEY: ${{ secrets.TYPESENSE_PUBLIC_API_KEY }} + TYPESENSE_PRIVATE_API_KEY: ${{ secrets.TYPESENSE_PRIVATE_API_KEY }} + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + with: + version: 10.29.2 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Index preview collection + run: pnpm index:docs + + prod-index: + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + env: + TYPESENSE_URL: ${{ secrets.TYPESENSE_URL }} + TYPESENSE_PUBLIC_API_KEY: ${{ secrets.TYPESENSE_PUBLIC_API_KEY }} + TYPESENSE_PRIVATE_API_KEY: ${{ secrets.TYPESENSE_PRIVATE_API_KEY }} + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + with: + version: 10.29.2 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Index production collection + run: pnpm index:docs diff --git a/.nuxtrc b/.nuxtrc new file mode 100644 index 000000000..ce850a63b --- /dev/null +++ b/.nuxtrc @@ -0,0 +1 @@ +setups.@nuxt/test-utils="4.0.3" diff --git a/README.md b/README.md index 6fdffce77..8675d90f9 100644 --- a/README.md +++ b/README.md @@ -49,13 +49,14 @@ pnpm build ### Repository Tooling -The repository includes scripts that keep docs routes stable when files move. +The repository includes scripts that keep docs routes stable when files move and that index the docs into Typesense. ```bash pnpm stable-ids:ensure # Add missing stableId frontmatter pnpm stable-ids:check # Validate stableId frontmatter pnpm redirects:sync # Update redirects.json for moved pages pnpm redirects:check # Check redirect coverage without writing files +pnpm index:docs # Build the search index in Typesense pnpm typecheck:scripts # Type check repository scripts ``` @@ -109,9 +110,45 @@ The documentation automatically deploys to Vercel when changes are merged into t - [GitHub Issues](https://github.com/directus/docs/issues) (Report Bugs) - [Roadmap](https://roadmap.directus.io) (Roadmap & Feature Requests) -## Making changes to Algolia Search +## 🔍 Search -The docs make use of the Algolia Crawler to index the content. The crawler is found at the bottom left in the Algolia dashboard under `Data Sources > Crawler > directus`. To make changes on how the crawler works, go to the `Editor` tab and make your changes. By default the crawler runs once a day but you can also manually run it. In order to tweak the ranking of search results, go to the `Search > Configure > Index > Configuration > Ranking and Sorting` tab. +Search is powered by [Typesense](https://typesense.org). The browser palette (`UCommandPalette`-based) lives at `app/components/DocsSearchPalette.vue` and queries Typesense directly via `app/services/typesenseService.ts`. The official `typesense` npm client is used by the indexer only. + +### Indexing + +The indexer at `scripts/index-docs.ts` walks `/content`, chunks each Markdown page, attaches synonyms, and pushes everything to Typesense. OpenAPI indexing is deferred to a later branch. Run it locally with: + +```bash +pnpm index:docs +``` + +CI runs the same command on every push to `main` (production index) and on every PR commit (per-branch preview index). See `.github/workflows/search-index.yml`. + +### Collection naming + +Indexes use a blue/green slot pattern with a stable alias: + +- `main` -> alias `directus-docs`, slots `directus-docs-a` / `directus-docs-b` +- Branch `bry/foo` -> alias `directus-docs-preview-bry-foo`, slots `...-a` / `...-b` +- Local branch runs use the same branch-derived alias as CI + +Each indexer run writes to whichever slot the alias is not currently pointing at, swaps the alias, then deletes the previous slot. + +For one-off writes, override the index target with `TYPESENSE_INDEX_TARGET=...`. + +The browser reads from `TYPESENSE_COLLECTION` when set. Otherwise it derives the same branch alias as the indexer. The app reads the alias, never the `-a` / `-b` slot name. + +### Ranking + +Section boosts and personalization live in `buildPersonalizedSortBy` in `app/composables/useDocsSearch.ts`. The same `sectionPriority` array drives both the Typesense `_eval` boost order and the chip-bar render order in the palette. + +### Synonyms + +Search synonyms live in `server/data/synonyms.ts` and are pushed to Typesense on every indexer run. Two formats: `multiway` (equivalent terms) and `oneway` (directional shorthand -> canonical, e.g. `db -> database`). Header comment in the file explains both. + +### Search-friendly content + +Write H2s and first paragraphs so they work as standalone search results.
diff --git a/app/app.config.ts b/app/app.config.ts index 5f64020cb..d787a0778 100644 --- a/app/app.config.ts +++ b/app/app.config.ts @@ -1,6 +1,6 @@ export default defineAppConfig({ search: { - backend: 'algolia', + backend: 'typesense', }, ui: { diff --git a/app/assets/css/algolia.css b/app/assets/css/algolia.css deleted file mode 100644 index 694701b24..000000000 --- a/app/assets/css/algolia.css +++ /dev/null @@ -1,30 +0,0 @@ -html.light { - --docsearch-primary-color: var(--color-primary-500); -} - -html.dark[data-theme='dark'] { - --docsearch-primary-color: var(--color-primary-400); - - --docsearch-text-color: rgb(245, 246, 247); - --docsearch-container-background: color-mix(in srgb, var(--color-neutral-950), transparent 20%); - --docsearch-modal-background: var(--color-neutral-800); - --docsearch-modal-shadow: inset 1px 1px 0 0 var(--docsearch-footer-background), - 0 3px 8px 0 rgb(var(--color-neutral-950)); - --docsearch-searchbox-background: var(--color-neutral-800); - --docsearch-searchbox-focus-background: var(--color-neutral-950); - --docsearch-hit-color: rgb(190, 195, 201); - --docsearch-hit-shadow: none; - --docsearch-hit-background: color-mix(in srgb, var(--color-neutral-700) 30%, transparent); - --docsearch-key-gradient: var(--color-neutral-900); - --docsearch-key-shadow: transparent; - --docsearch-key-pressed-shadow: transparent; - --docsearch-footer-background: color-mix(in srgb, rgb(var(--color-neutral-800)) 70%, rgb(var(--color-neutral-900))); - --docsearch-footer-shadow: inset 0 1px 0 0 rgba(var(--color-neutral-700), 0.5), - 0 -4px 8px 0 rgba(0, 0, 0, 0.2); - --docsearch-logo-color: rgb(255, 255, 255); - --docsearch-muted-color: rgb(var(--color-neutral-500)); -} - -.DocSearch-Container { - backdrop-filter: blur(2px) -} diff --git a/app/components/DocsSearchPalette.vue b/app/components/DocsSearchPalette.vue new file mode 100644 index 000000000..daa3364af --- /dev/null +++ b/app/components/DocsSearchPalette.vue @@ -0,0 +1,860 @@ + + + + + + + diff --git a/app/components/DocsSearchPreview.vue b/app/components/DocsSearchPreview.vue new file mode 100644 index 000000000..3b6446479 --- /dev/null +++ b/app/components/DocsSearchPreview.vue @@ -0,0 +1,130 @@ + + + diff --git a/app/components/DocsSearchTrigger.vue b/app/components/DocsSearchTrigger.vue index 71d9ef86a..849cd0ee5 100644 --- a/app/components/DocsSearchTrigger.vue +++ b/app/components/DocsSearchTrigger.vue @@ -1,99 +1,34 @@ - - diff --git a/app/components/HomeHero.vue b/app/components/HomeHero.vue index 042546614..eb4892b19 100644 --- a/app/components/HomeHero.vue +++ b/app/components/HomeHero.vue @@ -9,14 +9,12 @@ function openSearch() {
-
-
- - + +
@@ -67,4 +81,16 @@ function openSearch() { -webkit-mask-size: 100% 100%; mask-size: 100% 100%; } + +.home-hero-search { + background: rgba(255, 255, 255, 0.04); + border: 1px solid rgba(255, 255, 255, 0.08); + transition: border-color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease; +} + +.home-hero-search:hover { + background: rgba(255, 255, 255, 0.06); + border-color: color-mix(in oklab, var(--color-primary) 45%, transparent); + box-shadow: 0 0 0 4px color-mix(in oklab, var(--color-primary) 12%, transparent); +} diff --git a/app/composables/useDocsSearch.ts b/app/composables/useDocsSearch.ts new file mode 100644 index 000000000..136b5f146 --- /dev/null +++ b/app/composables/useDocsSearch.ts @@ -0,0 +1,195 @@ +import type { DocsSectionId } from '#shared/utils/docsSections'; +import { getTypesenseService } from '~/services/typesenseService'; +import type { DocsSearchDocument, DocsSearchItem } from '~/utils/searchResults'; +import { + buildPersonalizedSortBy, + flattenGroups, + hasDynamicPersonalization, +} from '~/utils/searchResults'; + +export default function useDocsSearch() { + if (import.meta.server) return null; + + const config = useRuntimeConfig(); + const { prefs } = useUserPreferences(); + const query = ref(''); + const section = ref<'all' | DocsSectionId>('all'); + const pending = ref(false); + const found = ref(0); + const items = ref([]); + const sectionCounts = ref(new Map()); + if (!config.public.typesenseUrl || !config.public.typesensePublicApiKey || !config.public.typesenseCollection) { + console.warn('[search] Typesense env not configured. Search disabled.'); + return null; + } + + const service = getTypesenseService({ + typesenseUrl: config.public.typesenseUrl, + typesensePublicApiKey: config.public.typesensePublicApiKey, + }); + + /* Two chars keeps the palette responsive for short docs terms like `ai`, while still avoiding the noisy / jarring 1-character search state. */ + const minQueryLength = 2; + const isTooShort = computed(() => { + const currentQuery = query.value.trim(); + return currentQuery.length > 0 && currentQuery.length < minQueryLength; + }); + let abortController: AbortController | null = null; + let requestId = 0; + + function abort() { + abortController?.abort(); + abortController = null; + } + + function resetResults() { + found.value = 0; + items.value = []; + sectionCounts.value = new Map(); + } + + async function runSearch() { + const currentQuery = query.value.trim(); + if (currentQuery.length < minQueryLength) { + abort(); + pending.value = false; + resetResults(); + return; + } + + const currentRequestId = ++requestId; + abort(); + abortController = new AbortController(); + pending.value = true; + + try { + const sortBy = buildPersonalizedSortBy(prefs.value); + const result = await service.search({ + indexName: config.public.typesenseCollection, + searchConfig: { + /* + Search across both page-level and chunk-level fields. We group by + `group_id` below so Typesense can rank by the best matching chunk, + while the UI still renders a single page-level result. + + `search_title` and `title` are weighted highest because they best + reflect page intent. `content` and `code_blocks` stay searchable, + but lower, so exact body snippets don't dominate broad queries. + */ + query_by: 'search_title,title,heading,hierarchy,path_tokens,content,code_blocks', + query_by_weights: '10,8,6,5,4,3,2', + sort_by: sortBy, + /* + Collapse chunks from the same page into one result. `group_id` is + assigned per page during indexing. + */ + group_by: 'group_id', + /* + Keep the top 3 hits per page so matched headings stay available + without inflating the result count. + */ + group_limit: 3, + /* + Section counts power the footer chip bar. One facet keeps the + refinement multi_search cheap. + */ + facet_by: 'section', + /* + Use snippet highlights for content previews. + */ + highlight_fields: 'search_title,title,heading,content', + /* + Identical list is intentional. Full highlights are used for + title, heading, and search_title rendering paths. + */ + highlight_full_fields: 'search_title,title,heading,content', + /* + Trim the payload to fields used by buildSearchItem and + flattenGroups. + */ + include_fields: 'id,group_id,url,title,search_title,description,anchor,heading,hierarchy,path_tokens,path_depth,rank_order,section,doc_type,technologies,content,weight,chunk_index', + /* + Personalized sort clauses change per user, so only cache when the + query shape stays stable. + */ + use_cache: !hasDynamicPersonalization(prefs.value), + }, + state: { + query: currentQuery, + page: 1, + hitsPerPage: 12, + sort: sortBy, + filters: section.value === 'all' ? {} : { section: [section.value] }, + }, + facetRefinementAttributes: ['section'], + }, abortController.signal); + + if (currentRequestId !== requestId) return; + + items.value = flattenGroups(result); + sectionCounts.value = new Map( + (result.facets.section ?? []) + .map(entry => [entry.value as DocsSectionId, entry.count] as const), + ); + /* When a section filter is active, `result.found` is the filtered count. Sum the unfiltered facet counts so the "All" chip shows a stable cross-section total regardless of selection. */ + found.value = section.value === 'all' + ? result.found + : [...sectionCounts.value.values()].reduce((sum, n) => sum + n, 0); + } + catch (searchError) { + if (searchError instanceof Error && searchError.name === 'AbortError') { + return; + } + if (currentRequestId !== requestId) return; + resetResults(); + } + finally { + if (currentRequestId === requestId) { + pending.value = false; + } + } + } + + /* Small debounce to avoid spamming Typesense while still feeling instant. */ + const debouncedSearch = useDebounceFn(runSearch, 150); + + watch([ + query, + section, + () => prefs.value.framework, + () => prefs.value.deployment, + ], () => { + const currentQuery = query.value.trim(); + if (currentQuery.length < minQueryLength) { + abort(); + pending.value = false; + resetResults(); + return; + } + + pending.value = true; + debouncedSearch(); + }); + + onScopeDispose(() => { + abort(); + }); + + return { + query, + section, + pending, + found, + items, + sectionCounts, + minQueryLength, + isTooShort, + clear() { + abort(); + query.value = ''; + section.value = 'all'; + pending.value = false; + resetResults(); + }, + }; +} diff --git a/app/composables/useSearchOverlay.ts b/app/composables/useSearchOverlay.ts index 85e2fa562..8d13c4565 100644 --- a/app/composables/useSearchOverlay.ts +++ b/app/composables/useSearchOverlay.ts @@ -1,10 +1,7 @@ import { createSharedComposable } from '@vueuse/core'; +import { LazyDocsSearchPalette } from '#components'; export const useSearchOverlay = createSharedComposable(() => { - function open() { - if (!import.meta.client) return; - document.querySelector('#docsearch .DocSearch-Button')?.click(); - } - - return { open }; + const overlay = useOverlay(); + return overlay.create(LazyDocsSearchPalette); }); diff --git a/app/services/typesenseService.ts b/app/services/typesenseService.ts new file mode 100644 index 000000000..97b8308d9 --- /dev/null +++ b/app/services/typesenseService.ts @@ -0,0 +1,254 @@ +import { parseTypesenseUrl } from '#shared/utils/parseTypesenseUrl'; + +export interface TypesenseSearchState { + query: string; + page: number; + hitsPerPage: number; + sort?: string; + filters: Record; +} + +export interface TypesenseSearchConfig { + query_by: string; + query_by_weights?: string; + facet_by?: string; + sort_by?: string; + filter_by?: string; + group_by?: string; + group_limit?: number; + include_fields?: string; + highlight_fields?: string; + highlight_full_fields?: string; + prefix?: string | boolean; + use_cache?: boolean; +} + +export interface TypesenseSearchParams { + indexName: string; + searchConfig: TypesenseSearchConfig; + state: TypesenseSearchState; + /** + * Facet attributes that need unfiltered counts. When the user has applied a + * filter on one of these attributes, we fire a parallel multi_search query + * with that filter removed so the filter widget can still show counts for + * unselected values. https://typesense.org/docs/30.2/api/search.html#facet-results + */ + facetRefinementAttributes?: string[]; +} + +export interface TypesenseFacetCount { + value: string; + count: number; + highlighted?: string; +} + +export interface TypesenseFacetResults { + [field: string]: TypesenseFacetCount[]; +} + +export interface TypesenseSearchHit> { + document: TDocument; + highlights?: Array>; + highlight?: Record; + text_match?: number; + text_match_info?: Record; +} + +export interface TypesenseGroupedHit> { + group_key: string[]; + hits: TypesenseSearchHit[]; + found?: number; +} + +export interface TypesenseSearchResult> { + hits: TypesenseSearchHit[]; + grouped_hits?: TypesenseGroupedHit[]; + facets: TypesenseFacetResults; + found: number; + search_time_ms: number; + page: number; + out_of: number; +} + +interface TypesenseServiceOptions { + typesenseUrl: string; + typesensePublicApiKey: string; +} + +interface TypesenseAPISearchParams { + q: string; + query_by: string; + page: number; + per_page: number; + query_by_weights?: string; + facet_by?: string; + sort_by?: string; + filter_by?: string; + group_by?: string; + group_limit?: number; + include_fields?: string; + highlight_fields?: string; + highlight_full_fields?: string; + prefix?: string | boolean; + use_cache?: boolean; +} + +interface RawSearchResponse { + hits?: TypesenseSearchHit[]; + grouped_hits?: TypesenseGroupedHit[]; + facet_counts?: Array<{ field_name: string; counts: Array<{ value: string; count: number; highlighted?: string }> }>; + found?: number; + page?: number; + out_of?: number; +} + +export class TypesenseService { + private typesenseNode: ReturnType; + private typesensePublicApiKey: string; + + constructor(options: TypesenseServiceOptions) { + this.typesenseNode = parseTypesenseUrl(options.typesenseUrl); + this.typesensePublicApiKey = options.typesensePublicApiKey; + } + + private get baseUrl() { + const path = this.typesenseNode.path ?? ''; + return `${this.typesenseNode.protocol}://${this.typesenseNode.host}:${this.typesenseNode.port}${path}`; + } + + private buildSearchParams({ searchConfig, state }: TypesenseSearchParams, excludeFilterAttribute?: string): TypesenseAPISearchParams { + const params: TypesenseAPISearchParams = { + q: state.query || '*', + query_by: searchConfig.query_by, + page: state.page, + per_page: state.hitsPerPage, + }; + + if (searchConfig.query_by_weights) params.query_by_weights = searchConfig.query_by_weights; + if (searchConfig.facet_by) params.facet_by = searchConfig.facet_by; + if (state.sort) params.sort_by = state.sort; + else if (searchConfig.sort_by) params.sort_by = searchConfig.sort_by; + if (searchConfig.group_by) params.group_by = searchConfig.group_by; + if (searchConfig.group_limit) params.group_limit = searchConfig.group_limit; + if (searchConfig.include_fields) params.include_fields = searchConfig.include_fields; + if (searchConfig.highlight_fields) params.highlight_fields = searchConfig.highlight_fields; + if (searchConfig.highlight_full_fields) params.highlight_full_fields = searchConfig.highlight_full_fields; + if (searchConfig.prefix !== undefined) params.prefix = searchConfig.prefix; + if (searchConfig.use_cache !== undefined) params.use_cache = searchConfig.use_cache; + + const filterParts: string[] = []; + if (searchConfig.filter_by) filterParts.push(searchConfig.filter_by); + for (const [attribute, values] of Object.entries(state.filters)) { + if (values.length === 0 || attribute === excludeFilterAttribute) continue; + const clause = values.map(value => `${attribute}:=${value}`).join(' || '); + filterParts.push(`(${clause})`); + } + if (filterParts.length > 0) params.filter_by = filterParts.join(' && '); + + return params; + } + + private toFacets(facetCounts: RawSearchResponse['facet_counts']): TypesenseFacetResults { + const facets: TypesenseFacetResults = {}; + for (const facetCount of facetCounts ?? []) { + facets[facetCount.field_name] = facetCount.counts.map(count => ({ + value: count.value, + count: count.count, + highlighted: count.highlighted, + })); + } + return facets; + } + + async search>( + params: TypesenseSearchParams, + signal?: AbortSignal, + ): Promise> { + const requestStartTime = performance.now(); + const refinementAttributes = (params.facetRefinementAttributes ?? []) + .filter(attribute => params.state.filters[attribute]?.length); + + if (refinementAttributes.length === 0) { + const apiParams = this.buildSearchParams(params); + const url = new URL(`${this.baseUrl}/collections/${params.indexName}/documents/search`); + for (const [key, value] of Object.entries(apiParams)) { + url.searchParams.append(key, String(value)); + } + + const response = await $fetch>(url.toString(), { + headers: { 'X-TYPESENSE-API-KEY': this.typesensePublicApiKey }, + signal, + }); + + return { + hits: response.hits ?? [], + grouped_hits: response.grouped_hits ?? [], + facets: this.toFacets(response.facet_counts), + found: response.found ?? 0, + search_time_ms: Math.round(performance.now() - requestStartTime), + page: response.page ?? 1, + out_of: response.out_of ?? 0, + }; + } + + // Refinement path: fire the main search + one facet-only search per + // refinement attribute (each with that attribute's filter removed) in a + // single multi_search request, then merge the facet counts back. + const searches: Array = [ + { ...this.buildSearchParams(params), collection: params.indexName }, + ]; + for (const attribute of refinementAttributes) { + searches.push({ + ...this.buildSearchParams(params, attribute), + collection: params.indexName, + facet_by: attribute, + per_page: 0, + }); + } + + const response = await $fetch<{ results: RawSearchResponse[] }>(`${this.baseUrl}/multi_search`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-TYPESENSE-API-KEY': this.typesensePublicApiKey, + }, + body: { searches }, + signal, + }); + + const main = response.results[0]!; + const facets = this.toFacets(main.facet_counts); + for (const [index, attribute] of refinementAttributes.entries()) { + const refinement = response.results[index + 1]; + const refinementCount = refinement?.facet_counts?.find(entry => entry.field_name === attribute); + if (refinementCount) { + facets[attribute] = refinementCount.counts.map(count => ({ + value: count.value, + count: count.count, + highlighted: count.highlighted, + })); + } + } + + return { + hits: main.hits ?? [], + grouped_hits: main.grouped_hits ?? [], + facets, + found: main.found ?? 0, + search_time_ms: Math.round(performance.now() - requestStartTime), + page: main.page ?? 1, + out_of: main.out_of ?? 0, + }; + } +} + +let typesenseService: TypesenseService | null = null; + +export function getTypesenseService(options?: TypesenseServiceOptions) { + if (!typesenseService) { + if (!options) throw new Error('getTypesenseService: first call requires options'); + typesenseService = new TypesenseService(options); + } + + return typesenseService; +} diff --git a/app/utils/highlightHtml.ts b/app/utils/highlightHtml.ts new file mode 100644 index 000000000..e7daa2cde --- /dev/null +++ b/app/utils/highlightHtml.ts @@ -0,0 +1,21 @@ +const MARK_OPEN = '\uE000'; +const MARK_CLOSE = '\uE001'; + +function escapeHtml(value: string) { + return value + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + +export function sanitizeHighlightHtml(value: string) { + return escapeHtml( + value + .replace(//gi, MARK_OPEN) + .replace(/<\/mark>/gi, MARK_CLOSE), + ) + .replaceAll(MARK_OPEN, '') + .replaceAll(MARK_CLOSE, ''); +} diff --git a/app/utils/searchResults.ts b/app/utils/searchResults.ts new file mode 100644 index 000000000..ca25a29a4 --- /dev/null +++ b/app/utils/searchResults.ts @@ -0,0 +1,218 @@ +import { withoutBase } from 'ufo'; +import type { + TypesenseGroupedHit, + TypesenseSearchHit, + TypesenseSearchResult, +} from '~/services/typesenseService'; +import type { DocsSectionId } from '#shared/utils/docsSections'; +import { docsSections } from '#shared/utils/docsSections'; + +export interface DocsSearchDocument { + id: string; + group_id: string; + url: string; + title: string; + search_title: string; + description?: string; + anchor?: string; + heading?: string; + hierarchy: string[]; + path_tokens: string; + path_depth: number; + rank_order: number; + section: DocsSectionId; + doc_type: 'page' | 'api-operation' | 'api-tag'; + technologies?: string[]; + content: string; + code_blocks?: string[]; + weight: number; + chunk_index: number; +} + +export interface DocsSearchItem { + id: string; + to: string; + title: string; + titleHtml?: string; + breadcrumb: string; + snippetHtml?: string; + content: string; + description?: string; + matchedHeadings: string[]; + section: DocsSectionId; + sectionLabel: string; + framework?: string; + docTypeLabel: string; + docType: DocsSearchDocument['doc_type']; +} + +export interface UserSearchPrefs { + framework?: string | null; + deployment?: string | null; +} + +function clipSnippet(value: string, limit = 140) { + if (value.length <= limit) return value; + return `${value.slice(0, limit - 1).trimEnd()}…`; +} + +function normalizeSnippet(value: string) { + return value.replace(/\s+/g, ' ').trim(); +} + +function getHighlightMap(hit: TypesenseSearchHit) { + const entries = Array.isArray(hit.highlights) ? hit.highlights : []; + const highlights = new Map(); + for (const entry of entries) { + const field = typeof entry.field === 'string' ? entry.field : typeof entry.field === 'number' ? String(entry.field) : ''; + const snippet = typeof entry.snippet === 'string' + ? entry.snippet + : Array.isArray(entry.snippets) && typeof entry.snippets[0] === 'string' + ? entry.snippets[0] + : ''; + if (field && snippet) highlights.set(field, snippet); + } + return highlights; +} + +function getSectionLabel(sectionId: DocsSectionId) { + return docsSections.find(section => section.id === sectionId)?.label ?? sectionId; +} + +function getDocTypeLabel(document: DocsSearchDocument) { + if (document.doc_type.startsWith('api-') || document.section === 'api' || document.section === 'reference') { + return 'Reference'; + } + if (document.section === 'tutorials') { + return 'Tutorial'; + } + return 'Guide'; +} + +function normalizeResultUrl(url: string) { + if (!url.startsWith('/docs')) return url; + return withoutBase(url, '/docs') || '/'; +} + +export function buildSearchItem( + displayHit: TypesenseSearchHit, + { + targetHit = displayHit, + matchedHeadings = [], + }: { + targetHit?: TypesenseSearchHit; + matchedHeadings?: string[]; + } = {}, +) { + const document = displayHit.document; + const targetDocument = targetHit.document; + const displayHighlights = getHighlightMap(displayHit); + const targetHighlights = getHighlightMap(targetHit); + const displayTitle = document.title; + const titleHtml = displayHighlights.get('title'); + const snippetHtml = targetHighlights.get('content') || displayHighlights.get('content'); + const breadcrumb = document.hierarchy.filter(h => h !== displayTitle).join(' › '); + const content = clipSnippet(normalizeSnippet(targetDocument.content), 400); + const description = document.description?.trim() || undefined; + + return { + id: document.id, + to: normalizeResultUrl(targetDocument.url), + title: displayTitle, + titleHtml, + breadcrumb, + snippetHtml, + content, + description, + matchedHeadings, + section: document.section, + sectionLabel: getSectionLabel(document.section), + framework: document.technologies?.[0], + docTypeLabel: getDocTypeLabel(document), + docType: document.doc_type, + } satisfies DocsSearchItem; +} + +function getDisplayHit(group: TypesenseGroupedHit) { + return group.hits.find(hit => hit.document.chunk_index === 0 && !hit.document.anchor) + ?? group.hits.find(hit => !hit.document.anchor) + ?? group.hits[0]!; +} + +export function flattenGroups(result: TypesenseSearchResult) { + if (result.grouped_hits?.length) { + return result.grouped_hits.map((group: TypesenseGroupedHit) => { + const primaryHit = group.hits[0]!; + const displayHit = getDisplayHit(group); + const matchedHeadings = [...new Set(group.hits + .map(hit => hit.document.heading?.trim()) + .filter((heading): heading is string => Boolean(heading)) + .filter(heading => heading !== displayHit.document.search_title && heading !== displayHit.document.title))]; + return buildSearchItem(displayHit, { targetHit: primaryHit, matchedHeadings }); + }); + } + return result.hits.map(hit => buildSearchItem(hit)); +} + +/** + * Soft section boosts for docs search. + * + * We intentionally keep this as optional re-ranking via `_eval(...)`, not + * filtering or pinning, so strong text matches can still win. + * + * Typesense refs: + * - Ranking / optional boosts: https://typesense.org/docs/guide/ranking-and-relevance.html + * - Personalization: https://typesense.org/docs/guide/personalization.html + * Section priority used for both Typesense ranking boosts and chip-bar + * ordering in the palette. Sections not listed here render after the listed + * ones in their docsSections order. + * + * Weights are relative only. Keep guides, api, and frameworks near the top, + * while still letting `_text_match(buckets: 10)` win on strong matches. + */ +export const sectionPriority: Array<{ id: DocsSectionId; weight: number }> = [ + { id: 'guides', weight: 6 }, + { id: 'api', weight: 6 }, + { id: 'frameworks', weight: 5 }, + { id: 'reference', weight: 3 }, + { id: 'getting-started', weight: 2 }, +]; + +function buildSectionBoostClauses() { + return sectionPriority.map(({ id, weight }) => `(section:=${id}):${weight}`); +} + +export function hasDynamicPersonalization(prefs: UserSearchPrefs) { + return Boolean(prefs.framework || prefs.deployment === 'cloud'); +} + +/** + * Build the Typesense `sort_by` expression for docs search. + * + * Why this shape: + * - `_text_match(buckets: 10):desc` keeps text relevance first, while still + * allowing later clauses to re-rank near-ties within buckets. + * - framework-specific clauses come before generic section clauses so a + * preferred framework can beat broad `frameworks` boosting. + * - `_eval([...])` is used for soft boosts only. We don't hide results. + * + * Typesense refs: + * - Search params: https://typesense.org/docs/30.2/api/search.html + * - Relevance / buckets: https://typesense.org/docs/guide/ranking-and-relevance.html + * - Personalization: https://typesense.org/docs/guide/personalization.html + */ +export function buildPersonalizedSortBy(prefs: UserSearchPrefs) { + const clauses: string[] = []; + + if (prefs.framework) { + clauses.push(`(section:=frameworks && technologies:=${prefs.framework}):10`); + clauses.push(`(technologies:=${prefs.framework}):3`); + } + if (prefs.deployment === 'cloud') { + clauses.push('(section:=guides):1'); + } + + clauses.push(...buildSectionBoostClauses()); + + return `_text_match(buckets: 10):desc,_eval([${clauses.join(', ')}]):desc,rank_order:asc`; +} diff --git a/app/utils/transformAlgoliaSearchItems.ts b/app/utils/transformAlgoliaSearchItems.ts deleted file mode 100644 index 5a86103d5..000000000 --- a/app/utils/transformAlgoliaSearchItems.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { DocSearchHit } from "@docsearch/react"; -import { withoutTrailingSlash } from "ufo"; - -function getRelativePath(absoluteUrl: string) { - const { pathname, hash } = new URL(absoluteUrl); - const url = window.location.origin; - const relativeUrl = pathname.replace(url, '/') + hash; - return withoutTrailingSlash(relativeUrl); -} - -/** - * Transform Algolia search items to ensure off-site links aren't rendered as relative links - */ -export default function (items: DocSearchHit[]): DocSearchHit[] { - return items.map((item) => { - const relativePath = getRelativePath(item.url); - - let url = relativePath; - - if (!relativePath.startsWith('/docs')) { - url = item.url; - } - - return { - ...item, - url, - }; - }); -} diff --git a/lib/typesenseAlias.ts b/lib/typesenseAlias.ts new file mode 100644 index 000000000..f75882167 --- /dev/null +++ b/lib/typesenseAlias.ts @@ -0,0 +1,43 @@ +import { execSync } from 'node:child_process'; +import { createHash } from 'node:crypto'; +import process from 'node:process'; + +export function slugifyBranch(branch: string) { + const slug = branch + .toLowerCase() + .replace(/[^a-z0-9]+/g, '-') + .replace(/^-+|-+$/g, '') + || 'unknown'; + + const MAX = 60; + if (slug.length <= MAX) return slug; + + const hash = createHash('sha1').update(branch).digest('hex').slice(0, 6); + return `${slug.slice(0, MAX - 7)}-${hash}`; +} + +export function getLocalGitBranch(): string | null { + try { + const branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: ['ignore', 'pipe', 'ignore'] }) + .toString() + .trim(); + if (!branch || branch === 'HEAD') return null; + return branch; + } + catch { + return null; + } +} + +export function getTypesenseBranchName() { + return process.env.GITHUB_HEAD_REF + || process.env.GITHUB_REF_NAME + || process.env.VERCEL_GIT_COMMIT_REF + || getLocalGitBranch(); +} + +export function resolveBranchTypesenseAlias(branch = getTypesenseBranchName()) { + if (!branch) return null; + if (branch === 'main') return 'directus-docs'; + return `directus-docs-preview-${slugifyBranch(branch)}`; +} diff --git a/nuxt.config.ts b/nuxt.config.ts index 415f8321a..1c3f9c80f 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -1,5 +1,6 @@ import { existsSync, readFileSync } from 'node:fs'; import type { NitroConfig } from 'nitropack'; +import { resolveBranchTypesenseAlias } from './lib/typesenseAlias'; const directusLight = JSON.parse(readFileSync('./app/assets/shiki/directus-light.json', 'utf8')); const directusDark = JSON.parse(readFileSync('./app/assets/shiki/directus-dark.json', 'utf8')); @@ -25,6 +26,8 @@ function loadRedirectRouteRules(): NitroConfig['routeRules'] { return rules; } +const typesenseCollection = process.env.TYPESENSE_COLLECTION || resolveBranchTypesenseAlias() || undefined; + // https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ modules: [ @@ -35,9 +38,6 @@ export default defineNuxtConfig({ '@nuxt/scripts', '@nuxtjs/seo', '@vueuse/nuxt', - ...(process.env.ALGOLIA_APPLICATION_ID && process.env.ALGOLIA_API_KEY - ? ['@nuxtjs/algolia'] - : []), ], devtools: { @@ -48,7 +48,7 @@ export default defineNuxtConfig({ baseURL: BASE_URL, }, - css: ['~/assets/css/main.css', '~/assets/css/algolia.css'], + css: ['~/assets/css/main.css'], site: { name: 'Directus Docs', @@ -126,6 +126,9 @@ export default defineNuxtConfig({ id: process.env.GOOGLE_TAG_MANAGER_ID!, }, }, + typesenseUrl: process.env.TYPESENSE_URL, + typesensePublicApiKey: process.env.TYPESENSE_PUBLIC_API_KEY, + typesenseCollection, }, directusUrl: process.env.DIRECTUS_URL, }, @@ -164,11 +167,6 @@ export default defineNuxtConfig({ }, }, - algolia: { - docSearch: { indexName: 'directus_unified', - }, - }, - eslint: { config: { stylistic: { diff --git a/package.json b/package.json index ad0a06213..9de8682d9 100644 --- a/package.json +++ b/package.json @@ -12,41 +12,55 @@ "stable-ids:check": "node scripts/check-stable-ids.ts", "redirects:sync": "node scripts/redirects-sync.ts --write-deterministic --fail-on-unresolved", "redirects:check": "node scripts/redirects-sync.ts --fail-on-unresolved --no-write", - "typecheck:scripts": "tsc -p scripts/tsconfig.json" + "typecheck:scripts": "tsc -p scripts/tsconfig.json", + "index:docs": "tsx scripts/index-docs.ts", + "test:search": "vitest run tests/scripts/index-docs-chunker.test.ts tests/components/DocsSearchPalette.test.ts tests/shared/parseTypesenseUrl.test.ts tests/lib/typesenseAlias.test.ts tests/services/typesenseService.test.ts tests/utils/highlightHtml.test.ts" }, "dependencies": { "@directus/openapi": "0.3.0", "@directus/sdk": "^21.2.2", - "@docsearch/css": "4.6.2", - "@docsearch/js": "4.6.2", + "@iconify-json/heroicons-outline": "1.2.1", "@iconify-json/material-symbols": "1.2.68", "@iconify-json/simple-icons": "1.2.79", "@nuxt/content": "3.13.0", "@nuxt/fonts": "0.14.0", "@nuxt/ui": "^4.6.1", - "@nuxtjs/algolia": "1.11.2", "@nuxtjs/color-mode": "4.0.0", "@nuxtjs/seo": "5.1.3", "@takumi-rs/core": "^1.1.0", "@vueuse/core": "14.2.1", "@vueuse/nuxt": "14.2.1", + "dotenv": "^17.4.2", + "gray-matter": "^4.0.3", + "js-yaml": "^4.1.1", "lodash-es": "4.18.1", "nuxt": "4.4.2", "nuxt-llms": "0.2.0", "openapi3-ts": "4.5.0", "posthog-js": "1.371.2", "posthog-node": "5.29.7", + "remark": "^15.0.1", + "remark-mdc": "^3.11.0", + "remark-parse": "^11.0.0", "sharp": "^0.34.5", "tailwindcss": "^4.2.4", + "typesense": "^3.0.6", "ufo": "1.6.3", "unhead": "^3.1.0" }, "devDependencies": { + "@iconify-json/ph": "^1.2.2", "@nuxt/eslint": "1.15.2", "@nuxt/scripts": "1.0.2", + "@nuxt/test-utils": "^4.0.3", + "@types/js-yaml": "^4.0.9", "@types/lodash-es": "4.17.12", "@types/node": "^22", + "@vue/test-utils": "^2.4.10", + "happy-dom": "^20.9.0", + "tsx": "^4.22.3", "typescript": "6.0.3", + "vitest": "^4.1.7", "vue-tsc": "^3.2.7" }, "pnpm": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 006a5ef9b..3cf755bb2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,12 +17,9 @@ importers: '@directus/sdk': specifier: ^21.2.2 version: 21.2.2 - '@docsearch/css': - specifier: 4.6.2 - version: 4.6.2 - '@docsearch/js': - specifier: 4.6.2 - version: 4.6.2 + '@iconify-json/heroicons-outline': + specifier: 1.2.1 + version: 1.2.1 '@iconify-json/material-symbols': specifier: 1.2.68 version: 1.2.68 @@ -34,19 +31,16 @@ importers: version: 3.13.0(better-sqlite3@11.10.0)(magicast@0.5.2)(valibot@1.3.1(typescript@6.0.3)) '@nuxt/fonts': specifier: 0.14.0 - version: 0.14.0(@netlify/blobs@9.1.2)(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + version: 0.14.0(@netlify/blobs@9.1.2)(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) '@nuxt/ui': specifier: ^4.6.1 - version: 4.6.1(@netlify/blobs@9.1.2)(@nuxt/content@3.13.0(better-sqlite3@11.10.0)(magicast@0.5.2)(valibot@1.3.1(typescript@6.0.3)))(@tiptap/extensions@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@tiptap/y-tiptap@3.0.3(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))(axios@1.13.5)(change-case@5.4.4)(db0@0.3.4(better-sqlite3@11.10.0))(embla-carousel@8.6.0)(ioredis@5.10.1)(jwt-decode@4.0.0)(magicast@0.5.2)(tailwindcss@4.2.4)(typescript@6.0.3)(valibot@1.3.1(typescript@6.0.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-router@5.0.6(@vue/compiler-sfc@3.5.33)(vue@3.5.33(typescript@6.0.3)))(vue@3.5.33(typescript@6.0.3))(yjs@13.6.30)(zod@4.3.6) - '@nuxtjs/algolia': - specifier: 1.11.2 - version: 1.11.2(@vue/server-renderer@3.5.33(vue@3.5.33(typescript@6.0.3)))(magicast@0.5.2)(vue@3.5.33(typescript@6.0.3)) + version: 4.6.1(@netlify/blobs@9.1.2)(@nuxt/content@3.13.0(better-sqlite3@11.10.0)(magicast@0.5.2)(valibot@1.3.1(typescript@6.0.3)))(@tiptap/extensions@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@tiptap/y-tiptap@3.0.3(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))(axios@1.16.1)(change-case@5.4.4)(db0@0.3.4(better-sqlite3@11.10.0))(embla-carousel@8.6.0)(ioredis@5.10.1)(jwt-decode@4.0.0)(magicast@0.5.2)(tailwindcss@4.2.4)(typescript@6.0.3)(valibot@1.3.1(typescript@6.0.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-router@5.0.6(@vue/compiler-sfc@3.5.33)(vue@3.5.33(typescript@6.0.3)))(vue@3.5.33(typescript@6.0.3))(yjs@13.6.30)(zod@3.25.76) '@nuxtjs/color-mode': specifier: 4.0.0 version: 4.0.0(magicast@0.5.2) '@nuxtjs/seo': specifier: 5.1.3 - version: 5.1.3(f958a059aa9f5a6866becf12bff13989) + version: 5.1.3(1759d3db8cf72984d24b6002807c57ae) '@takumi-rs/core': specifier: ^1.1.0 version: 1.1.0 @@ -55,13 +49,22 @@ importers: version: 14.2.1(vue@3.5.33(typescript@6.0.3)) '@vueuse/nuxt': specifier: 14.2.1 - version: 14.2.1(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3)) + version: 14.2.1(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3)) + dotenv: + specifier: ^17.4.2 + version: 17.4.2 + gray-matter: + specifier: ^4.0.3 + version: 4.0.3 + js-yaml: + specifier: ^4.1.1 + version: 4.1.1 lodash-es: specifier: 4.18.1 version: 4.18.1 nuxt: specifier: 4.4.2 - version: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3) + version: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0) nuxt-llms: specifier: 0.2.0 version: 0.2.0(magicast@0.5.2) @@ -74,99 +77,73 @@ importers: posthog-node: specifier: 5.29.7 version: 5.29.7 + remark: + specifier: ^15.0.1 + version: 15.0.1 + remark-mdc: + specifier: ^3.11.0 + version: 3.11.0 + remark-parse: + specifier: ^11.0.0 + version: 11.0.0 sharp: specifier: ^0.34.5 version: 0.34.5 tailwindcss: specifier: ^4.2.4 version: 4.2.4 + typesense: + specifier: ^3.0.6 + version: 3.0.6(@babel/runtime@7.29.2) ufo: specifier: 1.6.3 version: 1.6.3 unhead: specifier: ^3.1.0 - version: 3.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + version: 3.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) devDependencies: + '@iconify-json/ph': + specifier: ^1.2.2 + version: 1.2.2 '@nuxt/eslint': specifier: 1.15.2 - version: 1.15.2(@typescript-eslint/utils@8.59.0(eslint@9.28.0(jiti@2.6.1))(typescript@6.0.3))(@vue/compiler-sfc@3.5.33)(eslint@9.28.0(jiti@2.6.1))(magicast@0.5.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + version: 1.15.2(@typescript-eslint/utils@8.59.0(eslint@9.28.0(jiti@2.6.1))(typescript@6.0.3))(@vue/compiler-sfc@3.5.33)(eslint@9.28.0(jiti@2.6.1))(magicast@0.5.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) '@nuxt/scripts': specifier: 1.0.2 - version: 1.0.2(@netlify/blobs@9.1.2)(@types/google.maps@3.58.1)(@unhead/vue@2.1.13(vue@3.5.33(typescript@6.0.3)))(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(magicast@0.5.2)(posthog-js@1.371.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3)) + version: 1.0.2(@netlify/blobs@9.1.2)(@types/google.maps@3.58.1)(@unhead/vue@2.1.13(vue@3.5.33(typescript@6.0.3)))(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(magicast@0.5.2)(posthog-js@1.371.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3)) + '@nuxt/test-utils': + specifier: ^4.0.3 + version: 4.0.3(@vue/test-utils@2.4.10(@vue/compiler-dom@3.5.33)(@vue/server-renderer@3.5.33(vue@3.5.33(typescript@6.0.3)))(vue@3.5.33(typescript@6.0.3)))(crossws@0.4.5(srvx@0.11.15))(happy-dom@20.9.0)(magicast@0.5.2)(playwright-core@1.58.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vitest@4.1.7(@opentelemetry/api@1.9.1)(@types/node@22.19.17)(happy-dom@20.9.0)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))) + '@types/js-yaml': + specifier: ^4.0.9 + version: 4.0.9 '@types/lodash-es': specifier: 4.17.12 version: 4.17.12 '@types/node': specifier: ^22 version: 22.19.17 + '@vue/test-utils': + specifier: ^2.4.10 + version: 2.4.10(@vue/compiler-dom@3.5.33)(@vue/server-renderer@3.5.33(vue@3.5.33(typescript@6.0.3)))(vue@3.5.33(typescript@6.0.3)) + happy-dom: + specifier: ^20.9.0 + version: 20.9.0 + tsx: + specifier: ^4.22.3 + version: 4.22.3 typescript: specifier: 6.0.3 version: 6.0.3 + vitest: + specifier: ^4.1.7 + version: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@22.19.17)(happy-dom@20.9.0)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) vue-tsc: specifier: ^3.2.7 version: 3.2.7(typescript@6.0.3) packages: - '@algolia/cache-browser-local-storage@4.25.3': - resolution: {integrity: sha512-J0vrnbIYmDIf9d9qQwBXaHn10VoQ/rA+2iBMr/idfsjHhL9I4h2pC9Dj1i0ggDLv9sPajbeVVh0BdC+mDbo7Tw==} - - '@algolia/cache-common@4.25.3': - resolution: {integrity: sha512-dDls2jhGFdkGnoKwXADBnjosHKdKiwlY+tzaua5J0q9XJptn6DCBDUt3pg46GhTRz+64x08M+dyp8nNoV+3/Jw==} - - '@algolia/cache-in-memory@4.25.3': - resolution: {integrity: sha512-6u/fVDr3ZIJIgtqdgUDB5kL9KcOdowmxf052bjfI1XhFTpxmIa49HcAEh1y2R0YqmmNDQHaPCT0QzwkINhWbug==} - - '@algolia/client-account@4.25.3': - resolution: {integrity: sha512-TkSVT5+davX4Dzt3gyEJ+SAfaVT5bHrZctAiup/AGPV7sNBigv4kuZv40OEbMMgu1uPJ4zw3tA39Oj/mOjd6gg==} - - '@algolia/client-analytics@4.25.3': - resolution: {integrity: sha512-vHSU4zBaENbRjzwFYB3OQuDlKXwe+YDRgyGh1kKZhcMRDSsEBH/PGNWn+2ZmtbgrNS52TC+TJ8oUOg5wXIeISw==} - - '@algolia/client-common@4.25.3': - resolution: {integrity: sha512-ExRdFnJDe7t1/DgJUsqjzZKeI9gkLft4oVttlyTMru8TRNWA6eZ0wHRj4uQ9N3sxmzPiw3C53wigor705n1yQw==} - - '@algolia/client-common@5.48.0': - resolution: {integrity: sha512-7H3DgRyi7UByScc0wz7EMrhgNl7fKPDjKX9OcWixLwCj7yrRXDSIzwunykuYUUO7V7HD4s319e15FlJ9CQIIFQ==} - engines: {node: '>= 14.0.0'} - - '@algolia/client-personalization@4.25.3': - resolution: {integrity: sha512-ycCkQ0nWoH+sf0Gh20kk4NfJ+iUBc59ailqNCFcVl/0th1dtHF0P61IGetTsSmxVPZedDvnHop2z1ujWpYzNmw==} - - '@algolia/client-search@4.25.3': - resolution: {integrity: sha512-GFA99zL6cfNSDEDHfEJ0TmVYmXCJofQpForFhCShQLfRQgBYud9UBHOh4LB6ZSzmtVDIfP33joCA9hxQWPIbFw==} - - '@algolia/events@4.0.1': - resolution: {integrity: sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==} - - '@algolia/logger-common@4.25.3': - resolution: {integrity: sha512-RrlmuHNTc9CIgykWh37QduDAkpX4745KQ75I+vhgT5ER3BBykaYByDTyWkyFSSlZjpDHXtOymu9epNbI5V6OWQ==} - - '@algolia/logger-console@4.25.3': - resolution: {integrity: sha512-s8AtfF9W+6Pbxfwkmzywd8ThVJ04D4JZlNyBdCuWpC5b3jzx1JAXT9ZL8K2faUsO4rEdHpy9LXMURvF7cQAE0w==} - - '@algolia/recommend@4.25.3': - resolution: {integrity: sha512-/vpXzDFLmrkcM1UOvZae8i/z8wRs2uaKKlPaHqN24ySADWKyf2zxVsDmtcaGMYzBYqYsKR1XKFvwGA5HQxaZxQ==} - - '@algolia/requester-browser-xhr@4.25.3': - resolution: {integrity: sha512-5ZXO55IDqXUehQKilVYU6OdUBT2XGI+JIki2UsxUkMykH4ksA9EU8YZJth1ZwEYTDC50bVSH32VCYsOFB0MUTA==} - - '@algolia/requester-common@4.25.3': - resolution: {integrity: sha512-n5dJA5jlIle5IQavlDWBXC46lw/VuwFbbknWJcPiJ6nJ6lRllpLOhV2ZJeUdCvRyg/6zG18h+9+Q/m2d/vLEIw==} - - '@algolia/requester-fetch@4.25.3': - resolution: {integrity: sha512-VCi5D+Ds8MRH9nUgTdGes7nEZJN7UIgg6f2xt8k7JbtUkoJpXcDL4Gd3la8t7hDkd9wiBBqVU4tbQ8GpH9oCsw==} - - '@algolia/requester-node-http@4.25.3': - resolution: {integrity: sha512-7BXWAyVMK1Z3gT+2RPv0I48HfaIlho3nCQaB/tjziw+DdPigHRDq+xjtdzL8y+5O1g7LEdlPI9QHAgDbW/BLXw==} - - '@algolia/requester-node-http@5.48.0': - resolution: {integrity: sha512-ZgxV2+5qt3NLeUYBTsi6PLyHcENQWC0iFppFZekHSEDA2wcLdTUjnaJzimTEULHIvJuLRCkUs4JABdhuJktEag==} - engines: {node: '>= 14.0.0'} - - '@algolia/transporter@4.25.3': - resolution: {integrity: sha512-2yji+TKjC1uOxhJ9pCdw7lQm6GSiQ+fMvNH4es6oz82DrBpkVHkeU49HmpyTqz8Ai9e+nW/UBz8T9+UyBul3dA==} - '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -285,8 +262,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.28.6': - resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} '@babel/template@7.28.6': @@ -341,12 +318,6 @@ packages: resolution: {integrity: sha512-T8UhDG+GY534AqvLpRmycLYZmIYIaUYzu25X3WeUjWuxCvqAiKqXbYUrTRb0A5Mw93vUeVuyqabzvLbBY9AXxQ==} engines: {node: '>=22'} - '@docsearch/css@4.6.2': - resolution: {integrity: sha512-fH/cn8BjEEdM2nJdjNMHIvOVYupG6AIDtFVDgIZrNzdCSj4KXr9kd+hsehqsNGYjpUjObeKYKvgy/IwCb1jZYQ==} - - '@docsearch/js@4.6.2': - resolution: {integrity: sha512-qj1yoxl3y4GKoK7+VM6fq/rQqPnvUmg3IKzJ9x0VzN14QVzdB/SG/J6VfV1BWT5RcPUFxIcVwoY1fwHM2fSRRw==} - '@dxup/nuxt@0.4.1': resolution: {integrity: sha512-gtYffW6OfWNvoLW+XD3Mx/K8uUq08PMGLYJoDxc92EzZAWqR0FhcR5iaLm5r/OxyGTKz+P5f5Y7Aoir9+SjYaw==} peerDependencies: @@ -387,156 +358,312 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.28.0': + resolution: {integrity: sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.27.7': resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.28.0': + resolution: {integrity: sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.27.7': resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.28.0': + resolution: {integrity: sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.27.7': resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.28.0': + resolution: {integrity: sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.27.7': resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.28.0': + resolution: {integrity: sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.27.7': resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.28.0': + resolution: {integrity: sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.27.7': resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.28.0': + resolution: {integrity: sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.27.7': resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.28.0': + resolution: {integrity: sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.27.7': resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.28.0': + resolution: {integrity: sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.27.7': resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.28.0': + resolution: {integrity: sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.27.7': resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.28.0': + resolution: {integrity: sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.27.7': resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.28.0': + resolution: {integrity: sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.27.7': resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.28.0': + resolution: {integrity: sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.27.7': resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.28.0': + resolution: {integrity: sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.27.7': resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.28.0': + resolution: {integrity: sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.27.7': resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.28.0': + resolution: {integrity: sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.27.7': resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.28.0': + resolution: {integrity: sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.27.7': resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.28.0': + resolution: {integrity: sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.27.7': resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.28.0': + resolution: {integrity: sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.27.7': resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.28.0': + resolution: {integrity: sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.27.7': resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.28.0': + resolution: {integrity: sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.27.7': resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.28.0': + resolution: {integrity: sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.27.7': resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.28.0': + resolution: {integrity: sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.27.7': resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.28.0': + resolution: {integrity: sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.27.7': resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.28.0': + resolution: {integrity: sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.27.7': resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} engines: {node: '>=18'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.28.0': + resolution: {integrity: sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.9.1': resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -644,9 +771,15 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@iconify-json/heroicons-outline@1.2.1': + resolution: {integrity: sha512-QNYV4/KsW8Ww9a3B+hxDntS5BwLLbErKpL1V3MkvB8X+ZVTX5VLxjlj8rAEih+GCDWzaiZJOrdO/pagvsuBkXg==} + '@iconify-json/material-symbols@1.2.68': resolution: {integrity: sha512-MGo7A6j+evFoks/kIZAdAKMSKl24ARa19bUvXMw/RVFKuMo2tIc27HZitTuXna858pvhjzMaFq8UrXaKqbQGjA==} + '@iconify-json/ph@1.2.2': + resolution: {integrity: sha512-PgkEZNtqa8hBGjHXQa4pMwZa93hmfu8FUSjs/nv4oUU6yLsgv+gh9nu28Kqi8Fz9CCVu4hj1MZs9/60J57IzFw==} + '@iconify-json/simple-icons@1.2.79': resolution: {integrity: sha512-aNyO7Fd1qej9oQfIyohYFRv0lhQLaZ+6UkK1c1qwax0MDPUOZOdq65MlU500kow97pD/W+b2u1And3e25eE24Q==} @@ -941,6 +1074,11 @@ packages: '@nuxt/devalue@2.0.2': resolution: {integrity: sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==} + '@nuxt/devtools-kit@2.7.0': + resolution: {integrity: sha512-MIJdah6CF6YOW2GhfKnb8Sivu6HpcQheqdjOlZqShBr+1DyjtKQbAKSCAyKPaoIzZP4QOo2SmTFV6aN8jBeEIQ==} + peerDependencies: + vite: '>=6.0' + '@nuxt/devtools-kit@3.2.4': resolution: {integrity: sha512-Yxy2Xgmq5hf3dQy983V0xh0OJV2mYwRZz9eVIGc3EaribdFGPDNGMMbYqX9qCty3Pbxn/bCF3J0UyPaNlHVayQ==} peerDependencies: @@ -997,10 +1135,6 @@ packages: '@nuxt/icon@2.2.1': resolution: {integrity: sha512-GI840yYGuvHI0BGDQ63d6rAxGzG96jQcWrnaWIQKlyQo/7sx9PjXkSHckXUXyX1MCr9zY6U25Td6OatfY6Hklw==} - '@nuxt/kit@3.21.1': - resolution: {integrity: sha512-QORZRjcuTKgo++XP1Pc2c2gqwRydkaExrIRfRI9vFsPA3AzuHVn5Gfmbv1ic8y34e78mr5DMBvJlelUaeOuajg==} - engines: {node: '>=18.12.0'} - '@nuxt/kit@3.21.2': resolution: {integrity: sha512-Bd6m6mrDrqpBEbX+g0rc66/ALd1sxlgdx5nfK9MAYO0yKLTOSK7McSYz1KcOYn3LQFCXOWfvXwaqih/b+REI1g==} engines: {node: '>=18.12.0'} @@ -1065,6 +1199,42 @@ packages: peerDependencies: '@nuxt/kit': '>=3.0.0' + '@nuxt/test-utils@4.0.3': + resolution: {integrity: sha512-HwF3B+GIwzWeIioskhHIjq+TQttP7+g0GUO39hpivGWFZzYXD3lIspzfmliJkgwwA3m5Xl2Z8XXqX1zAolKX6w==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@cucumber/cucumber': '>=11.0.0' + '@jest/globals': '>=30.0.0' + '@playwright/test': ^1.43.1 + '@testing-library/vue': ^8.0.1 + '@vitest/ui': '*' + '@vue/test-utils': ^2.4.2 + happy-dom: '>=20.0.11' + jsdom: '>=27.4.0' + playwright-core: ^1.43.1 + vitest: ^4.0.2 + peerDependenciesMeta: + '@cucumber/cucumber': + optional: true + '@jest/globals': + optional: true + '@playwright/test': + optional: true + '@testing-library/vue': + optional: true + '@vitest/ui': + optional: true + '@vue/test-utils': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright-core: + optional: true + vitest: + optional: true + '@nuxt/ui@4.6.1': resolution: {integrity: sha512-mBbBTaVDTR6ohOoAJUiV4T2RPXo2hyLewGPTiHjy1arzHPNFnmb/Tkl/2/JipF3Y8cahV4LhVUdkWKsdgI1OXw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1118,9 +1288,6 @@ packages: rollup-plugin-visualizer: optional: true - '@nuxtjs/algolia@1.11.2': - resolution: {integrity: sha512-x22Sx6EQebvUmrEY5vDqSaTjNzmAaIA36TKR2Sn9WYM0lS7+tcVL2l3AKg0fUNTLHZz6kesoLMGsppX6cq5Lrw==} - '@nuxtjs/color-mode@3.5.2': resolution: {integrity: sha512-cC6RfgZh3guHBMLLjrBB2Uti5eUoGM9KyauOaYS9ETmxNWBMTvpgjvSiSJp1OFljIXPIqVTJ3xtJpSNZiO3ZaA==} @@ -1152,6 +1319,9 @@ packages: zod: optional: true + '@one-ini/wasm@0.1.1': + resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} + '@opentelemetry/api-logs@0.208.0': resolution: {integrity: sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg==} engines: {node: '>=8.0.0'} @@ -2487,10 +2657,6 @@ packages: '@swc/helpers@0.5.21': resolution: {integrity: sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==} - '@szmarczak/http-timer@4.0.6': - resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} - engines: {node: '>=10'} - '@tailwindcss/node@4.2.4': resolution: {integrity: sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==} @@ -2893,14 +3059,14 @@ packages: '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} - '@types/cacheable-request@6.0.3': - resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} '@types/debug@4.1.13': resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} - '@types/dom-speech-recognition@0.0.1': - resolution: {integrity: sha512-udCxb8DvjcDKfk1WTBzDsxFbLgYxmQGKrE/ricoMqHRNjSlSUCcamVTA5lIQqzY10mY5qCY0QDwBfFEwhfoDPw==} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} '@types/esrecurse@4.3.1': resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} @@ -2914,18 +3080,12 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - '@types/hogan.js@3.0.5': - resolution: {integrity: sha512-/uRaY3HGPWyLqOyhgvW9Aa43BNnLZrNeQxl2p8wqId4UHMfPKolSB+U7BlZyO1ng7MkLnyEAItsBzCG0SDhqrA==} - - '@types/http-cache-semantics@4.2.0': - resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/keyv@3.1.4': - resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} - '@types/lodash-es@4.17.12': resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} @@ -2945,15 +3105,9 @@ packages: resolution: {integrity: sha512-EULJ8LApcVEPbrfND0cRQqutIOdiIgJ1Mgrhpy755r14xMohPTEpkV/k28SJvuOs9bHRFW8x+KeDAEPiGQPB9Q==} deprecated: This is a stub types definition. parse-path provides its own type definitions, so you do not need this installed. - '@types/qs@6.14.0': - resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} - '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - '@types/responselike@1.0.3': - resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} - '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -2969,6 +3123,12 @@ packages: '@types/web-bluetooth@0.0.21': resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} + '@types/whatwg-mimetype@3.0.2': + resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@typescript-eslint/eslint-plugin@8.59.0': resolution: {integrity: sha512-HyAZtpdkgZwpq8Sz3FSUvCR4c+ScbuWa9AksK2Jweub7w4M3yTz4O11AqVJzLYjy/B9ZWPyc81I+mOdJU/bDQw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3198,6 +3358,35 @@ packages: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 vue: ^3.2.25 + '@vitest/expect@4.1.7': + resolution: {integrity: sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w==} + + '@vitest/mocker@4.1.7': + resolution: {integrity: sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.1.7': + resolution: {integrity: sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==} + + '@vitest/runner@4.1.7': + resolution: {integrity: sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw==} + + '@vitest/snapshot@4.1.7': + resolution: {integrity: sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw==} + + '@vitest/spy@4.1.7': + resolution: {integrity: sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q==} + + '@vitest/utils@4.1.7': + resolution: {integrity: sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==} + '@volar/language-core@2.4.28': resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} @@ -3278,6 +3467,16 @@ packages: '@vue/shared@3.5.33': resolution: {integrity: sha512-5vR2QIlmaLG77Ygd4pMP6+SGQ5yox9VhtnbDWTy9DzMzdmeLxZ1QqxrywEZ9sa1AVubfIJyaCG3ytyWU81ufcQ==} + '@vue/test-utils@2.4.10': + resolution: {integrity: sha512-SmoZ5EA1kYiAFs9NkYdiFFQF+cSnUwnvlYEbY+DogWQZUiqOm/Y29eSbc5T6yi75SgSF9863SBeXniIEoPajCA==} + peerDependencies: + '@vue/compiler-dom': 3.x + '@vue/server-renderer': 3.x + vue: 3.x + peerDependenciesMeta: + '@vue/server-renderer': + optional: true + '@vueuse/core@10.11.1': resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==} @@ -3371,8 +3570,9 @@ packages: resolution: {integrity: sha512-ueFCcIPaMgtuYDS9u0qlUoEvj6GiSsKrwnOLPp9SshqjtcRaR1IEHRjoReq3sXNydsF5i0ZnmuYgXq9dV53t0g==} engines: {node: '>=18.0.0'} - abbrev@1.1.1: - resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} abbrev@3.0.1: resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} @@ -3402,6 +3602,10 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} @@ -3409,14 +3613,6 @@ packages: ajv@6.14.0: resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} - algoliasearch-helper@3.27.0: - resolution: {integrity: sha512-eNYchRerbsvk2doHOMfdS1/B6Tm70oGtu8mzQlrNzbCeQ8p1MjCW8t/BL6iZ5PD+cL5NNMgTMyMnmiXZ1sgmNw==} - peerDependencies: - algoliasearch: '>= 3.1 < 6' - - algoliasearch@4.25.3: - resolution: {integrity: sha512-kgeIixgDiB+FbH1cHDFUtTNkxdJadHryF8lSPIHHQkEeUrzZA1Hi3PLL+EgNubO0dch4ALNb5G4rw+FDCv3Vbw==} - alien-signals@3.1.2: resolution: {integrity: sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw==} @@ -3456,6 +3652,9 @@ packages: resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} engines: {node: '>=14'} + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -3463,6 +3662,10 @@ packages: resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} engines: {node: '>=10'} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + ast-kit@2.2.0: resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} engines: {node: '>=20.19.0'} @@ -3494,8 +3697,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axios@1.13.5: - resolution: {integrity: sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==} + axios@1.16.1: + resolution: {integrity: sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A==} b4a@1.8.0: resolution: {integrity: sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==} @@ -3652,14 +3855,6 @@ packages: resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} engines: {node: '>=20.19.0'} - cacheable-lookup@5.0.4: - resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} - engines: {node: '>=10.6.0'} - - cacheable-request@7.0.4: - resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} - engines: {node: '>=8'} - call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -3688,6 +3883,10 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -3755,9 +3954,6 @@ packages: resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} engines: {node: '>=20'} - clone-response@1.0.3: - resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} - cluster-key-slot@1.1.2: resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} engines: {node: '>=0.10.0'} @@ -3779,6 +3975,10 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + commander@11.1.0: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} @@ -3809,6 +4009,9 @@ packages: confbox@0.2.4: resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + consola@3.4.2: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} @@ -3991,10 +4194,6 @@ packages: resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} engines: {node: '>=18'} - defer-to-connect@2.0.1: - resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} - engines: {node: '>=10'} - define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} @@ -4058,9 +4257,6 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - domino@2.1.6: - resolution: {integrity: sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ==} - dompurify@3.4.1: resolution: {integrity: sha512-JahakDAIg1gyOm7dlgWSDjV4n7Ip2PKR55NIT6jrMfIgLFgWo81vdr1/QGqWtFNRqXP9UV71oVePtjqS2ebnPw==} @@ -4075,10 +4271,6 @@ packages: resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} engines: {node: '>=18'} - dotenv@17.2.4: - resolution: {integrity: sha512-mudtfb4zRB4bVvdj0xRo+e6duH1csJRM8IukBqfTRvHotn9+LBXB8ynAidP9zHqoRC/fsllXgk4kCKlR21fIhw==} - engines: {node: '>=12'} - dotenv@17.4.2: resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} engines: {node: '>=12'} @@ -4093,6 +4285,11 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + editorconfig@1.0.7: + resolution: {integrity: sha512-e0GOtq/aTQhVdNyDU9e02+wz9oDDM+SIOQxWME2QRjzRX5yyLAuHDE+0aE8vHb9XRC8XD37eO2u57+F09JqFhw==} + engines: {node: '>=14'} + hasBin: true + ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -4226,6 +4423,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.28.0: + resolution: {integrity: sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -4367,6 +4569,11 @@ packages: resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + esquery@1.7.0: resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} @@ -4412,12 +4619,24 @@ packages: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + exsolve@1.0.8: resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + fake-indexeddb@6.2.5: + resolution: {integrity: sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w==} + engines: {node: '>=18'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -4512,8 +4731,8 @@ packages: flatted@3.4.2: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -4616,10 +4835,6 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} - get-stream@5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} - get-stream@8.0.1: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} @@ -4688,13 +4903,13 @@ packages: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} - got@11.8.6: - resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} - engines: {node: '>=10.19.0'} - graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + gzip-size@7.0.0: resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -4702,6 +4917,20 @@ packages: h3@1.15.11: resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} + h3@2.0.1-rc.20: + resolution: {integrity: sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg==} + engines: {node: '>=20.11.1'} + hasBin: true + peerDependencies: + crossws: ^0.4.1 + peerDependenciesMeta: + crossws: + optional: true + + happy-dom@20.9.0: + resolution: {integrity: sha512-GZZ9mKe8r646NUAf/zemnGbjYh4Bt8/MqASJY+pSm5ZDtc3YQox+4gsLI7yi1hba6o+eCsGxpHn5+iEVn31/FQ==} + engines: {node: '>=20.0.0'} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -4782,19 +5011,12 @@ packages: hey-listen@1.0.8: resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} - hogan.js@3.0.2: - resolution: {integrity: sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==} - hasBin: true - hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} hookable@6.1.1: resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} - htm@3.1.1: - resolution: {integrity: sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==} - html-entities@2.6.0: resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} @@ -4804,9 +5026,6 @@ packages: html-whitespace-sensitive-tag-names@3.0.1: resolution: {integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==} - http-cache-semantics@4.2.0: - resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} - http-errors@2.0.1: resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} engines: {node: '>= 0.8'} @@ -4815,9 +5034,9 @@ packages: resolution: {integrity: sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - http2-wrapper@1.0.3: - resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} - engines: {node: '>=10.19.0'} + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} @@ -4874,17 +5093,6 @@ packages: resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - instantsearch-ui-components@0.17.1: - resolution: {integrity: sha512-uOn39sNs9ukK0N6pklVdxbE5dapIdSJmkh/WJPPtOe4bpnvLzzvvexQYpUJ9vy1xQJMaQcAoPMoMKfBXwUA29A==} - - instantsearch.css@7.4.5: - resolution: {integrity: sha512-iIGBYjCokU93DDB8kbeztKtlu4qVEyTg1xvS6iSO1YvqRwkIZgf0tmsl/GytsLdZhuw8j4wEaeYsCzNbeJ/zEQ==} - - instantsearch.js@4.87.1: - resolution: {integrity: sha512-KkOSosDPnCXZg5QNZ6AnW+wWJaTsK0kXzUyr4/ugGE/Tm5Fn5D08yC9RFT4JxlvDJw+re0ov1xBbWKBcBn8XuA==} - peerDependencies: - algoliasearch: '>= 3.1 < 6' - ioredis@5.10.1: resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==} engines: {node: '>=12.22.0'} @@ -4927,6 +5135,10 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} hasBin: true + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -5024,12 +5236,25 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true + js-beautify@1.15.4: + resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} + engines: {node: '>=14'} + hasBin: true + + js-cookie@3.0.7: + resolution: {integrity: sha512-z/wZZgDrkNV1eA0ULjM/F9/50Ya8fbzgKneSpoPsXSGd0KnpdtHfOZWK+GcwLk+EZbS4F9RBhU+K2RgzuDaItw==} + engines: {node: '>=20'} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + js-yaml@4.1.1: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true @@ -5067,6 +5292,10 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + kleur@4.1.5: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} @@ -5226,6 +5455,10 @@ packages: lodash@4.18.1: resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + loglevel@1.9.2: + resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} + engines: {node: '>= 0.6.0'} + logs-sdk@0.0.6: resolution: {integrity: sha512-G4M1C9aLLBOIWpmw/Lqk4zrap/T2IJsoUOuUDjRcVSLy6lHQqxr3wCqIT1FvvpYTUYpEwvu4utsMY42jTNvx8Q==} @@ -5235,10 +5468,6 @@ packages: longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} - lowercase-keys@2.0.0: - resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} - engines: {node: '>=8'} - lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -5265,15 +5494,6 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} - markdown-to-jsx@7.7.17: - resolution: {integrity: sha512-7mG/1feQ0TX5I7YyMZVDgCC/y2I3CiEhIRQIhyov9nGBP5eoVrOXXHuL5ZP8GRfxVZKRiXWJgwXkb9It+nQZfQ==} - engines: {node: '>= 10'} - peerDependencies: - react: '>= 0.14.0' - peerDependenciesMeta: - react: - optional: true - marked@17.0.6: resolution: {integrity: sha512-gB0gkNafnonOw0obSTEGZTT86IuhILt2Wfx0mWH/1Au83kybTayroZ/V6nS25mN7u8ASy+5fMhgB3XPNrOZdmA==} engines: {node: '>= 20'} @@ -5335,9 +5555,6 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - metadata-scraper@0.2.61: - resolution: {integrity: sha512-ECV8r10nIVgn7Y5vY8lnlvi9vF1YgYBJjn2R1zrOcKRe47ra9Yg25ZE1ejL3Equqi8u2Mp346KHqIcR4PLdyTA==} - micro-api-client@3.3.0: resolution: {integrity: sha512-y0y6CUB9RLVsy3kfgayU28746QrNMpSm9O/AYGNsBgOkJr/X/Jk0VLGoO8Ude7Bpa8adywzF+MzXNZRFRsNPhg==} @@ -5454,10 +5671,6 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} - mimic-response@1.0.1: - resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} - engines: {node: '>=4'} - mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} @@ -5494,16 +5707,9 @@ packages: resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} engines: {node: '>= 18'} - mitt@2.1.0: - resolution: {integrity: sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==} - mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - mkdirp@0.3.0: - resolution: {integrity: sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew==} - deprecated: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.) - mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} @@ -5614,8 +5820,9 @@ packages: node-releases@2.0.38: resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==} - nopt@1.0.10: - resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} + nopt@7.2.1: + resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} hasBin: true nopt@8.1.0: @@ -5627,10 +5834,6 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - normalize-url@6.1.0: - resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} - engines: {node: '>=10'} - npm-run-path@5.3.0: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -5778,6 +5981,11 @@ packages: engines: {node: '>=18'} hasBin: true + nypm@0.6.6: + resolution: {integrity: sha512-vRyr0r4cbBapw07Xw8xrj9Teq3o7MUD35rSaTcanDbW+aK2XHDgJFiU6ZTj2GBw7Q12ysdsyFss+Vdz4hQ0Y6Q==} + engines: {node: '>=18'} + hasBin: true + object-deep-merge@2.0.0: resolution: {integrity: sha512-3DC3UMpeffLTHiuXSy/UG4NOIYTLlY9u3V82+djSCLYClWobZiS4ivYzpIUWrRY/nfsJ8cWsKyG3QfyLePmhvg==} @@ -5861,10 +6069,6 @@ packages: peerDependencies: oxc-parser: '>=0.98.0' - p-cancelable@2.1.1: - resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} - engines: {node: '>=8'} - p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -6206,9 +6410,6 @@ packages: resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} engines: {node: '>=20'} - preact@10.28.3: - resolution: {integrity: sha512-tCmoRkPQLpBeWzpmbhryairGnhW9tKV6c6gr/w+RhoRoKEJwsjzipwp//1oCpGPOchvSLaAPlpcJi9MwMmoPyA==} - preact@10.29.1: resolution: {integrity: sha512-gQCLc/vWroE8lIpleXtdJhTFDogTdZG9AjMUpVkDf2iTCNwYNWA+u16dL41TqUDJO4gm2IgrcMv3uTpjd4Pwmg==} @@ -6272,6 +6473,9 @@ packages: prosemirror-view@1.41.8: resolution: {integrity: sha512-TnKDdohEatgyZNGCDWIdccOHXhYloJwbwU+phw/a23KBvJIR9lWQWW7WHHK3vBdOLDNuF7TaX98GObUZOWkOnA==} + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + protobufjs@7.5.5: resolution: {integrity: sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg==} engines: {node: '>=12.0.0'} @@ -6279,11 +6483,9 @@ packages: protocols@2.0.2: resolution: {integrity: sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} pump@3.0.4: resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} @@ -6292,10 +6494,6 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - qs@6.14.1: - resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==} - engines: {node: '>=0.6'} - qs@6.15.1: resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} engines: {node: '>=0.6'} @@ -6309,10 +6507,6 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - quick-lru@5.1.1: - resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} - engines: {node: '>=10'} - radix3@1.1.2: resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} @@ -6333,10 +6527,6 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true - react@19.2.4: - resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} - engines: {node: '>=0.10.0'} - readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} @@ -6425,8 +6615,8 @@ packages: remark-gfm@4.0.1: resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} - remark-mdc@3.10.0: - resolution: {integrity: sha512-gJhrSs4bGyqr7eSuLoaLlpmiDZrJ9fP/8gTA/w1CnKnW/mfxc9VKM+ndzpOxHQnpAU4tjD8QqF6SMLiOvIVTYA==} + remark-mdc@3.11.0: + resolution: {integrity: sha512-xFrKmGRa+xgsfAZPA2CDaKILSHSOhX2irjJBrrPLxNrxaz2NFI+gXuVjo6Bkbh2vx7fKKTB5S9yyKyIwJh+FsQ==} remark-parse@11.0.0: resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} @@ -6437,13 +6627,13 @@ packages: remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + remark@15.0.1: + resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==} + reserved-identifiers@1.2.0: resolution: {integrity: sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==} engines: {node: '>=18'} - resolve-alpn@1.2.1: - resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} - resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -6460,9 +6650,6 @@ packages: engines: {node: '>= 0.4'} hasBin: true - responselike@2.0.1: - resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} - reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -6561,8 +6748,9 @@ packages: scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} - search-insights@2.17.3: - resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==} + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} @@ -6640,6 +6828,9 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} @@ -6716,6 +6907,9 @@ packages: spdx-license-ids@3.0.23: resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + srvx@0.11.15: resolution: {integrity: sha512-iXsux0UcOjdvs0LCMa2Ws3WwcDUozA3JN3BquNXkaFPP7TpRqgunKdEgoZ/uwb1J6xaYHfxtz9Twlh6yzwM6Tg==} engines: {node: '>=20.16.0'} @@ -6725,6 +6919,9 @@ packages: resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} engines: {node: '>=12.0.0'} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + standard-as-callback@2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} @@ -6738,12 +6935,6 @@ packages: std-env@4.1.0: resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} - storyblok-algolia-indexer@1.1.0: - resolution: {integrity: sha512-Kuy4FAzhdNC//LtZ+FJ3kZ92W9FVe7auUicAj4e2of5j4VE2BXYtg/TdAWtekjvA4vvzHYoYCt1sPPDe45n29A==} - - storyblok-js-client@5.14.4: - resolution: {integrity: sha512-9yY33tvfO3Cbe25h/l6K0T3IxJeOOyGl/pCwsd55woT0ZEBhIiEZoMumpRsyLjD5AedW9KXLbLjMXhHazkepCA==} - streamx@2.25.0: resolution: {integrity: sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==} @@ -6776,6 +6967,10 @@ packages: resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + strip-final-newline@3.0.0: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} @@ -6879,6 +7074,9 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinyclip@0.1.12: resolution: {integrity: sha512-Ae3OVUqifDw0wBriIBS7yVaW44Dp6eSHQcyq4Igc7eN2TJH/2YsicswaW+J/OuMvhpDPOKEgpAZCjkb4hpoyeA==} engines: {node: ^16.14.0 || >= 17.3.0} @@ -6899,6 +7097,10 @@ packages: resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} engines: {node: '>=12.0.0'} + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} + engines: {node: '>=14.0.0'} + to-buffer@1.2.2: resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} engines: {node: '>= 0.4'} @@ -6940,6 +7142,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.22.3: + resolution: {integrity: sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg==} + engines: {node: '>=18.0.0'} + hasBin: true + tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} @@ -6972,6 +7179,12 @@ packages: engines: {node: '>=14.17'} hasBin: true + typesense@3.0.6: + resolution: {integrity: sha512-d3LL1qOLS8FCRxgAOqH+uDuK+VVA+/HYI1frU9fjYVwOg68mg/dX6XTtZ4yKKAkDCasB/se5uh/ZpMdOz/uJNg==} + engines: {node: '>=18'} + peerDependencies: + '@babel/runtime': ^7.23.2 + ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} @@ -7318,6 +7531,50 @@ packages: yaml: optional: true + vitest-environment-nuxt@2.0.0: + resolution: {integrity: sha512-zEGFRiCAaRR3fHnqISHKMNTRvCzkQEI1XyFeqNgR2IBD0oYkfZ1rUHwi7C+h3Cns3KPykfB0av1B3MtLEbChDw==} + + vitest@4.1.7: + resolution: {integrity: sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.1.7 + '@vitest/browser-preview': 4.1.7 + '@vitest/browser-webdriverio': 4.1.7 + '@vitest/coverage-istanbul': 4.1.7 + '@vitest/coverage-v8': 4.1.7 + '@vitest/ui': 4.1.7 + happy-dom: '*' + jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vscode-uri@3.1.0: resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} @@ -7355,19 +7612,6 @@ packages: peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - vue-instantsearch@4.23.1: - resolution: {integrity: sha512-5nu1cwsjjmOe/768SLxiOk9WiWlai4TJZ78i7rYmqYAMeEG9dRGy32qGPvl2SVVpaowaR1f9mixU4nIgGxP/Ug==} - peerDependencies: - '@vue/server-renderer': ^3.1.2 - algoliasearch: '>= 3.32.0 < 6' - vue: ^2.6.0 || >=3.0.0-rc.0 - vue-server-renderer: ^2.6.11 - peerDependenciesMeta: - '@vue/server-renderer': - optional: true - vue-server-renderer: - optional: true - vue-router@5.0.6: resolution: {integrity: sha512-9+kmUTGbKMyW9Asoy98IXXYIzrTMT7JDAdpDDeEkorHvybpUvBI2wsrSM5jFOXrFydpzRFJ9vAh+80DN2PGu9w==} peerDependencies: @@ -7416,6 +7660,10 @@ packages: webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -7437,6 +7685,11 @@ packages: engines: {node: ^20.17.0 || >=22.9.0} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -7527,6 +7780,11 @@ packages: engines: {node: '>= 14.6'} hasBin: true + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} + engines: {node: '>= 14.6'} + hasBin: true + yargs-parser@22.0.0: resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} engines: {node: ^20.19.0 || ^22.12.0 || >=23} @@ -7557,11 +7815,6 @@ packages: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} - zod-to-json-schema@3.24.6: - resolution: {integrity: sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==} - peerDependencies: - zod: ^3.24.1 - zod-to-json-schema@3.25.2: resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} peerDependencies: @@ -7570,102 +7823,11 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - zod@4.3.6: - resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} - zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} snapshots: - '@algolia/cache-browser-local-storage@4.25.3': - dependencies: - '@algolia/cache-common': 4.25.3 - - '@algolia/cache-common@4.25.3': {} - - '@algolia/cache-in-memory@4.25.3': - dependencies: - '@algolia/cache-common': 4.25.3 - - '@algolia/client-account@4.25.3': - dependencies: - '@algolia/client-common': 4.25.3 - '@algolia/client-search': 4.25.3 - '@algolia/transporter': 4.25.3 - - '@algolia/client-analytics@4.25.3': - dependencies: - '@algolia/client-common': 4.25.3 - '@algolia/client-search': 4.25.3 - '@algolia/requester-common': 4.25.3 - '@algolia/transporter': 4.25.3 - - '@algolia/client-common@4.25.3': - dependencies: - '@algolia/requester-common': 4.25.3 - '@algolia/transporter': 4.25.3 - - '@algolia/client-common@5.48.0': {} - - '@algolia/client-personalization@4.25.3': - dependencies: - '@algolia/client-common': 4.25.3 - '@algolia/requester-common': 4.25.3 - '@algolia/transporter': 4.25.3 - - '@algolia/client-search@4.25.3': - dependencies: - '@algolia/client-common': 4.25.3 - '@algolia/requester-common': 4.25.3 - '@algolia/transporter': 4.25.3 - - '@algolia/events@4.0.1': {} - - '@algolia/logger-common@4.25.3': {} - - '@algolia/logger-console@4.25.3': - dependencies: - '@algolia/logger-common': 4.25.3 - - '@algolia/recommend@4.25.3': - dependencies: - '@algolia/cache-browser-local-storage': 4.25.3 - '@algolia/cache-common': 4.25.3 - '@algolia/cache-in-memory': 4.25.3 - '@algolia/client-common': 4.25.3 - '@algolia/client-search': 4.25.3 - '@algolia/logger-common': 4.25.3 - '@algolia/logger-console': 4.25.3 - '@algolia/requester-browser-xhr': 4.25.3 - '@algolia/requester-common': 4.25.3 - '@algolia/requester-node-http': 4.25.3 - '@algolia/transporter': 4.25.3 - - '@algolia/requester-browser-xhr@4.25.3': - dependencies: - '@algolia/requester-common': 4.25.3 - - '@algolia/requester-common@4.25.3': {} - - '@algolia/requester-fetch@4.25.3': - dependencies: - '@algolia/requester-common': 4.25.3 - - '@algolia/requester-node-http@4.25.3': - dependencies: - '@algolia/requester-common': 4.25.3 - - '@algolia/requester-node-http@5.48.0': - dependencies: - '@algolia/client-common': 5.48.0 - - '@algolia/transporter@4.25.3': - dependencies: - '@algolia/cache-common': 4.25.3 - '@algolia/logger-common': 4.25.3 - '@algolia/requester-common': 4.25.3 - '@alloc/quick-lru@5.2.0': {} '@antfu/install-pkg@1.1.0': @@ -7822,7 +7984,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/runtime@7.28.6': {} + '@babel/runtime@7.29.2': {} '@babel/template@7.28.6': dependencies: @@ -7876,10 +8038,6 @@ snapshots: '@directus/sdk@21.2.2': {} - '@docsearch/css@4.6.2': {} - - '@docsearch/js@4.6.2': {} - '@dxup/nuxt@0.4.1(magicast@0.5.2)(typescript@6.0.3)': dependencies: '@dxup/unimport': 0.1.2 @@ -7934,81 +8092,159 @@ snapshots: '@esbuild/aix-ppc64@0.27.7': optional: true + '@esbuild/aix-ppc64@0.28.0': + optional: true + '@esbuild/android-arm64@0.27.7': optional: true + '@esbuild/android-arm64@0.28.0': + optional: true + '@esbuild/android-arm@0.27.7': optional: true + '@esbuild/android-arm@0.28.0': + optional: true + '@esbuild/android-x64@0.27.7': optional: true + '@esbuild/android-x64@0.28.0': + optional: true + '@esbuild/darwin-arm64@0.27.7': optional: true + '@esbuild/darwin-arm64@0.28.0': + optional: true + '@esbuild/darwin-x64@0.27.7': optional: true + '@esbuild/darwin-x64@0.28.0': + optional: true + '@esbuild/freebsd-arm64@0.27.7': optional: true + '@esbuild/freebsd-arm64@0.28.0': + optional: true + '@esbuild/freebsd-x64@0.27.7': optional: true + '@esbuild/freebsd-x64@0.28.0': + optional: true + '@esbuild/linux-arm64@0.27.7': optional: true + '@esbuild/linux-arm64@0.28.0': + optional: true + '@esbuild/linux-arm@0.27.7': optional: true + '@esbuild/linux-arm@0.28.0': + optional: true + '@esbuild/linux-ia32@0.27.7': optional: true + '@esbuild/linux-ia32@0.28.0': + optional: true + '@esbuild/linux-loong64@0.27.7': optional: true + '@esbuild/linux-loong64@0.28.0': + optional: true + '@esbuild/linux-mips64el@0.27.7': optional: true + '@esbuild/linux-mips64el@0.28.0': + optional: true + '@esbuild/linux-ppc64@0.27.7': optional: true + '@esbuild/linux-ppc64@0.28.0': + optional: true + '@esbuild/linux-riscv64@0.27.7': optional: true + '@esbuild/linux-riscv64@0.28.0': + optional: true + '@esbuild/linux-s390x@0.27.7': optional: true + '@esbuild/linux-s390x@0.28.0': + optional: true + '@esbuild/linux-x64@0.27.7': optional: true + '@esbuild/linux-x64@0.28.0': + optional: true + '@esbuild/netbsd-arm64@0.27.7': optional: true + '@esbuild/netbsd-arm64@0.28.0': + optional: true + '@esbuild/netbsd-x64@0.27.7': optional: true + '@esbuild/netbsd-x64@0.28.0': + optional: true + '@esbuild/openbsd-arm64@0.27.7': optional: true + '@esbuild/openbsd-arm64@0.28.0': + optional: true + '@esbuild/openbsd-x64@0.27.7': optional: true + '@esbuild/openbsd-x64@0.28.0': + optional: true + '@esbuild/openharmony-arm64@0.27.7': optional: true + '@esbuild/openharmony-arm64@0.28.0': + optional: true + '@esbuild/sunos-x64@0.27.7': optional: true + '@esbuild/sunos-x64@0.28.0': + optional: true + '@esbuild/win32-arm64@0.27.7': optional: true + '@esbuild/win32-arm64@0.28.0': + optional: true + '@esbuild/win32-ia32@0.27.7': optional: true + '@esbuild/win32-ia32@0.28.0': + optional: true + '@esbuild/win32-x64@0.27.7': optional: true + '@esbuild/win32-x64@0.28.0': + optional: true + '@eslint-community/eslint-utils@4.9.1(eslint@9.28.0(jiti@2.6.1))': dependencies: eslint: 9.28.0(jiti@2.6.1) @@ -8129,10 +8365,18 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@iconify-json/heroicons-outline@1.2.1': + dependencies: + '@iconify/types': 2.0.0 + '@iconify-json/material-symbols@1.2.68': dependencies: '@iconify/types': 2.0.0 + '@iconify-json/ph@1.2.2': + dependencies: + '@iconify/types': 2.0.0 + '@iconify-json/simple-icons@1.2.79': dependencies: '@iconify/types': 2.0.0 @@ -8452,7 +8696,7 @@ snapshots: ohash: 2.0.11 pathe: 2.0.3 pkg-types: 2.3.0 - remark-mdc: 3.10.0 + remark-mdc: 3.11.0 scule: 1.3.0 shiki: 4.0.2 slugify: 1.6.9 @@ -8480,19 +8724,27 @@ snapshots: '@nuxt/devalue@2.0.2': {} - '@nuxt/devtools-kit@3.2.4(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))': + '@nuxt/devtools-kit@2.7.0(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))': + dependencies: + '@nuxt/kit': 3.21.2(magicast@0.5.2) + execa: 8.0.1 + vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + transitivePeerDependencies: + - magicast + + '@nuxt/devtools-kit@3.2.4(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))': dependencies: '@nuxt/kit': 4.4.2(magicast@0.5.2) execa: 8.0.1 - vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3) + vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) transitivePeerDependencies: - magicast - '@nuxt/devtools-kit@4.0.0-alpha.3(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))': + '@nuxt/devtools-kit@4.0.0-alpha.3(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))': dependencies: '@nuxt/kit': 4.4.2(magicast@0.5.2) tinyexec: 1.1.1 - vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3) + vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) transitivePeerDependencies: - magicast @@ -8507,9 +8759,9 @@ snapshots: pkg-types: 2.3.0 semver: 7.7.4 - '@nuxt/devtools@3.2.4(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))': + '@nuxt/devtools@3.2.4(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))': dependencies: - '@nuxt/devtools-kit': 3.2.4(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + '@nuxt/devtools-kit': 3.2.4(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) '@nuxt/devtools-wizard': 3.2.4 '@nuxt/kit': 4.4.2(magicast@0.5.2) '@vue/devtools-core': 8.1.1(vue@3.5.33(typescript@6.0.3)) @@ -8537,9 +8789,9 @@ snapshots: sirv: 3.0.2 structured-clone-es: 2.0.0 tinyglobby: 0.2.16 - vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3) - vite-plugin-inspect: 11.3.3(@nuxt/kit@4.4.2(magicast@0.5.2))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) - vite-plugin-vue-tracer: 1.3.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3)) + vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + vite-plugin-inspect: 11.3.3(@nuxt/kit@4.4.2(magicast@0.5.2))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) + vite-plugin-vue-tracer: 1.3.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3)) which: 6.0.1 ws: 8.20.0 transitivePeerDependencies: @@ -8588,10 +8840,10 @@ snapshots: - supports-color - typescript - '@nuxt/eslint@1.15.2(@typescript-eslint/utils@8.59.0(eslint@9.28.0(jiti@2.6.1))(typescript@6.0.3))(@vue/compiler-sfc@3.5.33)(eslint@9.28.0(jiti@2.6.1))(magicast@0.5.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))': + '@nuxt/eslint@1.15.2(@typescript-eslint/utils@8.59.0(eslint@9.28.0(jiti@2.6.1))(typescript@6.0.3))(@vue/compiler-sfc@3.5.33)(eslint@9.28.0(jiti@2.6.1))(magicast@0.5.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))': dependencies: '@eslint/config-inspector': 1.5.0(eslint@9.28.0(jiti@2.6.1)) - '@nuxt/devtools-kit': 3.2.4(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + '@nuxt/devtools-kit': 3.2.4(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) '@nuxt/eslint-config': 1.15.2(@typescript-eslint/utils@8.59.0(eslint@9.28.0(jiti@2.6.1))(typescript@6.0.3))(@vue/compiler-sfc@3.5.33)(eslint@9.28.0(jiti@2.6.1))(typescript@6.0.3) '@nuxt/eslint-plugin': 1.15.2(eslint@9.28.0(jiti@2.6.1))(typescript@6.0.3) '@nuxt/kit': 4.4.2(magicast@0.5.2) @@ -8616,13 +8868,13 @@ snapshots: - utf-8-validate - vite - '@nuxt/fonts@0.14.0(@netlify/blobs@9.1.2)(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))': + '@nuxt/fonts@0.14.0(@netlify/blobs@9.1.2)(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))': dependencies: - '@nuxt/devtools-kit': 3.2.4(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + '@nuxt/devtools-kit': 3.2.4(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) '@nuxt/kit': 4.4.2(magicast@0.5.2) consola: 3.4.2 defu: 6.1.7 - fontless: 0.2.1(@netlify/blobs@9.1.2)(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + fontless: 0.2.1(@netlify/blobs@9.1.2)(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) h3: 1.15.11 magic-regexp: 0.10.0 ofetch: 1.5.1 @@ -8656,13 +8908,13 @@ snapshots: - uploadthing - vite - '@nuxt/icon@2.2.1(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))': + '@nuxt/icon@2.2.1(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))': dependencies: '@iconify/collections': 1.0.675 '@iconify/types': 2.0.0 '@iconify/utils': 3.1.0 '@iconify/vue': 5.0.0(vue@3.5.33(typescript@6.0.3)) - '@nuxt/devtools-kit': 3.2.4(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + '@nuxt/devtools-kit': 3.2.4(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) '@nuxt/kit': 4.4.2(magicast@0.5.2) consola: 3.4.2 local-pkg: 1.1.2 @@ -8677,32 +8929,6 @@ snapshots: - vite - vue - '@nuxt/kit@3.21.1(magicast@0.5.2)': - dependencies: - c12: 3.3.3(magicast@0.5.2) - consola: 3.4.2 - defu: 6.1.4 - destr: 2.0.5 - errx: 0.1.0 - exsolve: 1.0.8 - ignore: 7.0.5 - jiti: 2.6.1 - klona: 2.0.6 - knitwork: 1.3.0 - mlly: 1.8.0 - ohash: 2.0.11 - pathe: 2.0.3 - pkg-types: 2.3.0 - rc9: 3.0.0 - scule: 1.3.0 - semver: 7.7.4 - tinyglobby: 0.2.15 - ufo: 1.6.3 - unctx: 2.5.0 - untyped: 2.0.0 - transitivePeerDependencies: - - magicast - '@nuxt/kit@3.21.2(magicast@0.5.2)': dependencies: c12: 3.3.4(magicast@0.5.2) @@ -8779,7 +9005,7 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/nitro-server@4.4.2(b200ed249053ecb3871c92755e06a756)': + '@nuxt/nitro-server@4.4.2(d8bfb31b08d32093c0f73363b4b5ece1)': dependencies: '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) '@nuxt/devalue': 2.0.2 @@ -8798,7 +9024,7 @@ snapshots: klona: 2.0.6 mocked-exports: 0.1.1 nitropack: 2.13.3(@netlify/blobs@9.1.2)(better-sqlite3@11.10.0)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(srvx@0.11.15) - nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3) + nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0) nypm: 0.6.5 ohash: 2.0.11 pathe: 2.0.3 @@ -8857,9 +9083,9 @@ snapshots: pkg-types: 2.3.0 std-env: 4.1.0 - '@nuxt/scripts@1.0.2(@netlify/blobs@9.1.2)(@types/google.maps@3.58.1)(@unhead/vue@2.1.13(vue@3.5.33(typescript@6.0.3)))(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(magicast@0.5.2)(posthog-js@1.371.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))': + '@nuxt/scripts@1.0.2(@netlify/blobs@9.1.2)(@types/google.maps@3.58.1)(@unhead/vue@2.1.13(vue@3.5.33(typescript@6.0.3)))(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(magicast@0.5.2)(posthog-js@1.371.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))': dependencies: - '@nuxt/devtools-kit': 3.2.4(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + '@nuxt/devtools-kit': 3.2.4(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) '@nuxt/kit': 4.4.2(magicast@0.5.2) '@unhead/vue': 2.1.13(vue@3.5.33(typescript@6.0.3)) '@vueuse/core': 14.2.1(vue@3.5.33(typescript@6.0.3)) @@ -8918,20 +9144,62 @@ snapshots: rc9: 3.0.1 std-env: 4.1.0 - '@nuxt/ui@4.6.1(@netlify/blobs@9.1.2)(@nuxt/content@3.13.0(better-sqlite3@11.10.0)(magicast@0.5.2)(valibot@1.3.1(typescript@6.0.3)))(@tiptap/extensions@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@tiptap/y-tiptap@3.0.3(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))(axios@1.13.5)(change-case@5.4.4)(db0@0.3.4(better-sqlite3@11.10.0))(embla-carousel@8.6.0)(ioredis@5.10.1)(jwt-decode@4.0.0)(magicast@0.5.2)(tailwindcss@4.2.4)(typescript@6.0.3)(valibot@1.3.1(typescript@6.0.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-router@5.0.6(@vue/compiler-sfc@3.5.33)(vue@3.5.33(typescript@6.0.3)))(vue@3.5.33(typescript@6.0.3))(yjs@13.6.30)(zod@4.3.6)': + '@nuxt/test-utils@4.0.3(@vue/test-utils@2.4.10(@vue/compiler-dom@3.5.33)(@vue/server-renderer@3.5.33(vue@3.5.33(typescript@6.0.3)))(vue@3.5.33(typescript@6.0.3)))(crossws@0.4.5(srvx@0.11.15))(happy-dom@20.9.0)(magicast@0.5.2)(playwright-core@1.58.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vitest@4.1.7(@opentelemetry/api@1.9.1)(@types/node@22.19.17)(happy-dom@20.9.0)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)))': + dependencies: + '@clack/prompts': 1.2.0 + '@nuxt/devtools-kit': 2.7.0(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) + '@nuxt/kit': 3.21.2(magicast@0.5.2) + c12: 3.3.4(magicast@0.5.2) + consola: 3.4.2 + defu: 6.1.7 + destr: 2.0.5 + estree-walker: 3.0.3 + exsolve: 1.0.8 + fake-indexeddb: 6.2.5 + get-port-please: 3.2.0 + h3: 1.15.11 + h3-next: h3@2.0.1-rc.20(crossws@0.4.5(srvx@0.11.15)) + local-pkg: 1.1.2 + magic-string: 0.30.21 + node-fetch-native: 1.6.7 + node-mock-http: 1.0.4 + nypm: 0.6.6 + ofetch: 1.5.1 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + radix3: 1.1.2 + scule: 1.3.0 + std-env: 4.1.0 + tinyexec: 1.1.1 + ufo: 1.6.3 + unplugin: 3.0.0 + vitest-environment-nuxt: 2.0.0(@vue/test-utils@2.4.10(@vue/compiler-dom@3.5.33)(@vue/server-renderer@3.5.33(vue@3.5.33(typescript@6.0.3)))(vue@3.5.33(typescript@6.0.3)))(crossws@0.4.5(srvx@0.11.15))(happy-dom@20.9.0)(magicast@0.5.2)(playwright-core@1.58.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vitest@4.1.7(@opentelemetry/api@1.9.1)(@types/node@22.19.17)(happy-dom@20.9.0)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))) + vue: 3.5.33(typescript@6.0.3) + optionalDependencies: + '@vue/test-utils': 2.4.10(@vue/compiler-dom@3.5.33)(@vue/server-renderer@3.5.33(vue@3.5.33(typescript@6.0.3)))(vue@3.5.33(typescript@6.0.3)) + happy-dom: 20.9.0 + playwright-core: 1.58.2 + vitest: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@22.19.17)(happy-dom@20.9.0)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) + transitivePeerDependencies: + - crossws + - magicast + - typescript + - vite + + '@nuxt/ui@4.6.1(@netlify/blobs@9.1.2)(@nuxt/content@3.13.0(better-sqlite3@11.10.0)(magicast@0.5.2)(valibot@1.3.1(typescript@6.0.3)))(@tiptap/extensions@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@tiptap/y-tiptap@3.0.3(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))(axios@1.16.1)(change-case@5.4.4)(db0@0.3.4(better-sqlite3@11.10.0))(embla-carousel@8.6.0)(ioredis@5.10.1)(jwt-decode@4.0.0)(magicast@0.5.2)(tailwindcss@4.2.4)(typescript@6.0.3)(valibot@1.3.1(typescript@6.0.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-router@5.0.6(@vue/compiler-sfc@3.5.33)(vue@3.5.33(typescript@6.0.3)))(vue@3.5.33(typescript@6.0.3))(yjs@13.6.30)(zod@3.25.76)': dependencies: '@floating-ui/dom': 1.7.6 '@iconify/vue': 5.0.0(vue@3.5.33(typescript@6.0.3)) '@internationalized/date': 3.12.1 '@internationalized/number': 3.6.6 - '@nuxt/fonts': 0.14.0(@netlify/blobs@9.1.2)(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) - '@nuxt/icon': 2.2.1(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3)) + '@nuxt/fonts': 0.14.0(@netlify/blobs@9.1.2)(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) + '@nuxt/icon': 2.2.1(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3)) '@nuxt/kit': 4.4.2(magicast@0.5.2) '@nuxt/schema': 4.4.2 '@nuxtjs/color-mode': 3.5.2(magicast@0.5.2) '@standard-schema/spec': 1.1.0 '@tailwindcss/postcss': 4.2.4 - '@tailwindcss/vite': 4.2.4(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + '@tailwindcss/vite': 4.2.4(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) '@tanstack/vue-table': 8.21.3(vue@3.5.33(typescript@6.0.3)) '@tanstack/vue-virtual': 3.13.24(vue@3.5.33(typescript@6.0.3)) '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) @@ -8953,7 +9221,7 @@ snapshots: '@tiptap/vue-3': 3.22.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)(vue@3.5.33(typescript@6.0.3)) '@unhead/vue': 2.1.13(vue@3.5.33(typescript@6.0.3)) '@vueuse/core': 14.2.1(vue@3.5.33(typescript@6.0.3)) - '@vueuse/integrations': 14.2.1(axios@1.13.5)(change-case@5.4.4)(fuse.js@7.3.0)(jwt-decode@4.0.0)(vue@3.5.33(typescript@6.0.3)) + '@vueuse/integrations': 14.2.1(axios@1.16.1)(change-case@5.4.4)(fuse.js@7.3.0)(jwt-decode@4.0.0)(vue@3.5.33(typescript@6.0.3)) '@vueuse/shared': 14.2.1(vue@3.5.33(typescript@6.0.3)) colortranslator: 5.0.0 consola: 3.4.2 @@ -8990,7 +9258,7 @@ snapshots: '@nuxt/content': 3.13.0(better-sqlite3@11.10.0)(magicast@0.5.2)(valibot@1.3.1(typescript@6.0.3)) valibot: 1.3.1(typescript@6.0.3) vue-router: 5.0.6(@vue/compiler-sfc@3.5.33)(vue@3.5.33(typescript@6.0.3)) - zod: 4.3.6 + zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -9033,12 +9301,12 @@ snapshots: - vue - yjs - '@nuxt/vite-builder@4.4.2(40ef2daf26488a39f37e42046efdfe2d)': + '@nuxt/vite-builder@4.4.2(7c2c1dd7c498c9a3b536bcb4959772f5)': dependencies: '@nuxt/kit': 4.4.2(magicast@0.5.2) '@rollup/plugin-replace': 6.0.3(rollup@4.60.2) - '@vitejs/plugin-vue': 6.0.6(rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3)) - '@vitejs/plugin-vue-jsx': 5.1.5(rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3)) + '@vitejs/plugin-vue': 6.0.6(rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3)) + '@vitejs/plugin-vue-jsx': 5.1.5(rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3)) autoprefixer: 10.5.0(postcss@8.5.10) consola: 3.4.2 cssnano: 7.1.7(postcss@8.5.10) @@ -9051,7 +9319,7 @@ snapshots: magic-string: 0.30.21 mlly: 1.8.2 mocked-exports: 0.1.1 - nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3) + nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0) nypm: 0.6.5 pathe: 2.0.3 pkg-types: 2.3.0 @@ -9060,9 +9328,9 @@ snapshots: std-env: 4.1.0 ufo: 1.6.3 unenv: 2.0.0-rc.24 - vite: rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(yaml@2.8.3) - vite-node: 5.3.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(yaml@2.8.3) - vite-plugin-checker: 0.12.0(eslint@9.28.0(jiti@2.6.1))(optionator@0.9.4)(rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(yaml@2.8.3))(typescript@6.0.3)(vue-tsc@3.2.7(typescript@6.0.3)) + vite: rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + vite-node: 5.3.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + vite-plugin-checker: 0.12.0(eslint@9.28.0(jiti@2.6.1))(optionator@0.9.4)(rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(typescript@6.0.3)(vue-tsc@3.2.7(typescript@6.0.3)) vue: 3.5.33(typescript@6.0.3) vue-bundle-renderer: 2.2.0 optionalDependencies: @@ -9096,29 +9364,6 @@ snapshots: - vue-tsc - yaml - '@nuxtjs/algolia@1.11.2(@vue/server-renderer@3.5.33(vue@3.5.33(typescript@6.0.3)))(magicast@0.5.2)(vue@3.5.33(typescript@6.0.3))': - dependencies: - '@algolia/cache-in-memory': 4.25.3 - '@algolia/recommend': 4.25.3 - '@algolia/requester-fetch': 4.25.3 - '@algolia/requester-node-http': 5.48.0 - '@nuxt/kit': 3.21.1(magicast@0.5.2) - algoliasearch: 4.25.3 - defu: 6.1.4 - exsolve: 1.0.8 - instantsearch.css: 7.4.5 - metadata-scraper: 0.2.61 - mocked-exports: 0.1.1 - storyblok-algolia-indexer: 1.1.0 - vue-instantsearch: 4.23.1(@vue/server-renderer@3.5.33(vue@3.5.33(typescript@6.0.3)))(algoliasearch@4.25.3)(vue@3.5.33(typescript@6.0.3)) - transitivePeerDependencies: - - '@vue/server-renderer' - - debug - - magicast - - react - - vue - - vue-server-renderer - '@nuxtjs/color-mode@3.5.2(magicast@0.5.2)': dependencies: '@nuxt/kit': 3.21.2(magicast@0.5.2) @@ -9172,7 +9417,7 @@ snapshots: rehype-sort-attributes: 5.0.1 remark-emoji: 5.0.2 remark-gfm: 4.0.1 - remark-mdc: 3.10.0 + remark-mdc: 3.11.0 remark-parse: 11.0.0 remark-rehype: 11.1.2 remark-stringify: 11.0.0 @@ -9188,20 +9433,20 @@ snapshots: - magicast - supports-color - '@nuxtjs/robots@6.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))(zod@4.3.6)': + '@nuxtjs/robots@6.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))(zod@3.25.76)': dependencies: '@fingerprintjs/botd': 2.0.0 '@nuxt/kit': 4.4.2(magicast@0.5.2) consola: 3.4.2 defu: 6.1.7 h3: 1.15.11 - nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))(zod@4.3.6) - nuxtseo-shared: 5.1.3(25023e8fc1951fd485d95c7642f63f09) + nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))(zod@3.25.76) + nuxtseo-shared: 5.1.3(831cc79224bc9108dd0c9e6e36ee323c) pathe: 2.0.3 pkg-types: 2.3.0 ufo: 1.6.3 optionalDependencies: - zod: 4.3.6 + zod: 3.25.76 transitivePeerDependencies: - '@nuxt/schema' - magicast @@ -9209,18 +9454,18 @@ snapshots: - vite - vue - '@nuxtjs/seo@5.1.3(f958a059aa9f5a6866becf12bff13989)': + '@nuxtjs/seo@5.1.3(1759d3db8cf72984d24b6002807c57ae)': dependencies: '@nuxt/kit': 4.4.2(magicast@0.5.2) - '@nuxtjs/robots': 6.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))(zod@4.3.6) - '@nuxtjs/sitemap': 8.0.13(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))(zod@4.3.6) - nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3) - nuxt-link-checker: 5.0.9(ad3672cc71ed4fef9dee73a54522c31c) - nuxt-og-image: 6.4.7(9fe474218c97b47f30882881f0852e2d) - nuxt-schema-org: 6.0.4(1a967bc97ce9677f66be35b83ed89595) - nuxt-seo-utils: 8.1.11(afd1536e353fe9aacca1e8172ba75d16) - nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))(zod@4.3.6) - nuxtseo-shared: 5.1.3(25023e8fc1951fd485d95c7642f63f09) + '@nuxtjs/robots': 6.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))(zod@3.25.76) + '@nuxtjs/sitemap': 8.0.13(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))(zod@3.25.76) + nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0) + nuxt-link-checker: 5.0.9(89533da900856b60956b41a60a77ded0) + nuxt-og-image: 6.4.7(0119389412a87344d59ece639bed8fe3) + nuxt-schema-org: 6.0.4(6f2234aa98e2ca2e8365a7c7195bb816) + nuxt-seo-utils: 8.1.11(f3ac38eccaefb2e9ee66d9006f0b5502) + nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))(zod@3.25.76) + nuxtseo-shared: 5.1.3(831cc79224bc9108dd0c9e6e36ee323c) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -9295,14 +9540,14 @@ snapshots: - yup - zod - '@nuxtjs/sitemap@8.0.13(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))(zod@4.3.6)': + '@nuxtjs/sitemap@8.0.13(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))(zod@3.25.76)': dependencies: '@nuxt/kit': 4.4.2(magicast@0.5.2) consola: 3.4.2 defu: 6.1.7 fast-xml-parser: 5.7.1 - nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))(zod@4.3.6) - nuxtseo-shared: 5.1.3(25023e8fc1951fd485d95c7642f63f09) + nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))(zod@3.25.76) + nuxtseo-shared: 5.1.3(831cc79224bc9108dd0c9e6e36ee323c) ofetch: 1.5.1 pathe: 2.0.3 pkg-types: 2.3.0 @@ -9310,7 +9555,7 @@ snapshots: ufo: 1.6.3 ultrahtml: 1.6.0 optionalDependencies: - zod: 4.3.6 + zod: 3.25.76 transitivePeerDependencies: - '@nuxt/schema' - magicast @@ -9318,6 +9563,8 @@ snapshots: - vite - vue + '@one-ini/wasm@0.1.1': {} + '@opentelemetry/api-logs@0.208.0': dependencies: '@opentelemetry/api': 1.9.1 @@ -10164,10 +10411,6 @@ snapshots: dependencies: tslib: 2.8.1 - '@szmarczak/http-timer@4.0.6': - dependencies: - defer-to-connect: 2.0.1 - '@tailwindcss/node@4.2.4': dependencies: '@jridgewell/remapping': 2.3.5 @@ -10237,12 +10480,12 @@ snapshots: postcss: 8.5.10 tailwindcss: 4.2.4 - '@tailwindcss/vite@4.2.4(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))': + '@tailwindcss/vite@4.2.4(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))': dependencies: '@tailwindcss/node': 4.2.4 '@tailwindcss/oxide': 4.2.4 tailwindcss: 4.2.4 - vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3) + vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) '@takumi-rs/core-darwin-arm64@1.1.0': optional: true @@ -10529,39 +10772,32 @@ snapshots: tslib: 2.8.1 optional: true - '@types/cacheable-request@6.0.3': + '@types/chai@5.2.3': dependencies: - '@types/http-cache-semantics': 4.2.0 - '@types/keyv': 3.1.4 - '@types/node': 22.19.17 - '@types/responselike': 1.0.3 + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 '@types/debug@4.1.13': dependencies: '@types/ms': 2.1.0 - '@types/dom-speech-recognition@0.0.1': {} + '@types/deep-eql@4.0.2': {} '@types/esrecurse@4.3.1': {} '@types/estree@1.0.8': {} - '@types/google.maps@3.58.1': {} + '@types/google.maps@3.58.1': + optional: true '@types/hast@3.0.4': dependencies: '@types/unist': 3.0.3 - '@types/hogan.js@3.0.5': {} - - '@types/http-cache-semantics@4.2.0': {} + '@types/js-yaml@4.0.9': {} '@types/json-schema@7.0.15': {} - '@types/keyv@3.1.4': - dependencies: - '@types/node': 22.19.17 - '@types/lodash-es@4.17.12': dependencies: '@types/lodash': 4.17.23 @@ -10582,14 +10818,8 @@ snapshots: dependencies: parse-path: 7.1.0 - '@types/qs@6.14.0': {} - '@types/resolve@1.20.2': {} - '@types/responselike@1.0.3': - dependencies: - '@types/node': 22.19.17 - '@types/trusted-types@2.0.7': optional: true @@ -10601,6 +10831,12 @@ snapshots: '@types/web-bluetooth@0.0.21': {} + '@types/whatwg-mimetype@3.0.2': {} + + '@types/ws@8.18.1': + dependencies: + '@types/node': 22.19.17 + '@typescript-eslint/eslint-plugin@8.59.0(@typescript-eslint/parser@8.59.0(eslint@9.28.0(jiti@2.6.1))(typescript@6.0.3))(eslint@9.28.0(jiti@2.6.1))(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -10694,14 +10930,14 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@unhead/bundler@3.0.5(esbuild@0.27.7)(lightningcss@1.32.0)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(typescript@6.0.3)(unhead@3.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))': + '@unhead/bundler@3.0.5(esbuild@0.27.7)(lightningcss@1.32.0)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(typescript@6.0.3)(unhead@3.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))': dependencies: - '@vitejs/devtools-kit': 0.1.15(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + '@vitejs/devtools-kit': 0.1.15(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) magic-string: 0.30.21 oxc-parser: 0.127.0 oxc-walker: 0.7.0(oxc-parser@0.127.0) ufo: 1.6.3 - unhead: 3.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + unhead: 3.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) unplugin: 3.0.0 optionalDependencies: esbuild: 0.27.7 @@ -10804,12 +11040,12 @@ snapshots: - rollup - supports-color - '@vitejs/devtools-kit@0.1.15(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))': + '@vitejs/devtools-kit@0.1.15(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))': dependencies: '@vitejs/devtools-rpc': 0.1.15(typescript@6.0.3) birpc: 4.0.0 ohash: 2.0.11 - vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3) + vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) transitivePeerDependencies: - bufferutil - typescript @@ -10829,24 +11065,65 @@ snapshots: - typescript - utf-8-validate - '@vitejs/plugin-vue-jsx@5.1.5(rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))': + '@vitejs/plugin-vue-jsx@5.1.5(rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) '@rolldown/pluginutils': 1.0.0-rc.17 '@vue/babel-plugin-jsx': 2.0.1(@babel/core@7.29.0) - vite: rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(yaml@2.8.3) + vite: rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) vue: 3.5.33(typescript@6.0.3) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@6.0.6(rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))': + '@vitejs/plugin-vue@6.0.6(rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.13 - vite: rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(yaml@2.8.3) + vite: rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) vue: 3.5.33(typescript@6.0.3) + '@vitest/expect@4.1.7': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.7 + '@vitest/utils': 4.1.7 + chai: 6.2.2 + tinyrainbow: 3.1.0 + + '@vitest/mocker@4.1.7(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))': + dependencies: + '@vitest/spy': 4.1.7 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + + '@vitest/pretty-format@4.1.7': + dependencies: + tinyrainbow: 3.1.0 + + '@vitest/runner@4.1.7': + dependencies: + '@vitest/utils': 4.1.7 + pathe: 2.0.3 + + '@vitest/snapshot@4.1.7': + dependencies: + '@vitest/pretty-format': 4.1.7 + '@vitest/utils': 4.1.7 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.1.7': {} + + '@vitest/utils@4.1.7': + dependencies: + '@vitest/pretty-format': 4.1.7 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 + '@volar/language-core@2.4.28': dependencies: '@volar/source-map': 2.4.28 @@ -10981,6 +11258,15 @@ snapshots: '@vue/shared@3.5.33': {} + '@vue/test-utils@2.4.10(@vue/compiler-dom@3.5.33)(@vue/server-renderer@3.5.33(vue@3.5.33(typescript@6.0.3)))(vue@3.5.33(typescript@6.0.3))': + dependencies: + '@vue/compiler-dom': 3.5.33 + js-beautify: 1.15.4 + vue: 3.5.33(typescript@6.0.3) + vue-component-type-helpers: 3.2.7 + optionalDependencies: + '@vue/server-renderer': 3.5.33(vue@3.5.33(typescript@6.0.3)) + '@vueuse/core@10.11.1(vue@3.5.33(typescript@6.0.3))': dependencies: '@types/web-bluetooth': 0.0.20 @@ -10998,13 +11284,13 @@ snapshots: '@vueuse/shared': 14.2.1(vue@3.5.33(typescript@6.0.3)) vue: 3.5.33(typescript@6.0.3) - '@vueuse/integrations@14.2.1(axios@1.13.5)(change-case@5.4.4)(fuse.js@7.3.0)(jwt-decode@4.0.0)(vue@3.5.33(typescript@6.0.3))': + '@vueuse/integrations@14.2.1(axios@1.16.1)(change-case@5.4.4)(fuse.js@7.3.0)(jwt-decode@4.0.0)(vue@3.5.33(typescript@6.0.3))': dependencies: '@vueuse/core': 14.2.1(vue@3.5.33(typescript@6.0.3)) '@vueuse/shared': 14.2.1(vue@3.5.33(typescript@6.0.3)) vue: 3.5.33(typescript@6.0.3) optionalDependencies: - axios: 1.13.5 + axios: 1.16.1 change-case: 5.4.4 fuse.js: 7.3.0 jwt-decode: 4.0.0 @@ -11013,13 +11299,13 @@ snapshots: '@vueuse/metadata@14.2.1': {} - '@vueuse/nuxt@14.2.1(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))': + '@vueuse/nuxt@14.2.1(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))': dependencies: '@nuxt/kit': 4.4.2(magicast@0.5.2) '@vueuse/core': 14.2.1(vue@3.5.33(typescript@6.0.3)) '@vueuse/metadata': 14.2.1 local-pkg: 1.1.2 - nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3) + nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0) vue: 3.5.33(typescript@6.0.3) transitivePeerDependencies: - magicast @@ -11070,7 +11356,7 @@ snapshots: tslib: 2.8.1 optional: true - abbrev@1.1.1: {} + abbrev@2.0.0: {} abbrev@3.0.1: {} @@ -11090,6 +11376,12 @@ snapshots: acorn@8.16.0: {} + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + agent-base@7.1.4: {} ajv@6.14.0: @@ -11099,29 +11391,6 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - algoliasearch-helper@3.27.0(algoliasearch@4.25.3): - dependencies: - '@algolia/events': 4.0.1 - algoliasearch: 4.25.3 - - algoliasearch@4.25.3: - dependencies: - '@algolia/cache-browser-local-storage': 4.25.3 - '@algolia/cache-common': 4.25.3 - '@algolia/cache-in-memory': 4.25.3 - '@algolia/client-account': 4.25.3 - '@algolia/client-analytics': 4.25.3 - '@algolia/client-common': 4.25.3 - '@algolia/client-personalization': 4.25.3 - '@algolia/client-search': 4.25.3 - '@algolia/logger-common': 4.25.3 - '@algolia/logger-console': 4.25.3 - '@algolia/recommend': 4.25.3 - '@algolia/requester-browser-xhr': 4.25.3 - '@algolia/requester-common': 4.25.3 - '@algolia/requester-node-http': 4.25.3 - '@algolia/transporter': 4.25.3 - alien-signals@3.1.2: {} ansi-regex@5.0.1: {} @@ -11167,12 +11436,18 @@ snapshots: are-docs-informative@0.0.2: {} + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + argparse@2.0.1: {} aria-hidden@1.2.6: dependencies: tslib: 2.8.1 + assertion-error@2.0.1: {} + ast-kit@2.2.0: dependencies: '@babel/parser': 7.29.2 @@ -11204,13 +11479,15 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 - axios@1.13.5: + axios@1.16.1: dependencies: - follow-redirects: 1.15.11 + follow-redirects: 1.16.0 form-data: 4.0.5 - proxy-from-env: 1.1.0 + https-proxy-agent: 5.0.1 + proxy-from-env: 2.1.0 transitivePeerDependencies: - debug + - supports-color b4a@1.8.0: {} @@ -11335,7 +11612,7 @@ snapshots: chokidar: 5.0.0 confbox: 0.2.4 defu: 6.1.4 - dotenv: 17.2.4 + dotenv: 17.4.2 exsolve: 1.0.8 giget: 2.0.0 jiti: 2.6.1 @@ -11368,18 +11645,6 @@ snapshots: cac@7.0.0: {} - cacheable-lookup@5.0.4: {} - - cacheable-request@7.0.4: - dependencies: - clone-response: 1.0.3 - get-stream: 5.2.0 - http-cache-semantics: 4.2.0 - keyv: 4.5.4 - lowercase-keys: 2.0.0 - normalize-url: 6.1.0 - responselike: 2.0.1 - call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -11413,6 +11678,8 @@ snapshots: ccount@2.0.1: {} + chai@6.2.2: {} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -11474,10 +11741,6 @@ snapshots: strip-ansi: 7.2.0 wrap-ansi: 9.0.2 - clone-response@1.0.3: - dependencies: - mimic-response: 1.0.1 - cluster-key-slot@1.1.2: {} color-convert@2.0.1: @@ -11494,6 +11757,8 @@ snapshots: comma-separated-tokens@2.0.3: {} + commander@10.0.1: {} + commander@11.1.0: {} commander@2.20.3: {} @@ -11518,6 +11783,11 @@ snapshots: confbox@0.2.4: {} + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + consola@3.4.2: {} convert-source-map@2.0.0: {} @@ -11679,8 +11949,6 @@ snapshots: bundle-name: 4.1.0 default-browser-id: 5.0.1 - defer-to-connect@2.0.1: {} - define-data-property@1.1.4: dependencies: es-define-property: 1.0.1 @@ -11729,8 +11997,6 @@ snapshots: dependencies: domelementtype: 2.3.0 - domino@2.1.6: {} - dompurify@3.4.1: optionalDependencies: '@types/trusted-types': 2.0.7 @@ -11750,8 +12016,6 @@ snapshots: type-fest: 4.41.0 optional: true - dotenv@17.2.4: {} - dotenv@17.4.2: {} dunder-proto@1.0.1: @@ -11764,6 +12028,13 @@ snapshots: eastasianwidth@0.2.0: {} + editorconfig@1.0.7: + dependencies: + '@one-ini/wasm': 0.1.1 + commander: 10.0.1 + minimatch: 9.0.9 + semver: 7.7.4 + ee-first@1.1.1: {} electron-to-chromium@1.5.344: {} @@ -11820,6 +12091,7 @@ snapshots: end-of-stream@1.4.5: dependencies: once: 1.4.0 + optional: true engine.io-client@6.6.4: dependencies: @@ -11870,7 +12142,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 has-tostringtag: 1.0.2 - hasown: 2.0.2 + hasown: 2.0.3 esbuild@0.27.7: optionalDependencies: @@ -11901,6 +12173,35 @@ snapshots: '@esbuild/win32-ia32': 0.27.7 '@esbuild/win32-x64': 0.27.7 + esbuild@0.28.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.0 + '@esbuild/android-arm': 0.28.0 + '@esbuild/android-arm64': 0.28.0 + '@esbuild/android-x64': 0.28.0 + '@esbuild/darwin-arm64': 0.28.0 + '@esbuild/darwin-x64': 0.28.0 + '@esbuild/freebsd-arm64': 0.28.0 + '@esbuild/freebsd-x64': 0.28.0 + '@esbuild/linux-arm': 0.28.0 + '@esbuild/linux-arm64': 0.28.0 + '@esbuild/linux-ia32': 0.28.0 + '@esbuild/linux-loong64': 0.28.0 + '@esbuild/linux-mips64el': 0.28.0 + '@esbuild/linux-ppc64': 0.28.0 + '@esbuild/linux-riscv64': 0.28.0 + '@esbuild/linux-s390x': 0.28.0 + '@esbuild/linux-x64': 0.28.0 + '@esbuild/netbsd-arm64': 0.28.0 + '@esbuild/netbsd-x64': 0.28.0 + '@esbuild/openbsd-arm64': 0.28.0 + '@esbuild/openbsd-x64': 0.28.0 + '@esbuild/openharmony-arm64': 0.28.0 + '@esbuild/sunos-x64': 0.28.0 + '@esbuild/win32-arm64': 0.28.0 + '@esbuild/win32-ia32': 0.28.0 + '@esbuild/win32-x64': 0.28.0 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -12102,6 +12403,8 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.16.0) eslint-visitor-keys: 5.0.1 + esprima@4.0.1: {} + esquery@1.7.0: dependencies: estraverse: 5.3.0 @@ -12147,10 +12450,18 @@ snapshots: expand-template@2.0.3: optional: true + expect-type@1.3.0: {} + exsolve@1.0.8: {} + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + extend@3.0.2: {} + fake-indexeddb@6.2.5: {} + fast-deep-equal@3.1.3: {} fast-fifo@1.3.2: {} @@ -12248,7 +12559,7 @@ snapshots: flatted@3.4.2: {} - follow-redirects@1.15.11: {} + follow-redirects@1.16.0: {} fontaine@0.8.0: dependencies: @@ -12264,7 +12575,7 @@ snapshots: dependencies: tiny-inflate: 1.0.3 - fontless@0.2.1(@netlify/blobs@9.1.2)(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)): + fontless@0.2.1(@netlify/blobs@9.1.2)(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)): dependencies: consola: 3.4.2 css-tree: 3.2.1 @@ -12280,7 +12591,7 @@ snapshots: unifont: 0.7.4 unstorage: 1.17.5(@netlify/blobs@9.1.2)(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1) optionalDependencies: - vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3) + vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -12316,7 +12627,7 @@ snapshots: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 - hasown: 2.0.2 + hasown: 2.0.3 mime-types: 2.1.35 formdata-polyfill@4.0.10: @@ -12372,10 +12683,6 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 - get-stream@5.2.0: - dependencies: - pump: 3.0.3 - get-stream@8.0.1: {} get-tsconfig@4.14.0: @@ -12451,22 +12758,15 @@ snapshots: gopd@1.2.0: {} - got@11.8.6: - dependencies: - '@sindresorhus/is': 4.6.0 - '@szmarczak/http-timer': 4.0.6 - '@types/cacheable-request': 6.0.3 - '@types/responselike': 1.0.3 - cacheable-lookup: 5.0.4 - cacheable-request: 7.0.4 - decompress-response: 6.0.0 - http2-wrapper: 1.0.3 - lowercase-keys: 2.0.0 - p-cancelable: 2.1.1 - responselike: 2.0.1 - graceful-fs@4.2.11: {} + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.2 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + gzip-size@7.0.0: dependencies: duplexer: 0.1.2 @@ -12483,6 +12783,25 @@ snapshots: ufo: 1.6.3 uncrypto: 0.1.3 + h3@2.0.1-rc.20(crossws@0.4.5(srvx@0.11.15)): + dependencies: + rou3: 0.8.1 + srvx: 0.11.15 + optionalDependencies: + crossws: 0.4.5(srvx@0.11.15) + + happy-dom@20.9.0: + dependencies: + '@types/node': 22.19.17 + '@types/whatwg-mimetype': 3.0.2 + '@types/ws': 8.18.1 + entities: 7.0.1 + whatwg-mimetype: 3.0.0 + ws: 8.20.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + has-flag@4.0.0: {} has-property-descriptors@1.0.2: @@ -12647,25 +12966,16 @@ snapshots: hey-listen@1.0.8: {} - hogan.js@3.0.2: - dependencies: - mkdirp: 0.3.0 - nopt: 1.0.10 - hookable@5.5.3: {} hookable@6.1.1: {} - htm@3.1.1: {} - html-entities@2.6.0: {} html-void-elements@3.0.0: {} html-whitespace-sensitive-tag-names@3.0.1: {} - http-cache-semantics@4.2.0: {} - http-errors@2.0.1: dependencies: depd: 2.0.0 @@ -12676,10 +12986,12 @@ snapshots: http-shutdown@1.2.2: {} - http2-wrapper@1.0.3: + https-proxy-agent@5.0.1: dependencies: - quick-lru: 5.1.1 - resolve-alpn: 1.2.1 + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color https-proxy-agent@7.0.6: dependencies: @@ -12721,41 +13033,10 @@ snapshots: inherits@2.0.4: {} - ini@1.3.8: - optional: true + ini@1.3.8: {} ini@4.1.1: {} - instantsearch-ui-components@0.17.1(react@19.2.4): - dependencies: - '@babel/runtime': 7.28.6 - markdown-to-jsx: 7.7.17(react@19.2.4) - zod: 4.3.6 - zod-to-json-schema: 3.24.6(zod@4.3.6) - transitivePeerDependencies: - - react - - instantsearch.css@7.4.5: {} - - instantsearch.js@4.87.1(algoliasearch@4.25.3): - dependencies: - '@algolia/events': 4.0.1 - '@types/dom-speech-recognition': 0.0.1 - '@types/google.maps': 3.58.1 - '@types/hogan.js': 3.0.5 - '@types/qs': 6.14.0 - algoliasearch: 4.25.3 - algoliasearch-helper: 3.27.0(algoliasearch@4.25.3) - hogan.js: 3.0.2 - htm: 3.1.1 - instantsearch-ui-components: 0.17.1(react@19.2.4) - preact: 10.28.3 - qs: 6.14.1 - react: 19.2.4 - search-insights: 2.17.3 - zod: 4.3.6 - zod-to-json-schema: 3.24.6(zod@4.3.6) - ioredis@5.10.1: dependencies: '@ioredis/commands': 1.5.1 @@ -12797,6 +13078,8 @@ snapshots: is-docker@3.0.0: {} + is-extendable@0.1.1: {} + is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -12882,10 +13165,25 @@ snapshots: jiti@2.6.1: {} + js-beautify@1.15.4: + dependencies: + config-chain: 1.1.13 + editorconfig: 1.0.7 + glob: 10.5.0 + js-cookie: 3.0.7 + nopt: 7.2.1 + + js-cookie@3.0.7: {} + js-tokens@4.0.0: {} js-tokens@9.0.1: {} + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + js-yaml@4.1.1: dependencies: argparse: 2.0.1 @@ -12914,6 +13212,8 @@ snapshots: dependencies: json-buffer: 3.0.1 + kind-of@6.0.3: {} + kleur@4.1.5: {} klona@2.0.6: {} @@ -13059,6 +13359,8 @@ snapshots: lodash@4.18.1: {} + loglevel@1.9.2: {} + logs-sdk@0.0.6: dependencies: magic-string: 0.30.21 @@ -13069,8 +13371,6 @@ snapshots: longest-streak@3.1.0: {} - lowercase-keys@2.0.0: {} - lru-cache@10.4.3: {} lru-cache@11.3.5: {} @@ -13105,10 +13405,6 @@ snapshots: markdown-table@3.0.4: {} - markdown-to-jsx@7.7.17(react@19.2.4): - optionalDependencies: - react: 19.2.4 - marked@17.0.6: {} marky@1.3.0: {} @@ -13237,11 +13533,6 @@ snapshots: merge2@1.4.1: {} - metadata-scraper@0.2.61: - dependencies: - domino: 2.1.6 - got: 11.8.6 - micro-api-client@3.3.0: optional: true @@ -13457,8 +13748,6 @@ snapshots: mimic-fn@4.0.0: {} - mimic-response@1.0.1: {} - mimic-response@3.1.0: {} minimark@0.2.0: {} @@ -13491,13 +13780,9 @@ snapshots: dependencies: minipass: 7.1.3 - mitt@2.1.0: {} - mkdirp-classic@0.5.3: optional: true - mkdirp@0.3.0: {} - mlly@1.8.0: dependencies: acorn: 8.15.0 @@ -13702,9 +13987,9 @@ snapshots: node-releases@2.0.38: {} - nopt@1.0.10: + nopt@7.2.1: dependencies: - abbrev: 1.1.1 + abbrev: 2.0.0 nopt@8.1.0: dependencies: @@ -13712,8 +13997,6 @@ snapshots: normalize-path@3.0.0: {} - normalize-url@6.1.0: {} - npm-run-path@5.3.0: dependencies: path-key: 4.0.0 @@ -13740,7 +14023,7 @@ snapshots: transitivePeerDependencies: - magicast - nuxt-link-checker@5.0.9(ad3672cc71ed4fef9dee73a54522c31c): + nuxt-link-checker@5.0.9(89533da900856b60956b41a60a77ded0): dependencies: '@nuxt/kit': 4.4.2(magicast@0.5.2) '@vueuse/core': 14.2.1(vue@3.5.33(typescript@6.0.3)) @@ -13748,9 +14031,9 @@ snapshots: diff: 8.0.4 fuse.js: 7.3.0 magic-string: 0.30.21 - nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3) - nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))(zod@4.3.6) - nuxtseo-shared: 5.1.3(25023e8fc1951fd485d95c7642f63f09) + nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0) + nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))(zod@3.25.76) + nuxtseo-shared: 5.1.3(831cc79224bc9108dd0c9e6e36ee323c) ofetch: 1.5.1 pathe: 2.0.3 pkg-types: 2.3.0 @@ -13790,7 +14073,7 @@ snapshots: transitivePeerDependencies: - magicast - nuxt-og-image@6.4.7(9fe474218c97b47f30882881f0852e2d): + nuxt-og-image@6.4.7(0119389412a87344d59ece639bed8fe3): dependencies: '@clack/prompts': 1.2.0 '@nuxt/kit': 4.4.2(magicast@0.5.2) @@ -13806,8 +14089,8 @@ snapshots: magic-string: 0.30.21 magicast: 0.5.2 mocked-exports: 0.1.1 - nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))(zod@4.3.6) - nuxtseo-shared: 5.1.3(25023e8fc1951fd485d95c7642f63f09) + nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))(zod@3.25.76) + nuxtseo-shared: 5.1.3(831cc79224bc9108dd0c9e6e36ee323c) nypm: 0.6.5 ofetch: 1.5.1 ohash: 2.0.11 @@ -13828,7 +14111,7 @@ snapshots: '@resvg/resvg-js': 2.6.2 '@resvg/resvg-wasm': 2.6.2 '@takumi-rs/core': 1.1.0 - fontless: 0.2.1(@netlify/blobs@9.1.2)(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + fontless: 0.2.1(@netlify/blobs@9.1.2)(db0@0.3.4(better-sqlite3@11.10.0))(ioredis@5.10.1)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) playwright-core: 1.58.2 sharp: 0.34.5 tailwindcss: 4.2.4 @@ -13841,19 +14124,19 @@ snapshots: - vue - zod - nuxt-schema-org@6.0.4(1a967bc97ce9677f66be35b83ed89595): + nuxt-schema-org@6.0.4(6f2234aa98e2ca2e8365a7c7195bb816): dependencies: '@nuxt/kit': 4.4.2(magicast@0.5.2) '@unhead/schema-org': 2.1.13(@unhead/vue@2.1.13(vue@3.5.33(typescript@6.0.3))) defu: 6.1.7 - nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))(zod@4.3.6) - nuxtseo-layer-devtools: 0.5.1(cfaa4fba2806ba2371a648f1cb68ae6a) - nuxtseo-shared: 0.9.0(25023e8fc1951fd485d95c7642f63f09) + nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))(zod@3.25.76) + nuxtseo-layer-devtools: 0.5.1(786243892090eb7a39cef94b013cf011) + nuxtseo-shared: 0.9.0(831cc79224bc9108dd0c9e6e36ee323c) pkg-types: 2.3.0 optionalDependencies: '@unhead/vue': 2.1.13(vue@3.5.33(typescript@6.0.3)) - unhead: 3.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) - zod: 4.3.6 + unhead: 3.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) + zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13910,18 +14193,18 @@ snapshots: - yjs - yup - nuxt-seo-utils@8.1.11(afd1536e353fe9aacca1e8172ba75d16): + nuxt-seo-utils@8.1.11(f3ac38eccaefb2e9ee66d9006f0b5502): dependencies: '@nuxt/kit': 4.4.2(magicast@0.5.2) - '@unhead/bundler': 3.0.5(esbuild@0.27.7)(lightningcss@1.32.0)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(typescript@6.0.3)(unhead@3.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + '@unhead/bundler': 3.0.5(esbuild@0.27.7)(lightningcss@1.32.0)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(typescript@6.0.3)(unhead@3.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) citty: 0.2.2 defu: 6.1.7 escape-string-regexp: 5.0.0 exsolve: 1.0.8 image-size: 2.0.2 - nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3) - nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))(zod@4.3.6) - nuxtseo-shared: 5.1.3(25023e8fc1951fd485d95c7642f63f09) + nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0) + nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))(zod@3.25.76) + nuxtseo-shared: 5.1.3(831cc79224bc9108dd0c9e6e36ee323c) pathe: 2.0.3 pkg-types: 2.3.0 scule: 1.3.0 @@ -13953,12 +14236,12 @@ snapshots: - magicast - vue - nuxt-site-config@4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))(zod@4.3.6): + nuxt-site-config@4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))(zod@3.25.76): dependencies: '@nuxt/kit': 4.4.2(magicast@0.5.2) h3: 1.15.11 nuxt-site-config-kit: 4.0.8(magicast@0.5.2)(vue@3.5.33(typescript@6.0.3)) - nuxtseo-shared: 5.1.3(25023e8fc1951fd485d95c7642f63f09) + nuxtseo-shared: 5.1.3(831cc79224bc9108dd0c9e6e36ee323c) pathe: 2.0.3 pkg-types: 2.3.0 site-config-stack: 4.0.8(vue@3.5.33(typescript@6.0.3)) @@ -13971,16 +14254,16 @@ snapshots: - vue - zod - nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3): + nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0): dependencies: '@dxup/nuxt': 0.4.1(magicast@0.5.2)(typescript@6.0.3) '@nuxt/cli': 3.34.0(@nuxt/schema@4.4.2)(cac@6.7.14)(magicast@0.5.2) - '@nuxt/devtools': 3.2.4(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3)) + '@nuxt/devtools': 3.2.4(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3)) '@nuxt/kit': 4.4.2(magicast@0.5.2) - '@nuxt/nitro-server': 4.4.2(b200ed249053ecb3871c92755e06a756) + '@nuxt/nitro-server': 4.4.2(d8bfb31b08d32093c0f73363b4b5ece1) '@nuxt/schema': 4.4.2 '@nuxt/telemetry': 2.8.0(@nuxt/kit@4.4.2(magicast@0.5.2)) - '@nuxt/vite-builder': 4.4.2(40ef2daf26488a39f37e42046efdfe2d) + '@nuxt/vite-builder': 4.4.2(7c2c1dd7c498c9a3b536bcb4959772f5) '@unhead/vue': 2.1.13(vue@3.5.33(typescript@6.0.3)) '@vue/shared': 3.5.33 c12: 3.3.4(magicast@0.5.2) @@ -14104,15 +14387,15 @@ snapshots: - xml2js - yaml - nuxtseo-layer-devtools@0.5.1(cfaa4fba2806ba2371a648f1cb68ae6a): + nuxtseo-layer-devtools@0.5.1(786243892090eb7a39cef94b013cf011): dependencies: - '@nuxt/devtools-kit': 4.0.0-alpha.3(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + '@nuxt/devtools-kit': 4.0.0-alpha.3(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) '@nuxt/kit': 4.4.2(magicast@0.5.2) - '@nuxt/ui': 4.6.1(@netlify/blobs@9.1.2)(@nuxt/content@3.13.0(better-sqlite3@11.10.0)(magicast@0.5.2)(valibot@1.3.1(typescript@6.0.3)))(@tiptap/extensions@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@tiptap/y-tiptap@3.0.3(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))(axios@1.13.5)(change-case@5.4.4)(db0@0.3.4(better-sqlite3@11.10.0))(embla-carousel@8.6.0)(ioredis@5.10.1)(jwt-decode@4.0.0)(magicast@0.5.2)(tailwindcss@4.2.4)(typescript@6.0.3)(valibot@1.3.1(typescript@6.0.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-router@5.0.6(@vue/compiler-sfc@3.5.33)(vue@3.5.33(typescript@6.0.3)))(vue@3.5.33(typescript@6.0.3))(yjs@13.6.30)(zod@4.3.6) + '@nuxt/ui': 4.6.1(@netlify/blobs@9.1.2)(@nuxt/content@3.13.0(better-sqlite3@11.10.0)(magicast@0.5.2)(valibot@1.3.1(typescript@6.0.3)))(@tiptap/extensions@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))(@tiptap/y-tiptap@3.0.3(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))(axios@1.16.1)(change-case@5.4.4)(db0@0.3.4(better-sqlite3@11.10.0))(embla-carousel@8.6.0)(ioredis@5.10.1)(jwt-decode@4.0.0)(magicast@0.5.2)(tailwindcss@4.2.4)(typescript@6.0.3)(valibot@1.3.1(typescript@6.0.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-router@5.0.6(@vue/compiler-sfc@3.5.33)(vue@3.5.33(typescript@6.0.3)))(vue@3.5.33(typescript@6.0.3))(yjs@13.6.30)(zod@3.25.76) '@shikijs/langs': 4.0.2 '@shikijs/themes': 4.0.2 - '@vueuse/nuxt': 14.2.1(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3)) - nuxtseo-shared: 0.9.0(25023e8fc1951fd485d95c7642f63f09) + '@vueuse/nuxt': 14.2.1(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3)) + nuxtseo-shared: 0.9.0(831cc79224bc9108dd0c9e6e36ee323c) ofetch: 1.5.1 shiki: 4.0.2 ufo: 1.6.3 @@ -14171,16 +14454,16 @@ snapshots: - yup - zod - nuxtseo-shared@0.9.0(25023e8fc1951fd485d95c7642f63f09): + nuxtseo-shared@0.9.0(831cc79224bc9108dd0c9e6e36ee323c): dependencies: '@clack/prompts': 1.2.0 - '@nuxt/devtools-kit': 4.0.0-alpha.3(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + '@nuxt/devtools-kit': 4.0.0-alpha.3(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) '@nuxt/kit': 4.4.2(magicast@0.5.2) '@nuxt/schema': 4.4.2 birpc: 4.0.0 consola: 3.4.2 defu: 6.1.7 - nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3) + nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0) ofetch: 1.5.1 pathe: 2.0.3 pkg-types: 2.3.0 @@ -14190,22 +14473,22 @@ snapshots: ufo: 1.6.3 vue: 3.5.33(typescript@6.0.3) optionalDependencies: - nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))(zod@4.3.6) - zod: 4.3.6 + nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))(zod@3.25.76) + zod: 3.25.76 transitivePeerDependencies: - magicast - vite - nuxtseo-shared@5.1.3(25023e8fc1951fd485d95c7642f63f09): + nuxtseo-shared@5.1.3(831cc79224bc9108dd0c9e6e36ee323c): dependencies: '@clack/prompts': 1.2.0 - '@nuxt/devtools-kit': 4.0.0-alpha.3(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + '@nuxt/devtools-kit': 4.0.0-alpha.3(magicast@0.5.2)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) '@nuxt/kit': 4.4.2(magicast@0.5.2) '@nuxt/schema': 4.4.2 birpc: 4.0.0 consola: 3.4.2 defu: 6.1.7 - nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3) + nuxt: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0) ofetch: 1.5.1 pathe: 2.0.3 pkg-types: 2.3.0 @@ -14215,8 +14498,8 @@ snapshots: ufo: 1.6.3 vue: 3.5.33(typescript@6.0.3) optionalDependencies: - nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.8.3))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3))(zod@4.3.6) - zod: 4.3.6 + nuxt-site-config: 4.0.8(@nuxt/schema@4.4.2)(magicast@0.5.2)(nuxt@4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.33)(better-sqlite3@11.10.0)(cac@6.7.14)(db0@0.3.4(better-sqlite3@11.10.0))(esbuild@0.27.7)(eslint@9.28.0(jiti@2.6.1))(ioredis@5.10.1)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-beta.53(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(rollup@4.60.2))(rollup@4.60.2)(srvx@0.11.15)(terser@5.46.2)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.2.7(typescript@6.0.3))(yaml@2.9.0))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3))(zod@3.25.76) + zod: 3.25.76 transitivePeerDependencies: - magicast - vite @@ -14227,9 +14510,16 @@ snapshots: pathe: 2.0.3 tinyexec: 1.0.2 + nypm@0.6.6: + dependencies: + citty: 0.2.2 + pathe: 2.0.3 + tinyexec: 1.1.1 + object-deep-merge@2.0.0: {} - object-inspect@1.13.4: {} + object-inspect@1.13.4: + optional: true obug@2.1.1: {} @@ -14436,8 +14726,6 @@ snapshots: magic-regexp: 0.10.0 oxc-parser: 0.127.0 - p-cancelable@2.1.1: {} - p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -14760,8 +15048,6 @@ snapshots: powershell-utils@0.1.0: {} - preact@10.28.3: {} - preact@10.29.1: {} prebuild-install@7.1.3: @@ -14859,6 +15145,8 @@ snapshots: prosemirror-state: 1.4.4 prosemirror-transform: 1.12.0 + proto-list@1.2.4: {} + protobufjs@7.5.5: dependencies: '@protobufjs/aspromise': 1.1.2 @@ -14876,12 +15164,7 @@ snapshots: protocols@2.0.2: {} - proxy-from-env@1.1.0: {} - - pump@3.0.3: - dependencies: - end-of-stream: 1.4.5 - once: 1.4.0 + proxy-from-env@2.1.0: {} pump@3.0.4: dependencies: @@ -14891,10 +15174,6 @@ snapshots: punycode@2.3.1: {} - qs@6.14.1: - dependencies: - side-channel: 1.1.0 - qs@6.15.1: dependencies: side-channel: 1.1.0 @@ -14906,8 +15185,6 @@ snapshots: queue-microtask@1.2.3: {} - quick-lru@5.1.1: {} - radix3@1.1.2: {} range-parser@1.2.1: {} @@ -14935,8 +15212,6 @@ snapshots: strip-json-comments: 2.0.1 optional: true - react@19.2.4: {} - readable-stream@2.3.8: dependencies: core-util-is: 1.0.3 @@ -15083,7 +15358,7 @@ snapshots: transitivePeerDependencies: - supports-color - remark-mdc@3.10.0: + remark-mdc@3.11.0: dependencies: '@types/mdast': 4.0.4 '@types/unist': 3.0.3 @@ -15102,7 +15377,7 @@ snapshots: unified: 11.0.5 unist-util-visit: 5.1.0 unist-util-visit-parents: 6.0.2 - yaml: 2.8.3 + yaml: 2.9.0 transitivePeerDependencies: - supports-color @@ -15129,9 +15404,16 @@ snapshots: mdast-util-to-markdown: 2.1.2 unified: 11.0.5 - reserved-identifiers@1.2.0: {} + remark@15.0.1: + dependencies: + '@types/mdast': 4.0.4 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color - resolve-alpn@1.2.1: {} + reserved-identifiers@1.2.0: {} resolve-from@4.0.0: {} @@ -15146,13 +15428,9 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - responselike@2.0.1: - dependencies: - lowercase-keys: 2.0.0 - reusify@1.1.0: {} - rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(yaml@2.8.3): + rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0): dependencies: '@oxc-project/runtime': 0.101.0 fdir: 6.5.0(picomatch@4.0.4) @@ -15167,7 +15445,8 @@ snapshots: fsevents: 2.3.3 jiti: 2.6.1 terser: 5.46.2 - yaml: 2.8.3 + tsx: 4.22.3 + yaml: 2.9.0 transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' @@ -15259,7 +15538,10 @@ snapshots: scule@1.3.0: {} - search-insights@2.17.3: {} + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 semver@6.3.1: {} @@ -15369,6 +15651,7 @@ snapshots: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 + optional: true side-channel-map@1.0.1: dependencies: @@ -15376,6 +15659,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 object-inspect: 1.13.4 + optional: true side-channel-weakmap@1.0.2: dependencies: @@ -15384,6 +15668,7 @@ snapshots: get-intrinsic: 1.3.0 object-inspect: 1.13.4 side-channel-map: 1.0.1 + optional: true side-channel@1.1.0: dependencies: @@ -15392,6 +15677,9 @@ snapshots: side-channel-list: 1.0.0 side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + optional: true + + siginfo@2.0.0: {} signal-exit@4.1.0: {} @@ -15476,10 +15764,14 @@ snapshots: spdx-license-ids@3.0.23: {} + sprintf-js@1.0.3: {} + srvx@0.11.15: {} stable-hash-x@0.2.0: {} + stackback@0.0.2: {} + standard-as-callback@2.1.0: {} statuses@2.0.2: {} @@ -15488,16 +15780,6 @@ snapshots: std-env@4.1.0: {} - storyblok-algolia-indexer@1.1.0: - dependencies: - algoliasearch: 4.25.3 - axios: 1.13.5 - storyblok-js-client: 5.14.4 - transitivePeerDependencies: - - debug - - storyblok-js-client@5.14.4: {} - streamx@2.25.0: dependencies: events-universal: 1.0.1 @@ -15546,6 +15828,8 @@ snapshots: dependencies: ansi-regex: 6.2.2 + strip-bom-string@1.0.0: {} + strip-final-newline@3.0.0: {} strip-indent@4.1.1: {} @@ -15661,6 +15945,8 @@ snapshots: tiny-invariant@1.3.3: {} + tinybench@2.9.0: {} + tinyclip@0.1.12: {} tinyexec@1.0.2: {} @@ -15677,6 +15963,8 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 + tinyrainbow@3.1.0: {} + to-buffer@1.2.2: dependencies: isarray: 2.0.5 @@ -15710,6 +15998,12 @@ snapshots: tslib@2.8.1: {} + tsx@4.22.3: + dependencies: + esbuild: 0.28.0 + optionalDependencies: + fsevents: 2.3.3 + tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 @@ -15738,6 +16032,16 @@ snapshots: typescript@6.0.3: {} + typesense@3.0.6(@babel/runtime@7.29.2): + dependencies: + '@babel/runtime': 7.29.2 + axios: 1.16.1 + loglevel: 1.9.2 + tslib: 2.8.1 + transitivePeerDependencies: + - debug + - supports-color + ufo@1.6.3: {} ultrahtml@1.6.0: {} @@ -15761,12 +16065,12 @@ snapshots: dependencies: hookable: 6.1.1 - unhead@3.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)): + unhead@3.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)): dependencies: hookable: 6.1.1 unplugin: 3.0.0 optionalDependencies: - vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3) + vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) unicode-emoji-modifier-base@1.0.0: {} @@ -16018,23 +16322,23 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-dev-rpc@1.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)): + vite-dev-rpc@1.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)): dependencies: birpc: 2.9.0 - vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3) - vite-hot-client: 2.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + vite-hot-client: 2.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) - vite-hot-client@2.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)): + vite-hot-client@2.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)): dependencies: - vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3) + vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) - vite-node@5.3.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(yaml@2.8.3): + vite-node@5.3.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0): dependencies: cac: 6.7.14 es-module-lexer: 2.0.0 obug: 2.1.1 pathe: 2.0.3 - vite: rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(yaml@2.8.3) + vite: rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' @@ -16050,7 +16354,7 @@ snapshots: - tsx - yaml - vite-plugin-checker@0.12.0(eslint@9.28.0(jiti@2.6.1))(optionator@0.9.4)(rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(yaml@2.8.3))(typescript@6.0.3)(vue-tsc@3.2.7(typescript@6.0.3)): + vite-plugin-checker@0.12.0(eslint@9.28.0(jiti@2.6.1))(optionator@0.9.4)(rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(typescript@6.0.3)(vue-tsc@3.2.7(typescript@6.0.3)): dependencies: '@babel/code-frame': 7.29.0 chokidar: 4.0.3 @@ -16059,7 +16363,7 @@ snapshots: picomatch: 4.0.4 tiny-invariant: 1.3.3 tinyglobby: 0.2.16 - vite: rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(yaml@2.8.3) + vite: rolldown-vite@7.3.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@22.19.17)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) vscode-uri: 3.1.0 optionalDependencies: eslint: 9.28.0(jiti@2.6.1) @@ -16067,7 +16371,7 @@ snapshots: typescript: 6.0.3 vue-tsc: 3.2.7(typescript@6.0.3) - vite-plugin-inspect@11.3.3(@nuxt/kit@4.4.2(magicast@0.5.2))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)): + vite-plugin-inspect@11.3.3(@nuxt/kit@4.4.2(magicast@0.5.2))(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)): dependencies: ansis: 4.2.0 debug: 4.4.1 @@ -16077,24 +16381,24 @@ snapshots: perfect-debounce: 2.1.0 sirv: 3.0.2 unplugin-utils: 0.3.1 - vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3) - vite-dev-rpc: 1.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3)) + vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + vite-dev-rpc: 1.1.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) optionalDependencies: '@nuxt/kit': 4.4.2(magicast@0.5.2) transitivePeerDependencies: - supports-color - vite-plugin-vue-tracer@1.3.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3))(vue@3.5.33(typescript@6.0.3)): + vite-plugin-vue-tracer@1.3.0(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.33(typescript@6.0.3)): dependencies: estree-walker: 3.0.3 exsolve: 1.0.8 magic-string: 0.30.21 pathe: 2.0.3 source-map-js: 1.2.1 - vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3) + vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) vue: 3.5.33(typescript@6.0.3) - vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.3): + vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0): dependencies: esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.4) @@ -16108,7 +16412,56 @@ snapshots: jiti: 2.6.1 lightningcss: 1.32.0 terser: 5.46.2 - yaml: 2.8.3 + tsx: 4.22.3 + yaml: 2.9.0 + + vitest-environment-nuxt@2.0.0(@vue/test-utils@2.4.10(@vue/compiler-dom@3.5.33)(@vue/server-renderer@3.5.33(vue@3.5.33(typescript@6.0.3)))(vue@3.5.33(typescript@6.0.3)))(crossws@0.4.5(srvx@0.11.15))(happy-dom@20.9.0)(magicast@0.5.2)(playwright-core@1.58.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vitest@4.1.7(@opentelemetry/api@1.9.1)(@types/node@22.19.17)(happy-dom@20.9.0)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))): + dependencies: + '@nuxt/test-utils': 4.0.3(@vue/test-utils@2.4.10(@vue/compiler-dom@3.5.33)(@vue/server-renderer@3.5.33(vue@3.5.33(typescript@6.0.3)))(vue@3.5.33(typescript@6.0.3)))(crossws@0.4.5(srvx@0.11.15))(happy-dom@20.9.0)(magicast@0.5.2)(playwright-core@1.58.2)(typescript@6.0.3)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))(vitest@4.1.7(@opentelemetry/api@1.9.1)(@types/node@22.19.17)(happy-dom@20.9.0)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0))) + transitivePeerDependencies: + - '@cucumber/cucumber' + - '@jest/globals' + - '@playwright/test' + - '@testing-library/vue' + - '@vitest/ui' + - '@vue/test-utils' + - crossws + - happy-dom + - jsdom + - magicast + - playwright-core + - typescript + - vite + - vitest + + vitest@4.1.7(@opentelemetry/api@1.9.1)(@types/node@22.19.17)(happy-dom@20.9.0)(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)): + dependencies: + '@vitest/expect': 4.1.7 + '@vitest/mocker': 4.1.7(vite@7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.7 + '@vitest/runner': 4.1.7 + '@vitest/snapshot': 4.1.7 + '@vitest/spy': 4.1.7 + '@vitest/utils': 4.1.7 + es-module-lexer: 2.0.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.1.0 + tinybench: 2.9.0 + tinyexec: 1.1.1 + tinyglobby: 0.2.16 + tinyrainbow: 3.1.0 + vite: 7.3.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.2)(tsx@4.22.3)(yaml@2.9.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@opentelemetry/api': 1.9.1 + '@types/node': 22.19.17 + happy-dom: 20.9.0 + transitivePeerDependencies: + - msw vscode-uri@3.1.0: {} @@ -16144,18 +16497,6 @@ snapshots: transitivePeerDependencies: - supports-color - vue-instantsearch@4.23.1(@vue/server-renderer@3.5.33(vue@3.5.33(typescript@6.0.3)))(algoliasearch@4.25.3)(vue@3.5.33(typescript@6.0.3)): - dependencies: - algoliasearch: 4.25.3 - instantsearch-ui-components: 0.17.1(react@19.2.4) - instantsearch.js: 4.87.1(algoliasearch@4.25.3) - mitt: 2.1.0 - vue: 3.5.33(typescript@6.0.3) - optionalDependencies: - '@vue/server-renderer': 3.5.33(vue@3.5.33(typescript@6.0.3)) - transitivePeerDependencies: - - react - vue-router@5.0.6(@vue/compiler-sfc@3.5.33)(vue@3.5.33(typescript@6.0.3)): dependencies: '@babel/generator': 7.29.1 @@ -16208,6 +16549,8 @@ snapshots: webpack-virtual-modules@0.6.2: {} + whatwg-mimetype@3.0.0: {} + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 @@ -16233,6 +16576,11 @@ snapshots: dependencies: isexe: 4.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + word-wrap@1.2.5: {} wrap-ansi@7.0.0: @@ -16293,6 +16641,8 @@ snapshots: yaml@2.8.3: {} + yaml@2.9.0: {} + yargs-parser@22.0.0: {} yargs@18.0.0: @@ -16331,16 +16681,10 @@ snapshots: compress-commons: 6.0.2 readable-stream: 4.7.0 - zod-to-json-schema@3.24.6(zod@4.3.6): - dependencies: - zod: 4.3.6 - zod-to-json-schema@3.25.2(zod@3.25.76): dependencies: zod: 3.25.76 zod@3.25.76: {} - zod@4.3.6: {} - zwitch@2.0.4: {} diff --git a/scripts/index-docs-chunker.ts b/scripts/index-docs-chunker.ts new file mode 100644 index 000000000..924090fc4 --- /dev/null +++ b/scripts/index-docs-chunker.ts @@ -0,0 +1,612 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import matter from 'gray-matter'; +import { load as loadYaml } from 'js-yaml'; +import { remark } from 'remark'; +import remarkParse from 'remark-parse'; +import remarkMdc from 'remark-mdc'; +import { findSectionByPath } from '../shared/utils/docsSections.ts'; +import slugify from '../app/utils/slugify.ts'; +import { listRoutableContentFiles } from './_content-lib.ts'; + +const CONTENT_DIR = path.resolve('content'); +const PARTIALS_DIR = path.join(CONTENT_DIR, '_partials'); +const MAX_PARTIAL_DEPTH = 8; +const MAX_CHUNK_SIZE = 1500; +const CHUNK_OVERLAP = 150; +const YAML_OPTIONS = { json: true } as const; + +interface MarkdownFrontmatter { + title?: string; + description?: string; + technologies?: string[]; +} + +interface MarkdownSection { + h2?: string; + h3?: string; + textParts: string[]; + codeBlocks: string[]; +} + +interface RawChunk { + url: string; + anchor?: string; + heading?: string; + hierarchy: string[]; + content: string; + code_blocks?: string[]; + weight: number; + level: number; + position: number; +} + +export interface IndexedSearchDocument { + id: string; + group_id: string; + chunk_index: number; + total_chunks: number; + url: string; + title: string; + search_title: string; + description?: string; + anchor?: string; + heading?: string; + hierarchy: string[]; + path_tokens: string; + path_depth: number; + rank_order: number; + section: string; + doc_type: 'page' | 'api-operation' | 'api-tag'; + technologies?: string[]; + content: string; + code_blocks?: string[]; + weight: number; + updated_at: number; + _source_path?: string; +} + +interface ChunkMarkdownPageOptions { + sourcePath: string; + updatedAt: number; + partials: Map; +} + +interface MdastNode { + type: string; + name?: string; + depth?: number; + value?: string; + url?: string; + children?: MdastNode[]; + attributes?: Record; + rawData?: string; +} + +interface ExtractedBlock { + type: 'heading' | 'paragraph' | 'code'; + depth?: number; + text: string; +} + +function stripNumericPrefix(segment: string): string { + return segment.replace(/^\d+\./, ''); +} + +function normalizePublicPath(routePath: string): string { + if (!routePath || routePath === '/') return '/'; + const normalized = `/${routePath.replace(/^\/+/, '').replace(/\/+$/, '')}`; + return normalized === '/index' ? '/' : normalized; +} + +export function contentPathToPublicPath(file: string): string { + const relative = file.replace(/^content\//, ''); + const parts = relative.split('/'); + const fileName = parts.pop() ?? ''; + const fileStem = stripNumericPrefix(fileName.replace(/\.[^.]+$/, '')); + const pathParts = parts.map(stripNumericPrefix).filter(Boolean); + + if (fileStem !== 'index') { + pathParts.push(fileStem); + } + + return normalizePublicPath(`/${pathParts.join('/')}`); +} + +function toSearchUrl(routePath: string, anchor?: string) { + const normalized = routePath === '/' ? '' : routePath; + return `/docs${normalized}${anchor ? `#${anchor}` : ''}` || '/docs'; +} + +const GENERIC_TITLES = new Set(['overview', 'installation', 'security', 'troubleshooting', 'introduction']); +const ACRONYMS: Record = { + ai: 'AI', + api: 'API', + mcp: 'MCP', + sdk: 'SDK', + sso: 'SSO', +}; + +function isGenericTitle(title: string) { + return GENERIC_TITLES.has(title.trim().toLowerCase()); +} + +function humanizeSegment(segment: string) { + return segment + .split('-') + .map(part => ACRONYMS[part.toLowerCase()] ?? `${part.charAt(0).toUpperCase()}${part.slice(1)}`) + .join(' ') + .trim(); +} + +function buildPathTokens(routePath: string, anchor?: string) { + const segments = routePath.split('/').filter(Boolean); + const anchorTokens = anchor ? anchor.split('-') : []; + return [...segments, ...anchorTokens] + .flatMap(segment => segment.split('-')) + .map(segment => segment.trim()) + .filter(Boolean) + .map(segment => ACRONYMS[segment.toLowerCase()] ?? segment) + .join(' '); +} + +function getPathDepth(routePath: string) { + return routePath.split('/').filter(Boolean).length; +} + +function buildRankOrder(routePath: string, level: number, position: number) { + return (getPathDepth(routePath) * 1000) + (level * 100) + position; +} + +function buildPageSearchTitle(routePath: string, title: string) { + if (!isGenericTitle(title)) return title; + const segments = routePath.split('/').filter(Boolean); + const last = segments.at(-1); + const contextSegment = last && !GENERIC_TITLES.has(last) ? last : segments.at(-2); + const contextLabel = contextSegment ? humanizeSegment(contextSegment) : ''; + return contextLabel ? `${contextLabel} ${title}` : title; +} + +function buildChunkSearchTitle(pageSearchTitle: string, heading?: string) { + return heading?.trim() || pageSearchTitle; +} + +function normalizeText(value: string): string { + return value + .replace(/\u00a0/g, ' ') + .replace(/[\t\r ]+/g, ' ') + .replace(/\n{3,}/g, '\n\n') + .trim(); +} + +function normalizeCode(value: string): string { + return value.replace(/\r/g, '').trim(); +} + +function cleanSentence(value: string): string { + return normalizeText(value.replace(/\s+/g, ' ')); +} + +function readPartialFiles(dir = PARTIALS_DIR, prefix = ''): Array<[string, string]> { + if (!fs.existsSync(dir)) return []; + const entries = fs.readdirSync(dir, { withFileTypes: true }); + const partials: Array<[string, string]> = []; + + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + const nextPrefix = prefix ? `${prefix}/${entry.name}` : entry.name; + if (entry.isDirectory()) { + partials.push(...readPartialFiles(fullPath, nextPrefix)); + continue; + } + + if (!entry.isFile() || !entry.name.endsWith('.md')) continue; + const key = nextPrefix.replace(/\.md$/, ''); + const source = fs.readFileSync(fullPath, 'utf8'); + partials.push([key, matter(source, { engines: { yaml: value => loadYaml(value, YAML_OPTIONS) as Record } }).content]); + } + + return partials; +} + +export function loadPartials() { + return new Map(readPartialFiles()); +} + +function resolvePartialContent(name: string, partials: Map): string | null { + const normalized = name.replace(/^\/_partials\//, '').replace(/^_partials\//, '').replace(/\.md$/, ''); + return partials.get(normalized) ?? null; +} + +function parseComponentMeta(rawData?: string, attributes?: Record): string[] { + const values: string[] = []; + const push = (value: unknown) => { + if (typeof value !== 'string') return; + const cleaned = normalizeText(value); + if (cleaned) values.push(cleaned); + }; + + push(attributes?.title); + push(attributes?.description); + push(attributes?.label); + push(attributes?.command); + + if (rawData) { + const cleanedRaw = rawData + .replace(/^-+\s*/, '') + .replace(/\s*-+\s*$/, '') + .split('\n') + .map(line => line.replace(/^\s{2}/, '')) + .join('\n') + .trim(); + if (cleanedRaw) { + const parsed = loadYaml(cleanedRaw) as Record | undefined; + push(parsed?.title); + push(parsed?.description); + push(parsed?.label); + } + } + + return [...new Set(values)]; +} + +function extractInlineText(node: MdastNode, partials: Map, depth: number): string { + switch (node.type) { + case 'text': + case 'inlineCode': + return node.value ?? ''; + case 'link': + case 'strong': + case 'emphasis': + case 'delete': + case 'paragraph': + case 'heading': + return (node.children ?? []).map(child => extractInlineText(child, partials, depth)).join(' '); + case 'break': + return ' '; + case 'textComponent': + case 'leafComponent': { + if (node.name === 'doc-cli-snippet') { + return typeof node.attributes?.command === 'string' ? node.attributes.command : ''; + } + if (node.name === 'partial') { + const partialName = typeof node.attributes?.content === 'string' ? node.attributes.content : ''; + const partial = partialName ? resolvePartialContent(partialName, partials) : null; + if (!partial || depth >= MAX_PARTIAL_DEPTH) return ''; + return extractInlineTextFromMarkdown(partial, partials, depth + 1); + } + return parseComponentMeta(node.rawData, node.attributes).join(' '); + } + default: + return (node.children ?? []).map(child => extractInlineText(child, partials, depth)).join(' '); + } +} + +function extractInlineTextFromMarkdown(markdown: string, partials: Map, depth: number) { + const tree = remark().use(remarkParse).use(remarkMdc).parse(markdown) as { children: MdastNode[] }; + return tree.children.map(child => extractInlineText(child, partials, depth)).join(' '); +} + +function extractBlocks(nodes: MdastNode[], partials: Map, depth = 0): ExtractedBlock[] { + const blocks: ExtractedBlock[] = []; + + for (const node of nodes) { + switch (node.type) { + case 'heading': { + const text = cleanSentence(extractInlineText(node, partials, depth)); + if (text) blocks.push({ type: 'heading', depth: node.depth, text }); + break; + } + case 'paragraph': { + const text = cleanSentence(extractInlineText(node, partials, depth)); + if (text) blocks.push({ type: 'paragraph', text }); + break; + } + case 'list': { + for (const child of node.children ?? []) { + const text = cleanSentence(extractInlineText(child, partials, depth)); + if (text) blocks.push({ type: 'paragraph', text: `- ${text}` }); + } + break; + } + case 'table': { + for (const row of node.children ?? []) { + const text = cleanSentence(extractInlineText(row, partials, depth)); + if (text) blocks.push({ type: 'paragraph', text }); + } + break; + } + case 'code': { + const code = normalizeCode(node.value ?? ''); + if (code) blocks.push({ type: 'code', text: code }); + break; + } + case 'textComponent': + case 'leafComponent': { + if (node.name === 'partial') { + const partialName = typeof node.attributes?.content === 'string' ? node.attributes.content : ''; + const partial = partialName ? resolvePartialContent(partialName, partials) : null; + if (!partial) { + blocks.push({ type: 'paragraph', text: `[Missing partial: ${partialName}]` }); + break; + } + if (depth >= MAX_PARTIAL_DEPTH) break; + const partialTree = remark().use(remarkParse).use(remarkMdc).parse(partial) as { children: MdastNode[] }; + blocks.push(...extractBlocks(partialTree.children, partials, depth + 1)); + break; + } + if (node.name === 'doc-cli-snippet') { + const command = typeof node.attributes?.command === 'string' ? normalizeCode(node.attributes.command) : ''; + if (command) blocks.push({ type: 'code', text: command }); + break; + } + const meta = parseComponentMeta(node.rawData, node.attributes).join('\n\n'); + if (meta) blocks.push({ type: 'paragraph', text: meta }); + break; + } + case 'containerComponent': { + const meta = parseComponentMeta(node.rawData, node.attributes); + for (const value of meta) { + blocks.push({ type: 'paragraph', text: value }); + } + blocks.push(...extractBlocks(node.children ?? [], partials, depth)); + break; + } + default: + if (node.children?.length) { + blocks.push(...extractBlocks(node.children, partials, depth)); + } + } + } + + return blocks; +} + +function blocksToSections(blocks: ExtractedBlock[]) { + const sections: MarkdownSection[] = []; + let current: MarkdownSection = { textParts: [], codeBlocks: [] }; + + const flush = () => { + if (current.h2 || current.h3 || current.textParts.length || current.codeBlocks.length) { + sections.push(current); + } + }; + + for (const block of blocks) { + if (block.type === 'heading') { + if (block.depth === 2) { + flush(); + current = { h2: block.text, textParts: [], codeBlocks: [] }; + continue; + } + if (block.depth === 3) { + flush(); + current = { h2: current.h2, h3: block.text, textParts: [], codeBlocks: [] }; + continue; + } + } + + if (block.type === 'code') { + current.codeBlocks.push(block.text); + continue; + } + + current.textParts.push(block.text); + } + + flush(); + return sections; +} + +function splitLongText(text: string, maxLength: number): string[] { + const normalized = normalizeText(text); + if (normalized.length <= maxLength) return [normalized]; + + const sentences = normalized.split(/(?<=[.!?])\s+/).map(cleanSentence).filter(Boolean); + if (sentences.length <= 1) { + const words = normalized.split(/\s+/); + const chunks: string[] = []; + let current = ''; + for (const word of words) { + const next = current ? `${current} ${word}` : word; + if (next.length > maxLength && current) { + chunks.push(current); + current = word; + } + else { + current = next; + } + } + if (current) chunks.push(current); + return chunks; + } + + const chunks: string[] = []; + let current = ''; + for (const sentence of sentences) { + const next = current ? `${current} ${sentence}` : sentence; + if (next.length > maxLength && current) { + chunks.push(current); + current = sentence; + } + else if (sentence.length > maxLength) { + chunks.push(...splitLongText(sentence, maxLength)); + current = ''; + } + else { + current = next; + } + } + if (current) chunks.push(current); + return chunks; +} + +function chunkSectionText(parts: string[]) { + const chunks: string[] = []; + let current = ''; + + for (const part of parts.map(normalizeText).filter(Boolean)) { + if (!part) continue; + if (part.length > MAX_CHUNK_SIZE) { + for (const split of splitLongText(part, MAX_CHUNK_SIZE)) { + if (current) { + chunks.push(current); + current = ''; + } + chunks.push(split); + } + continue; + } + + const next = current ? `${current}\n\n${part}` : part; + if (next.length > MAX_CHUNK_SIZE && current) { + chunks.push(current); + const overlap = current.slice(-CHUNK_OVERLAP).trim(); + current = overlap ? `${overlap}\n\n${part}` : part; + if (current.length > MAX_CHUNK_SIZE) { + chunks.push(...splitLongText(current, MAX_CHUNK_SIZE)); + current = ''; + } + } + else { + current = next; + } + } + + if (current) chunks.push(current); + return chunks; +} + +function buildSectionHierarchy(sectionLabel: string, title: string, section: MarkdownSection) { + return [sectionLabel, title, section.h2, section.h3].filter(Boolean) as string[]; +} + +function createSummaryChunk(routePath: string, title: string, description: string | undefined, sectionLabel: string, sections: MarkdownSection[]): RawChunk | null { + const firstSection = sections[0]; + const summaryParts = [description]; + + if (firstSection?.h2 && !firstSection.h3) summaryParts.push(firstSection.h2); + if (firstSection?.textParts[0]) summaryParts.push(firstSection.textParts[0]); + if (!summaryParts.some(Boolean)) return null; + + const content = normalizeText(summaryParts.filter(Boolean).join('\n\n')); + if (!content) return null; + + return { + url: toSearchUrl(routePath), + hierarchy: [sectionLabel, title], + content, + code_blocks: firstSection?.codeBlocks.length ? [...new Set(firstSection.codeBlocks)] : undefined, + weight: 10, + level: 0, + position: 0, + }; +} + +export function chunkMarkdownPage({ sourcePath, updatedAt, partials }: ChunkMarkdownPageOptions): IndexedSearchDocument[] { + const fileSource = fs.readFileSync(sourcePath, 'utf8'); + const parsed = matter(fileSource, { engines: { yaml: value => loadYaml(value, YAML_OPTIONS) as Record } }); + const frontmatter = parsed.data as MarkdownFrontmatter; + const routePath = contentPathToPublicPath(path.relative(process.cwd(), sourcePath).replace(/\\/g, '/')); + const section = findSectionByPath(routePath)?.id ?? 'getting-started'; + const sectionLabel = findSectionByPath(routePath)?.label ?? 'Get Started'; + const title = frontmatter.title?.trim(); + if (!title) { + throw new Error(`Missing title in ${sourcePath}`); + } + + const pageSearchTitle = buildPageSearchTitle(routePath, title); + const pathDepth = getPathDepth(routePath); + const tree = remark().use(remarkParse).use(remarkMdc).parse(parsed.content) as { children: MdastNode[] }; + const blocks = extractBlocks(tree.children, partials); + const sections = blocksToSections(blocks); + const rawChunks: RawChunk[] = []; + const summaryChunk = createSummaryChunk(routePath, pageSearchTitle, frontmatter.description, sectionLabel, sections); + if (summaryChunk) rawChunks.push(summaryChunk); + + for (const [sectionIndex, sectionBlock] of sections.entries()) { + const textParts = sectionBlock.textParts.length > 0 + ? sectionBlock.textParts + : [sectionBlock.h3 ?? sectionBlock.h2 ?? title]; + const contentChunks = chunkSectionText(textParts); + const anchor = sectionBlock.h3 ? slugify(sectionBlock.h3) : sectionBlock.h2 ? slugify(sectionBlock.h2) : undefined; + const heading = sectionBlock.h3 ?? sectionBlock.h2; + const hierarchy = buildSectionHierarchy(sectionLabel, pageSearchTitle, sectionBlock); + const codeBlocks = [...new Set(sectionBlock.codeBlocks.map(normalizeCode).filter(Boolean))]; + const level = sectionBlock.h3 ? 2 : sectionBlock.h2 ? 1 : 0; + + for (const [index, content] of contentChunks.entries()) { + rawChunks.push({ + url: toSearchUrl(routePath, anchor), + anchor, + heading, + hierarchy, + content, + code_blocks: codeBlocks.length ? codeBlocks : undefined, + weight: heading ? (index === 0 ? 8 : 5) : (index === 0 ? 10 : 5), + level, + position: (sectionIndex * 10) + index + 1, + }); + } + } + + const groupId = toSearchUrl(routePath); + const totalChunks = rawChunks.length; + return rawChunks.map((chunk, chunkIndex) => ({ + id: `${chunk.url}#${chunkIndex}`, + group_id: groupId, + chunk_index: chunkIndex, + total_chunks: totalChunks, + url: chunk.url, + title, + search_title: buildChunkSearchTitle(pageSearchTitle, chunk.heading), + description: frontmatter.description?.trim() || undefined, + anchor: chunk.anchor, + heading: chunk.heading, + hierarchy: chunk.hierarchy, + path_tokens: buildPathTokens(routePath, chunk.anchor), + path_depth: pathDepth, + rank_order: buildRankOrder(routePath, chunk.level, chunk.position), + section, + doc_type: 'page', + technologies: Array.isArray(frontmatter.technologies) && frontmatter.technologies.length > 0 + ? frontmatter.technologies + : undefined, + content: chunk.content, + code_blocks: chunk.code_blocks, + weight: chunk.weight, + updated_at: updatedAt, + _source_path: path.relative(process.cwd(), sourcePath).replace(/\\/g, '/'), + })); +} + +export function collectMarkdownDocuments() { + const partials = loadPartials(); + const files = listRoutableContentFiles('content').filter(file => { + if (file.startsWith('content/_partials/')) return false; + if (file.startsWith('content/releases/')) return false; + return true; + }); + + const documents: IndexedSearchDocument[] = []; + const failures: Array<{ file: string; error: string }> = []; + for (const file of files) { + const sourcePath = path.resolve(file); + const stat = fs.statSync(sourcePath); + try { + documents.push(...chunkMarkdownPage({ + sourcePath, + updatedAt: Math.round(stat.mtimeMs), + partials, + })); + } + catch (error) { + failures.push({ + file, + error: error instanceof Error ? error.message : String(error), + }); + } + } + + return { documents, filesIndexed: files.length, failures }; +} diff --git a/scripts/index-docs.ts b/scripts/index-docs.ts new file mode 100644 index 000000000..b57628569 --- /dev/null +++ b/scripts/index-docs.ts @@ -0,0 +1,288 @@ +import 'dotenv/config'; +import process from 'node:process'; +import { Client } from 'typesense'; +import type { CollectionCreateSchema } from 'typesense/lib/Typesense/Collections.js'; +import { parseTypesenseUrl } from '../shared/utils/parseTypesenseUrl.ts'; +import { resolveBranchTypesenseAlias } from '../lib/typesenseAlias.ts'; +import { multiway, oneway } from '../server/data/synonyms.ts'; +import { collectMarkdownDocuments, type IndexedSearchDocument } from './index-docs-chunker.ts'; + +interface SynonymDefinition { + id: string; + synonyms: string[]; + root?: string; +} + +/** + * Convert the editorial-friendly synonyms file into Typesense-shaped entries. + * IDs are auto-derived so writers don't have to keep them unique. + */ +function buildSynonymDefinitions(): SynonymDefinition[] { + const definitions: SynonymDefinition[] = []; + + for (const [index, terms] of multiway.entries()) { + definitions.push({ + id: `mw-${index}-${terms[0]?.replace(/\s+/g, '-')}`, + synonyms: [...terms], + }); + } + + for (const [root, target] of Object.entries(oneway)) { + definitions.push({ + id: `ow-${root.replace(/\s+/g, '-')}`, + root, + synonyms: [target], + }); + } + + return definitions; +} + +/** + * Single global synonym set name, reused across every alias and slot. + * + * Synonyms are editorial. They live in `server/data/synonyms.ts` and are the + * same vocabulary regardless of which collection (production, preview, dev) + * is being indexed. Sharing one set keeps the synonym sets list in the cluster + * clean (one entry forever instead of N × 2 per branch) and makes editorial + * changes propagate everywhere on the next indexer run. + */ +const SYNONYM_SET_NAME = 'directus-docs-synonyms'; + +function isTypesenseNotFoundError(error: unknown) { + return Boolean( + error + && typeof error === 'object' + && 'httpStatus' in error + && error.httpStatus === 404, + ); +} + +const COLLECTION_SCHEMA: CollectionCreateSchema = { + name: 'directus-docs', + enable_nested_fields: true, + fields: [ + { name: 'id', type: 'string' }, + { name: 'group_id', type: 'string', facet: true }, + { name: 'chunk_index', type: 'int32' }, + { name: 'total_chunks', type: 'int32' }, + { name: 'url', type: 'string' }, + { name: 'title', type: 'string' }, + { name: 'search_title', type: 'string' }, + { name: 'description', type: 'string', optional: true }, + { name: 'anchor', type: 'string', optional: true }, + { name: 'heading', type: 'string', optional: true }, + { name: 'hierarchy', type: 'string[]' }, + { name: 'path_tokens', type: 'string' }, + { name: 'path_depth', type: 'int32' }, + { name: 'rank_order', type: 'int32', sort: true }, + { name: 'section', type: 'string', facet: true }, + { name: 'doc_type', type: 'string', facet: true }, + { name: 'technologies', type: 'string[]', facet: true, optional: true }, + { name: 'content', type: 'string' }, + { name: 'code_blocks', type: 'string[]', optional: true }, + { name: 'weight', type: 'int32' }, + { name: 'updated_at', type: 'int64', sort: true }, + ], + default_sorting_field: 'weight', +}; + +function requiredEnv(name: string) { + const value = process.env[name]; + if (!value) { + throw new Error(`Missing required environment variable: ${name}`); + } + return value; +} + +function resolveCollectionAlias() { + if (process.env.TYPESENSE_INDEX_TARGET) return process.env.TYPESENSE_INDEX_TARGET; + + const alias = resolveBranchTypesenseAlias(); + if (!alias) { + throw new Error('Could not resolve Typesense index alias from branch. Set TYPESENSE_INDEX_TARGET.'); + } + + return alias; +} + +function resolveTypesenseUrl() { + return requiredEnv('TYPESENSE_URL'); +} + +function createClient() { + const node = parseTypesenseUrl(resolveTypesenseUrl()); + return new Client({ + nodes: [node], + apiKey: requiredEnv('TYPESENSE_PRIVATE_API_KEY'), + connectionTimeoutSeconds: 300, + }); +} + +async function getAliasTarget(client: Client, alias: string) { + try { + const existing = await client.aliases(alias).retrieve() as { collection_name?: string }; + return existing.collection_name ?? null; + } + catch (error) { + if (isTypesenseNotFoundError(error)) return null; + throw error; + } +} + +/** + * Resolve the next collection slot for blue/green indexing. + * + * We keep two fixed slots per alias (`${alias}-a` and `${alias}-b`). Each run + * writes into whichever slot the alias is NOT currently pointing at, then + * swaps the alias. This bounds collection count to 2 per alias forever: no + * timestamps, no grace window, no cleanup loop drift. + */ +function resolveNextSlot(currentTarget: string | null, alias: string) { + const slotA = `${alias}-a`; + const slotB = `${alias}-b`; + const next = currentTarget === slotA ? slotB : slotA; + const previous = currentTarget === slotA || currentTarget === slotB ? currentTarget : null; + return { next, previous }; +} + +function stripSourcePath(document: IndexedSearchDocument) { + const { _source_path, ...rest } = document; + return rest; +} + +async function createCollection(client: Client, collectionName: string) { + // Slots are reused across runs, so drop any stale collection sitting in the + // target slot before recreating it with the current schema. + try { + await client.collections(collectionName).delete(); + } + catch (error) { + if (!isTypesenseNotFoundError(error)) throw error; + } + await client.collections().create({ + ...COLLECTION_SCHEMA, + name: collectionName, + }); +} + +async function importDocuments(client: Client, collectionName: string, documents: IndexedSearchDocument[]) { + const response = await client.collections(collectionName).documents().import( + documents.map(stripSourcePath), + { action: 'upsert', dirty_values: 'coerce_or_drop' }, + ) as unknown; + + const failures: Array<{ document: IndexedSearchDocument; message: string }> = []; + const lines = Array.isArray(response) + ? response.map(entry => JSON.stringify(entry)) + : String(response).trim().split('\n').filter(Boolean); + for (const [index, line] of lines.entries()) { + let parsed: { success?: boolean; error?: string }; + try { + parsed = JSON.parse(line) as { success?: boolean; error?: string }; + } + catch { + failures.push({ document: documents[index]!, message: `Unparseable import response: ${line}` }); + continue; + } + if (!parsed.success) { + failures.push({ document: documents[index]!, message: parsed.error || 'Unknown import failure' }); + } + } + + return failures; +} + +async function validateDocumentCount(client: Client, collectionName: string, expectedCount: number) { + const collection = await client.collections(collectionName).retrieve() as { num_documents?: number }; + const actualCount = collection.num_documents ?? 0; + if (actualCount !== expectedCount) { + throw new Error(`Document count mismatch for ${collectionName}: expected ${expectedCount}, got ${actualCount}`); + } +} + +async function syncSynonyms(client: Client, collectionName: string) { + const definitions = buildSynonymDefinitions(); + await client.synonymSets(SYNONYM_SET_NAME).upsert({ items: definitions }); + await client.collections(collectionName).update({ synonym_sets: [SYNONYM_SET_NAME] }); +} + +async function swapAlias(client: Client, alias: string, collectionName: string) { + await client.aliases().upsert(alias, { collection_name: collectionName }); +} + +async function deletePreviousSlot(client: Client, previousCollection: string | null) { + if (!previousCollection) return; + try { + await client.collections(previousCollection).delete(); + console.log(`Deleted previous slot ${previousCollection}`); + } + catch (error) { + if (!isTypesenseNotFoundError(error)) throw error; + } + // Synonym set is global (SYNONYM_SET_NAME), not per-slot. Nothing to clean up here. +} + +function printFailures(failures: Array<{ file: string; error: string }>) { + if (failures.length === 0) return; + console.error('Markdown chunking failures:'); + for (const failure of failures) { + console.error(`- ${failure.file}: ${failure.error}`); + } +} + +function printImportFailures(failures: Array<{ document: IndexedSearchDocument; message: string }>) { + if (failures.length === 0) return; + console.error('Typesense import failures:'); + for (const failure of failures) { + console.error(`- ${failure.document._source_path ?? failure.document.id}: ${failure.message}`); + } +} + +async function main() { + const alias = resolveCollectionAlias(); + if (alias === 'directus-docs' && !process.env.GITHUB_ACTIONS) { + throw new Error('Refusing to write prod alias from local. Use TYPESENSE_INDEX_TARGET to override.'); + } + + const client = createClient(); + const currentTarget = await getAliasTarget(client, alias); + const { next: nextCollection, previous: previousCollection } = resolveNextSlot(currentTarget, alias); + + console.log(`Target alias: ${alias}`); + console.log(`Writing to slot: ${nextCollection}`); + if (currentTarget) console.log(`Current alias target: ${currentTarget}`); + + const markdown = collectMarkdownDocuments(); + printFailures(markdown.failures); + + const documents = markdown.documents; + console.log(`Markdown pages indexed: ${markdown.filesIndexed}`); + console.log('OAS indexing deferred to the OpenAPI/API reference PR.'); + console.log(`Total chunks prepared: ${documents.length}`); + + if (markdown.failures.length > 0) { + throw new Error(`Aborting due to ${markdown.failures.length} markdown chunking failures`); + } + + await createCollection(client, nextCollection); + await syncSynonyms(client, nextCollection); + + const importFailures = await importDocuments(client, nextCollection, documents); + printImportFailures(importFailures); + if (importFailures.length > 0) { + throw new Error(`Aborting due to ${importFailures.length} Typesense import failures`); + } + + await validateDocumentCount(client, nextCollection, documents.length); + await swapAlias(client, alias, nextCollection); + await deletePreviousSlot(client, previousCollection); + + console.log(`Alias ${alias} now points to ${nextCollection}`); + console.log('Index complete'); +} + +main().catch(async (error) => { + console.error(error instanceof Error ? error.message : error); + process.exitCode = 1; +}); diff --git a/scripts/nuxt-shims.d.ts b/scripts/nuxt-shims.d.ts new file mode 100644 index 000000000..58d8155c2 --- /dev/null +++ b/scripts/nuxt-shims.d.ts @@ -0,0 +1,4 @@ +declare const resolveOasRef: typeof import('../app/utils/resolveOasRef.ts').default; +declare const flattenSchema: typeof import('../app/utils/flattenSchema.ts').default; +declare const responseToExample: typeof import('../app/utils/responseToExample.ts').default; +declare const linguistToShiki: typeof import('../app/utils/linguistToShiki.ts').default; diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json index c8735ba45..eec1ce76f 100644 --- a/scripts/tsconfig.json +++ b/scripts/tsconfig.json @@ -2,10 +2,19 @@ "compilerOptions": { "module": "nodenext", "moduleResolution": "nodenext", + "baseUrl": "..", + "paths": { + "~/types": ["./app/types.ts"], + "~/*": ["./*"], + "@/*": ["./*"] + }, "target": "es2022", + "ignoreDeprecations": "6.0", "strict": true, "noEmit": true, "allowImportingTsExtensions": true, + "esModuleInterop": true, + "resolveJsonModule": true, "types": ["node"], "skipLibCheck": true }, diff --git a/server/api/search/debug/[...slug].get.ts b/server/api/search/debug/[...slug].get.ts new file mode 100644 index 000000000..b91729192 --- /dev/null +++ b/server/api/search/debug/[...slug].get.ts @@ -0,0 +1,36 @@ +import { parseTypesenseUrl } from '#shared/utils/parseTypesenseUrl'; + +export default defineEventHandler(async (event) => { + if (!import.meta.dev) { + throw createError({ statusCode: 404, statusMessage: 'Not found' }); + } + + const params = getRouterParams(event).slug; + const slug = Array.isArray(params) ? params.join('/') : params; + if (!slug) { + throw createError({ statusCode: 400, statusMessage: 'Missing slug' }); + } + + const config = useRuntimeConfig(); + const node = parseTypesenseUrl(config.public.typesenseUrl); + const path = node.path ?? ''; + const baseUrl = `${node.protocol}://${node.host}:${node.port}${path}`; + const groupId = `/docs/${slug.replace(/^\/+/, '').replace(/\/+$/, '')}`; + const url = new URL(`${baseUrl}/collections/${config.public.typesenseCollection}/documents/search`); + url.searchParams.set('q', '*'); + url.searchParams.set('query_by', 'title,heading,content'); + url.searchParams.set('filter_by', `group_id:=${groupId}`); + url.searchParams.set('sort_by', 'chunk_index:asc'); + url.searchParams.set('per_page', '50'); + url.searchParams.set('include_fields', 'weight,chunk_index,rank_order,search_title,anchor,content,heading,url'); + + const result = await $fetch<{ + hits?: Array<{ document: Record }>; + }>(url.toString(), { + headers: { + 'X-TYPESENSE-API-KEY': config.public.typesensePublicApiKey, + }, + }); + + return (result.hits ?? []).map(hit => hit.document); +}); diff --git a/server/data/synonyms.ts b/server/data/synonyms.ts new file mode 100644 index 000000000..718fc3a59 --- /dev/null +++ b/server/data/synonyms.ts @@ -0,0 +1,60 @@ +/** + * Search synonyms for Typesense, pushed by `pnpm index`. + * + * Two flavors: + * + * 1. `multiway`: equivalent terms. Searching ANY term in the group matches + * docs containing ANY OTHER term in the group. Use for true synonyms where + * direction doesn't matter. + * + * Add a new entry by appending an array of equivalent terms: + * ['perms', 'permissions'] + * ['login', 'sign in', 'log in'] + * + * 2. `oneway`: directional. Searching the KEY surfaces docs containing the + * VALUE, but NOT the reverse. Use when a shorthand should reach the + * canonical Directus term, but the canonical term shouldn't be polluted + * with shorthand mentions. + * + * Add a new entry as `'': ''`: + * table: 'collection' // searches for "table" find collection docs + * db: 'database' // searches for "db" find database docs + * + * Notes: + * - Don't add pure case variants (Typesense case-folds by default). + * - Don't add stemming pairs like aggregate/aggregation (Typesense stems). + * - When in doubt, leave it out. Bad synonyms hurt search worse than missing ones. + */ + +export const multiway: ReadonlyArray = [ + ['auth', 'authentication'], + ['env var', 'environment variable'], + ['OAS', 'OpenAPI'], + ['M2M', 'many-to-many'], + ['M2O', 'many-to-one'], + ['O2M', 'one-to-many'], + ['O2O', 'one-to-one'], + ['M2A', 'many-to-any'], + ['realtime', 'websockets'], + ['js', 'javascript'], + ['ts', 'typescript'], + ['ui', 'user interface'], + ['login', 'sign in', 'log in'], + ['logout', 'sign out', 'log out'], + ['register', 'sign up'], + ['relation', 'relationship'], + ['junction collection', 'join table'], + ['query param', 'query parameter'], + ['self-host', 'self-hosted', 'self-managed'], + ['static token', 'personal access token'], + ['webhook', 'event hook'], + ['revision', 'version history'], +]; + +export const oneway: Readonly> = { + table: 'collection', + column: 'field', + row: 'item', + record: 'item', + db: 'database', +}; diff --git a/shared/utils/parseTypesenseUrl.ts b/shared/utils/parseTypesenseUrl.ts new file mode 100644 index 000000000..c9a6efb68 --- /dev/null +++ b/shared/utils/parseTypesenseUrl.ts @@ -0,0 +1,24 @@ +export interface TypesenseNode { + host: string; + port: number; + protocol: string; + path: string; +} + +export function parseTypesenseUrl(url: string): TypesenseNode { + try { + const parsedUrl = new URL(/^https?:\/\//i.test(url) ? url : `https://${url}`); + return { + host: parsedUrl.hostname, + port: Number.parseInt(parsedUrl.port, 10) || (parsedUrl.protocol === 'https:' ? 443 : 8108), + protocol: parsedUrl.protocol.replace(':', ''), + // Empty string (not undefined) so the official Typesense client's + // `${protocol}://${host}:${port}${path}${endpoint}` URL builder + // doesn't interpolate the literal "undefined". + path: parsedUrl.pathname === '/' ? '' : parsedUrl.pathname, + }; + } + catch (error) { + throw new Error(`Invalid Typesense URL: ${url}`, { cause: error }); + } +} diff --git a/tests/components/DocsSearchPalette.test.ts b/tests/components/DocsSearchPalette.test.ts new file mode 100644 index 000000000..7e6adc2d1 --- /dev/null +++ b/tests/components/DocsSearchPalette.test.ts @@ -0,0 +1,249 @@ +import { nextTick, ref } from 'vue'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { mountSuspended, mockNuxtImport } from '@nuxt/test-utils/runtime'; +import DocsSearchPalette from '../../app/components/DocsSearchPalette.vue'; +import DocsSearchPreview from '../../app/components/DocsSearchPreview.vue'; + +const { + defineShortcutsMock, + navigateToMock, + useDocsSearchMock, + usePageHistoryMock, +} = vi.hoisted(() => ({ + defineShortcutsMock: vi.fn(), + navigateToMock: vi.fn(), + useDocsSearchMock: vi.fn(), + usePageHistoryMock: vi.fn(), +})); + +mockNuxtImport('useDocsSearch', () => useDocsSearchMock); +mockNuxtImport('usePageHistory', () => usePageHistoryMock); +mockNuxtImport('defineShortcuts', () => defineShortcutsMock); +mockNuxtImport('navigateTo', () => navigateToMock); + +const stubHits = [ + { + id: '1', + to: '/guides/data-model/collections', + title: 'Collections', + titleHtml: 'Collections', + breadcrumb: 'Guides › Data Model', + snippetHtml: 'Create and manage collections.', + content: 'Create and manage collections.', + section: 'guides', + sectionLabel: 'Guides', + docTypeLabel: 'Guide', + docType: 'page', + }, + { + id: '2', + to: '/frameworks/nuxt/authentication', + title: 'Nuxt Authentication', + titleHtml: 'Nuxt Authentication', + breadcrumb: 'Frameworks › Nuxt', + snippetHtml: 'Authenticate users in Nuxt.', + content: 'Authenticate users in Nuxt.', + section: 'frameworks', + sectionLabel: 'Frameworks', + framework: 'nuxt', + docTypeLabel: 'Guide', + docType: 'page', + }, + { + id: '3', + to: '/api/items#create-multiple-items', + title: 'POST /items/{collection}', + titleHtml: 'POST /items/{collection}', + breadcrumb: 'API Reference › Items', + snippetHtml: 'Create item records.', + content: 'Create item records.', + section: 'api', + sectionLabel: 'API Reference', + docTypeLabel: 'Reference', + docType: 'api-operation', + }, + { + id: '4', + to: '/reference/query-parameters', + title: 'Query Parameters', + titleHtml: 'Query Parameters', + breadcrumb: 'Reference', + snippetHtml: 'Filter and paginate responses.', + content: 'Filter and paginate responses.', + section: 'reference', + sectionLabel: 'Reference', + docTypeLabel: 'Reference', + docType: 'page', + }, + { + id: '5', + to: '/tutorials/build-a-chat-app', + title: 'Build a Chat App', + titleHtml: 'Build a Chat App', + breadcrumb: 'Tutorials', + snippetHtml: 'Step-by-step chat app tutorial.', + content: 'Step-by-step chat app tutorial.', + section: 'tutorials', + sectionLabel: 'Tutorials', + docTypeLabel: 'Tutorial', + docType: 'page', + }, +] as const; + +describe('DocsSearchPalette', () => { + const query = ref('auth'); + const section = ref<'all' | 'guides' | 'frameworks' | 'api' | 'reference' | 'tutorials'>('all'); + const pending = ref(false); + const found = ref(stubHits.length); + const items = ref([...stubHits]); + const sectionCounts = ref(new Map([ + ['guides', 1], + ['frameworks', 1], + ['api', 1], + ['reference', 1], + ['tutorials', 1], + ])); + const clearMock = vi.fn(); + + beforeEach(() => { + query.value = 'auth'; + section.value = 'all'; + pending.value = false; + found.value = stubHits.length; + items.value = [...stubHits]; + sectionCounts.value = new Map([ + ['guides', 1], + ['frameworks', 1], + ['api', 1], + ['reference', 1], + ['tutorials', 1], + ]); + clearMock.mockReset(); + navigateToMock.mockReset(); + useDocsSearchMock.mockReset(); + usePageHistoryMock.mockReset(); + defineShortcutsMock.mockReset(); + + useDocsSearchMock.mockReturnValue({ + query, + section, + pending, + found, + items, + sectionCounts, + minQueryLength: 2, + isTooShort: ref(false), + clear: clearMock, + }); + + usePageHistoryMock.mockReturnValue({ + recents: ref([]), + favorites: ref([]), + }); + + Object.defineProperty(navigator, 'clipboard', { + value: { writeText: vi.fn().mockResolvedValue(undefined) }, + configurable: true, + }); + + Object.defineProperty(window, 'matchMedia', { + writable: true, + configurable: true, + value: vi.fn().mockImplementation((query: string) => ({ + matches: query.includes('min-width: 640px'), + media: query, + onchange: null, + addListener: vi.fn(), + removeListener: vi.fn(), + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), + }); + }); + + async function mountPalette() { + return mountSuspended(DocsSearchPalette, { + props: { open: false }, + global: { + provide: { + navigation: ref([ + { + title: 'Frameworks', + path: '/frameworks', + children: [ + { + title: 'Nuxt', + path: '/frameworks/nuxt', + children: [ + { title: 'Nuxt Authentication', path: '/frameworks/nuxt/authentication' }, + ], + }, + ], + }, + ]), + }, + }, + }); + } + + async function openPalette(wrapper: Awaited>) { + await wrapper.setProps({ open: true }); + await nextTick(); + } + + function findButton(label: string) { + return [...document.querySelectorAll('button')] + .find(button => button.textContent?.includes(label)); + } + + it('scopes [/] keydown to open state', async () => { + const wrapper = await mountPalette(); + + window.dispatchEvent(new KeyboardEvent('keydown', { key: ']' })); + await nextTick(); + expect(section.value).toBe('all'); + + await openPalette(wrapper); + window.dispatchEvent(new KeyboardEvent('keydown', { key: ']' })); + await nextTick(); + expect(section.value).toBe('guides'); + }); + + it('renders the preview pane with a docs-prefixed display path', async () => { + const wrapper = await mountPalette(); + await openPalette(wrapper); + items.value = [...stubHits]; + await nextTick(); + + const preview = wrapper.getComponent(DocsSearchPreview); + expect(preview.text()).toContain('/docs/guides/data-model/collections'); + }); + + it('keeps preview actions wired through the parent', async () => { + const wrapper = await mountPalette(); + await openPalette(wrapper); + + const openButton = findButton('Open page'); + const copyButton = findButton('Copy link'); + expect(openButton).toBeTruthy(); + expect(copyButton).toBeTruthy(); + + const preview = wrapper.getComponent(DocsSearchPreview); + copyButton?.click(); + await nextTick(); + expect(navigator.clipboard.writeText).toHaveBeenCalledWith(`${window.location.origin}/docs/guides/data-model/collections`); + + const externalHit = { + ...stubHits[1], + to: 'http://docs.example.com/frameworks/nuxt/authentication', + }; + const palette = wrapper.findComponent({ name: 'UCommandPalette' }); + palette.vm.$emit('highlight', { ref: document.createElement('div'), value: externalHit }); + await nextTick(); + + preview.vm.$emit('open'); + await nextTick(); + expect(navigateToMock).toHaveBeenCalledWith('http://docs.example.com/frameworks/nuxt/authentication', { external: true }); + }); +}); diff --git a/tests/lib/typesenseAlias.test.ts b/tests/lib/typesenseAlias.test.ts new file mode 100644 index 000000000..91d7f4bed --- /dev/null +++ b/tests/lib/typesenseAlias.test.ts @@ -0,0 +1,27 @@ +import { afterEach, describe, expect, it } from 'vitest'; +import { getTypesenseBranchName, resolveBranchTypesenseAlias, slugifyBranch } from '../../lib/typesenseAlias'; + +const originalEnv = { ...process.env }; + +afterEach(() => { + process.env = { ...originalEnv }; +}); + +describe('typesense alias helpers', () => { + it('slugifies branch names for preview aliases', () => { + expect(slugifyBranch('bry/Dockem 6: Typesense')).toBe('bry-dockem-6-typesense'); + expect(resolveBranchTypesenseAlias('bry/foo')).toBe('directus-docs-preview-bry-foo'); + }); + + it('maps main to the production alias', () => { + expect(resolveBranchTypesenseAlias('main')).toBe('directus-docs'); + }); + + it('uses the Vercel branch env when GitHub env is absent', () => { + delete process.env.GITHUB_HEAD_REF; + delete process.env.GITHUB_REF_NAME; + process.env.VERCEL_GIT_COMMIT_REF = 'preview/search'; + + expect(getTypesenseBranchName()).toBe('preview/search'); + }); +}); diff --git a/tests/scripts/index-docs-chunker.test.ts b/tests/scripts/index-docs-chunker.test.ts new file mode 100644 index 000000000..3ec7a9ef8 --- /dev/null +++ b/tests/scripts/index-docs-chunker.test.ts @@ -0,0 +1,41 @@ +// @vitest-environment node + +import fs from 'node:fs'; +import path from 'node:path'; +import { describe, expect, it } from 'vitest'; +import { chunkMarkdownPage, loadPartials } from '../../scripts/index-docs-chunker.ts'; + +describe('index-docs chunker', () => { + it('keeps MDC-heavy home page chunks clean', () => { + const sourcePath = path.resolve('content/index.md'); + const partials = loadPartials(); + const documents = chunkMarkdownPage({ + sourcePath, + updatedAt: Math.round(fs.statSync(sourcePath).mtimeMs), + partials, + }); + + const combined = documents.map(document => document.content).join('\n'); + expect(combined).toContain('Local Demo'); + expect(combined).toContain('Try Directus locally in one command.'); + expect(combined).not.toContain('shiny-card'); + expect(combined).not.toContain('shiny-grid'); + expect(combined).not.toContain('two-up'); + }); + + it('extracts card titles from component-only sections', () => { + const sourcePath = path.resolve('content/guides/09.extensions/2.api-extensions/0.index.md'); + const partials = loadPartials(); + const documents = chunkMarkdownPage({ + sourcePath, + updatedAt: Math.round(fs.statSync(sourcePath).mtimeMs), + partials, + }); + + const combined = documents.map(document => document.content).join('\n'); + expect(combined).toContain('Hooks'); + expect(combined).toContain('Endpoints'); + expect(combined).toContain('Operations'); + expect(combined).not.toContain('shiny-card'); + }); +}); diff --git a/tests/services/typesenseService.test.ts b/tests/services/typesenseService.test.ts new file mode 100644 index 000000000..5b6c4ceba --- /dev/null +++ b/tests/services/typesenseService.test.ts @@ -0,0 +1,64 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { TypesenseService } from '../../app/services/typesenseService'; + +afterEach(() => { + vi.unstubAllGlobals(); +}); + +describe('TypesenseService', () => { + it('uses multi_search to merge unfiltered facet counts for refinements', async () => { + const fetchMock = vi.fn().mockResolvedValue({ + results: [ + { + hits: [{ document: { id: '1', title: 'Auth' } }], + facet_counts: [{ field_name: 'section', counts: [{ value: 'guides', count: 1 }] }], + found: 1, + page: 1, + out_of: 1, + }, + { + facet_counts: [{ field_name: 'section', counts: [{ value: 'guides', count: 3 }, { value: 'api', count: 2 }] }], + }, + ], + }); + vi.stubGlobal('$fetch', fetchMock); + + const service = new TypesenseService({ + typesenseUrl: 'https://search.example.com/typesense', + typesensePublicApiKey: 'public-key', + }); + + const result = await service.search({ + indexName: 'directus-docs', + searchConfig: { + query_by: 'title,content', + facet_by: 'section', + filter_by: 'doc_type:=page', + }, + state: { + query: 'auth', + page: 1, + hitsPerPage: 10, + filters: { section: ['guides'] }, + }, + facetRefinementAttributes: ['section'], + }); + + expect(fetchMock).toHaveBeenCalledWith( + 'https://search.example.com:443/typesense/multi_search', + expect.objectContaining({ + method: 'POST', + headers: expect.objectContaining({ 'X-TYPESENSE-API-KEY': 'public-key' }), + }), + ); + const request = fetchMock.mock.calls[0]?.[1]; + expect(request.body.searches).toHaveLength(2); + expect(request.body.searches[0].filter_by).toBe('doc_type:=page && (section:=guides)'); + expect(request.body.searches[1].filter_by).toBe('doc_type:=page'); + expect(request.body.searches[1].per_page).toBe(0); + expect(result.facets.section).toEqual([ + { value: 'guides', count: 3, highlighted: undefined }, + { value: 'api', count: 2, highlighted: undefined }, + ]); + }); +}); diff --git a/tests/shared/parseTypesenseUrl.test.ts b/tests/shared/parseTypesenseUrl.test.ts new file mode 100644 index 000000000..433fbaa5e --- /dev/null +++ b/tests/shared/parseTypesenseUrl.test.ts @@ -0,0 +1,26 @@ +import { describe, expect, it } from 'vitest'; +import { parseTypesenseUrl } from '../../shared/utils/parseTypesenseUrl'; + +describe('parseTypesenseUrl', () => { + it('defaults bare hosts to https port 443', () => { + expect(parseTypesenseUrl('search.example.com')).toEqual({ + host: 'search.example.com', + port: 443, + protocol: 'https', + path: '', + }); + }); + + it('keeps custom protocol, port, and path', () => { + expect(parseTypesenseUrl('http://localhost:8108/typesense')).toEqual({ + host: 'localhost', + port: 8108, + protocol: 'http', + path: '/typesense', + }); + }); + + it('throws for invalid URLs', () => { + expect(() => parseTypesenseUrl('http://')).toThrow('Invalid Typesense URL'); + }); +}); diff --git a/tests/utils/highlightHtml.test.ts b/tests/utils/highlightHtml.test.ts new file mode 100644 index 000000000..834c4b744 --- /dev/null +++ b/tests/utils/highlightHtml.test.ts @@ -0,0 +1,10 @@ +import { describe, expect, it } from 'vitest'; +import { sanitizeHighlightHtml } from '../../app/utils/highlightHtml'; + +describe('sanitizeHighlightHtml', () => { + it('keeps mark tags and escapes other markup', () => { + expect(sanitizeHighlightHtml('Col')).toBe( + 'Col<img src=x onerror=alert(1)>', + ); + }); +}); diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 000000000..c64f1f42c --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineVitestConfig } from '@nuxt/test-utils/config'; + +export default defineVitestConfig({ + test: { + environment: 'nuxt', + environmentOptions: { + nuxt: { + domEnvironment: 'happy-dom', + }, + }, + }, +});