- {{ $t('search.title') }} -
++ {{ $t('search.title') }} +
++ {{ $t('settings.sections.search') }} +
++ {{ $t('settings.data_source.description') }} +
+ ++ {{ + settings.searchProvider === 'algolia' + ? $t('settings.data_source.algolia_description') + : $t('settings.data_source.npm_description') + }} +
+ + + + {{ $t('search.algolia_disclaimer') }} + + +
{{ $t('settings.sections.language') }}
diff --git a/app/pages/~[username]/index.vue b/app/pages/~[username]/index.vue
index c4cab4920..84d971335 100644
--- a/app/pages/~[username]/index.vue
+++ b/app/pages/~[username]/index.vue
@@ -7,17 +7,6 @@ const router = useRouter()
const username = computed(() => route.params.username)
-// Infinite scroll state
-const pageSize = 50
-const maxResults = 250 // npm API hard limit
-const currentPage = shallowRef(1)
-
-// Get initial page from URL (for scroll restoration on reload)
-const initialPage = computed(() => {
- const p = Number.parseInt(normalizeSearchParam(route.query.page), 10)
- return Number.isNaN(p) ? 1 : Math.max(1, p)
-})
-
// Debounced URL update for page and filter/sort
const updateUrl = debounce((updates: { page?: number; filter?: string; sort?: string }) => {
router.replace({
@@ -38,48 +27,35 @@ const sortOption = shallowRef(
(normalizeSearchParam(route.query.sort) as SortOption) || 'downloads',
)
-// Track if we've loaded all results (one-way flag, doesn't reset)
-// Initialize to true if URL already has filter/sort params
-const hasLoadedAll = shallowRef(
- Boolean(route.query.q) ||
- (route.query.sort && normalizeSearchParam(route.query.sort) !== 'downloads'),
-)
-
// Update URL when filter/sort changes (debounced)
const debouncedUpdateUrl = debounce((filter: string, sort: string) => {
updateUrl({ filter, sort })
}, 300)
+// Load all results when user starts filtering/sorting (so client-side filter works on full set)
watch([filterText, sortOption], ([filter, sort]) => {
- // Once user interacts with filter/sort, load all results
- if (!hasLoadedAll.value && (filter !== '' || sort !== 'downloads')) {
- hasLoadedAll.value = true
+ if (filter !== '' || sort !== 'downloads') {
+ loadAll()
}
debouncedUpdateUrl(filter, sort)
})
-// Search for packages by this maintainer
-const searchQuery = computed(() => `maintainer:${username.value}`)
-
-// Request size: load all if user has interacted with filter/sort, otherwise paginate
-const requestSize = computed(() => (hasLoadedAll.value ? maxResults : pageSize * currentPage.value))
-
+// Fetch packages (composable manages pagination & provider dispatch internally)
const {
data: results,
status,
error,
isLoadingMore,
- hasMore: apiHasMore,
- fetchMore,
-} = useNpmSearch(searchQuery, () => ({
- size: requestSize.value,
-}))
+ hasMore,
+ loadMore,
+ loadAll,
+ pageSize,
+} = useUserPackages(username)
-// Initialize current page from URL on mount
-onMounted(() => {
- if (initialPage.value > 1) {
- currentPage.value = initialPage.value
- }
+// Get initial page from URL (for scroll restoration on reload)
+const initialPage = computed(() => {
+ const p = Number.parseInt(normalizeSearchParam(route.query.page), 10)
+ return Number.isNaN(p) ? 1 : Math.max(1, p)
})
// Get the base packages list
@@ -132,22 +108,6 @@ const totalWeeklyDownloads = computed(() =>
filteredAndSortedPackages.value.reduce((sum, pkg) => sum + (pkg.downloads?.weekly ?? 0), 0),
)
-// Check if there are potentially more results
-const hasMore = computed(() => {
- if (!results.value) return false
- // Don't show "load more" when we've already loaded all
- if (hasLoadedAll.value) return false
- // Use API's hasMore, but cap at maxResults
- if (!apiHasMore.value) return false
- return results.value.objects.length < maxResults
-})
-
-async function loadMore() {
- if (isLoadingMore.value || !hasMore.value) return
- currentPage.value++
- await fetchMore(requestSize.value)
-}
-
// Update URL when page changes from scrolling
function handlePageChange(page: number) {
updateUrl({ page, filter: filterText.value, sort: sortOption.value })
@@ -155,10 +115,8 @@ function handlePageChange(page: number) {
// Reset state when username changes
watch(username, () => {
- currentPage.value = 1
filterText.value = ''
sortOption.value = 'downloads'
- hasLoadedAll.value = false
})
useSeoMeta({
@@ -217,14 +175,14 @@ defineOgImageComponent('Default', {
-
+
-
+
{{ error?.message ?? $t('user.page.failed_to_load') }}
@@ -260,7 +218,7 @@ defineOgImageComponent('Default', {
v-else
:results="filteredAndSortedPackages"
:has-more="hasMore"
- :is-loading="isLoadingMore || (status === 'pending' && currentPage > 1)"
+ :is-loading="isLoadingMore"
:page-size="pageSize"
:initial-page="initialPage"
@load-more="loadMore"
diff --git a/i18n/locales/en.json b/i18n/locales/en.json
index 7518f7024..6fd6a7947 100644
--- a/i18n/locales/en.json
+++ b/i18n/locales/en.json
@@ -36,6 +36,7 @@
"claim_button": "Claim \"{name}\"",
"want_to_claim": "Want to claim this package name?",
"start_typing": "Start typing to search packages",
+ "algolia_disclaimer": "Powered by Algolia",
"exact_match": "exact",
"suggestion": {
"user": "user",
@@ -63,8 +64,17 @@
"sections": {
"appearance": "Appearance",
"display": "Display",
+ "search": "Data source",
"language": "Language"
},
+ "data_source": {
+ "label": "Data source",
+ "description": "Choose where npmx gets search data. Individual package pages always use the npm registry directly.",
+ "npm": "npm Registry",
+ "npm_description": "Fetches search, org and user listings directly from the official npm registry. Authoritative, but can be slower.",
+ "algolia": "Algolia",
+ "algolia_description": "Uses Algolia for faster search, org and user pages."
+ },
"relative_dates": "Relative dates",
"include_types": "Include {'@'}types in install",
"include_types_description": "Add {'@'}types package to install commands for untyped packages",
diff --git a/lunaria/files/en-GB.json b/lunaria/files/en-GB.json
index fe8c669e7..22d33f0a5 100644
--- a/lunaria/files/en-GB.json
+++ b/lunaria/files/en-GB.json
@@ -36,6 +36,7 @@
"claim_button": "Claim \"{name}\"",
"want_to_claim": "Want to claim this package name?",
"start_typing": "Start typing to search packages",
+ "algolia_disclaimer": "Powered by Algolia",
"exact_match": "exact",
"suggestion": {
"user": "user",
@@ -63,8 +64,17 @@
"sections": {
"appearance": "Appearance",
"display": "Display",
+ "search": "Data source",
"language": "Language"
},
+ "data_source": {
+ "label": "Data source",
+ "description": "Choose where npmx gets search data. Individual package pages always use the npm registry directly.",
+ "npm": "npm Registry",
+ "npm_description": "Fetches search, org and user listings directly from the official npm registry. Authoritative, but can be slower.",
+ "algolia": "Algolia",
+ "algolia_description": "Uses Algolia for faster search, org and user pages."
+ },
"relative_dates": "Relative dates",
"include_types": "Include {'@'}types in install",
"include_types_description": "Add {'@'}types package to install commands for untyped packages",
diff --git a/lunaria/files/en-US.json b/lunaria/files/en-US.json
index 7518f7024..6fd6a7947 100644
--- a/lunaria/files/en-US.json
+++ b/lunaria/files/en-US.json
@@ -36,6 +36,7 @@
"claim_button": "Claim \"{name}\"",
"want_to_claim": "Want to claim this package name?",
"start_typing": "Start typing to search packages",
+ "algolia_disclaimer": "Powered by Algolia",
"exact_match": "exact",
"suggestion": {
"user": "user",
@@ -63,8 +64,17 @@
"sections": {
"appearance": "Appearance",
"display": "Display",
+ "search": "Data source",
"language": "Language"
},
+ "data_source": {
+ "label": "Data source",
+ "description": "Choose where npmx gets search data. Individual package pages always use the npm registry directly.",
+ "npm": "npm Registry",
+ "npm_description": "Fetches search, org and user listings directly from the official npm registry. Authoritative, but can be slower.",
+ "algolia": "Algolia",
+ "algolia_description": "Uses Algolia for faster search, org and user pages."
+ },
"relative_dates": "Relative dates",
"include_types": "Include {'@'}types in install",
"include_types_description": "Add {'@'}types package to install commands for untyped packages",
diff --git a/nuxt.config.ts b/nuxt.config.ts
index a4baaf79d..7d512685e 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -33,6 +33,14 @@ export default defineNuxtConfig({
redisRestUrl: process.env.UPSTASH_KV_REST_API_URL || process.env.KV_REST_API_URL || '',
redisRestToken: process.env.UPSTASH_KV_REST_API_TOKEN || process.env.KV_REST_API_TOKEN || '',
},
+ public: {
+ // Algolia npm-search index (maintained by Algolia & jsDelivr, used by yarnpkg.com et al.)
+ algolia: {
+ appId: 'OFCNCOG2CU',
+ apiKey: 'f54e21fa3a2a0160595bb058179bfb1e',
+ indexName: 'npm-search',
+ },
+ },
},
devtools: { enabled: true },
diff --git a/package.json b/package.json
index c8ec225ed..5c9484409 100644
--- a/package.json
+++ b/package.json
@@ -78,6 +78,7 @@
"@vueuse/nuxt": "14.2.0",
"@vueuse/router": "^14.2.0",
"@vueuse/shared": "14.2.0",
+ "algoliasearch": "5.48.0",
"defu": "6.1.4",
"fast-npm-meta": "1.0.0",
"focus-trap": "^7.8.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 50953c709..4903d2079 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -122,6 +122,9 @@ importers:
'@vueuse/shared':
specifier: 14.2.0
version: 14.2.0(vue@3.5.27(typescript@5.9.3))
+ algoliasearch:
+ specifier: 5.48.0
+ version: 5.48.0
defu:
specifier: 6.1.4
version: 6.1.4
@@ -340,6 +343,62 @@ importers:
packages:
+ '@algolia/abtesting@1.14.0':
+ resolution: {integrity: sha512-cZfj+1Z1dgrk3YPtNQNt0H9Rr67P8b4M79JjUKGS0d7/EbFbGxGgSu6zby5f22KXo3LT0LZa4O2c6VVbupJuDg==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-abtesting@5.48.0':
+ resolution: {integrity: sha512-n17WSJ7vazmM6yDkWBAjY12J8ERkW9toOqNgQ1GEZu/Kc4dJDJod1iy+QP5T/UlR3WICgZDi/7a/VX5TY5LAPQ==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-analytics@5.48.0':
+ resolution: {integrity: sha512-v5bMZMEqW9U2l40/tTAaRyn4AKrYLio7KcRuHmLaJtxuJAhvZiE7Y62XIsF070juz4MN3eyvfQmI+y5+OVbZuA==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-common@5.48.0':
+ resolution: {integrity: sha512-7H3DgRyi7UByScc0wz7EMrhgNl7fKPDjKX9OcWixLwCj7yrRXDSIzwunykuYUUO7V7HD4s319e15FlJ9CQIIFQ==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-insights@5.48.0':
+ resolution: {integrity: sha512-tXmkB6qrIGAXrtRYHQNpfW0ekru/qymV02bjT0w5QGaGw0W91yT+53WB6dTtRRsIrgS30Al6efBvyaEosjZ5uw==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-personalization@5.48.0':
+ resolution: {integrity: sha512-4tXEsrdtcBZbDF73u14Kb3otN+xUdTVGop1tBjict+Rc/FhsJQVIwJIcTrOJqmvhtBfc56Bu65FiVOnpAZCxcw==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-query-suggestions@5.48.0':
+ resolution: {integrity: sha512-unzSUwWFpsDrO8935RhMAlyK0Ttua/5XveVIwzfjs5w+GVBsHgIkbOe8VbBJccMU/z1LCwvu1AY3kffuSLAR5Q==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-search@5.48.0':
+ resolution: {integrity: sha512-RB9bKgYTVUiOcEb5bOcZ169jiiVW811dCsJoLT19DcbbFmU4QaK0ghSTssij35QBQ3SCOitXOUrHcGgNVwS7sQ==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/ingestion@1.48.0':
+ resolution: {integrity: sha512-rhoSoPu+TDzDpvpk3cY/pYgbeWXr23DxnAIH/AkN0dUC+GCnVIeNSQkLaJ+CL4NZ51cjLIjksrzb4KC5Xu+ktw==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/monitoring@1.48.0':
+ resolution: {integrity: sha512-aSe6jKvWt+8VdjOaq2ERtsXp9+qMXNJ3mTyTc1VMhNfgPl7ArOhRMRSQ8QBnY8ZL4yV5Xpezb7lAg8pdGrrulg==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/recommend@5.48.0':
+ resolution: {integrity: sha512-p9tfI1bimAaZrdiVExL/dDyGUZ8gyiSHsktP1ZWGzt5hXpM3nhv4tSjyHtXjEKtA0UvsaHKwSfFE8aAAm1eIQA==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/requester-browser-xhr@5.48.0':
+ resolution: {integrity: sha512-XshyfpsQB7BLnHseMinp3fVHOGlTv6uEHOzNK/3XrEF9mjxoZAcdVfY1OCXObfwRWX5qXZOq8FnrndFd44iVsQ==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/requester-fetch@5.48.0':
+ resolution: {integrity: sha512-Q4XNSVQU89bKNAPuvzSYqTH9AcbOOiIo6AeYMQTxgSJ2+uvT78CLPMG89RIIloYuAtSfE07s40OLV50++l1Bbw==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/requester-node-http@5.48.0':
+ resolution: {integrity: sha512-ZgxV2+5qt3NLeUYBTsi6PLyHcENQWC0iFppFZekHSEDA2wcLdTUjnaJzimTEULHIvJuLRCkUs4JABdhuJktEag==}
+ engines: {node: '>= 14.0.0'}
+
'@alloc/quick-lru@5.2.0':
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
@@ -483,6 +542,10 @@ packages:
resolution: {integrity: sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==}
engines: {node: '>=6.9.0'}
+ '@babel/compat-data@7.29.0':
+ resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==}
+ engines: {node: '>=6.9.0'}
+
'@babel/core@7.29.0':
resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==}
engines: {node: '>=6.9.0'}
@@ -677,8 +740,8 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
- '@babel/plugin-transform-async-generator-functions@7.28.6':
- resolution: {integrity: sha512-9knsChgsMzBV5Yh3kkhrZNxH3oCYAfMBkNNaVN4cP2RVlFPe8wYdwwcnOsAbkdDoV9UjFtOXWrWB52M8W4jNeA==}
+ '@babel/plugin-transform-async-generator-functions@7.29.0':
+ resolution: {integrity: sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -743,8 +806,8 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
- '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.28.6':
- resolution: {integrity: sha512-5suVoXjC14lUN6ZL9OLKIHCNVWCrqGqlmEp/ixdXjvgnEl/kauLvvMO/Xw9NyMc95Joj1AeLVPVMvibBgSoFlA==}
+ '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0':
+ resolution: {integrity: sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
@@ -821,8 +884,8 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
- '@babel/plugin-transform-modules-systemjs@7.28.5':
- resolution: {integrity: sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==}
+ '@babel/plugin-transform-modules-systemjs@7.29.0':
+ resolution: {integrity: sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -833,8 +896,8 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
- '@babel/plugin-transform-named-capturing-groups-regex@7.27.1':
- resolution: {integrity: sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==}
+ '@babel/plugin-transform-named-capturing-groups-regex@7.29.0':
+ resolution: {integrity: sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
@@ -905,8 +968,8 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
- '@babel/plugin-transform-regenerator@7.28.6':
- resolution: {integrity: sha512-eZhoEZHYQLL5uc1gS5e9/oTknS0sSSAtd5TkKMUp3J+S/CaUjagc0kOUPsEbDmMeva0nC3WWl4SxVY6+OBuxfw==}
+ '@babel/plugin-transform-regenerator@7.29.0':
+ resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -983,8 +1046,8 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0
- '@babel/preset-env@7.28.6':
- resolution: {integrity: sha512-GaTI4nXDrs7l0qaJ6Rg06dtOXTBCG6TMDB44zbqofCIC4PqC7SEvmFFtpxzCDw9W5aJ7RKVshgXTLvLdBFV/qw==}
+ '@babel/preset-env@7.29.0':
+ resolution: {integrity: sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -1747,10 +1810,18 @@ packages:
resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==}
engines: {node: 20 || >=22}
+ '@isaacs/brace-expansion@5.0.1':
+ resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==}
+ engines: {node: 20 || >=22}
+
'@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
+ '@isaacs/cliui@9.0.0':
+ resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==}
+ engines: {node: '>=18'}
+
'@isaacs/fs-minipass@4.0.1':
resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
engines: {node: '>=18.0.0'}
@@ -4575,6 +4646,10 @@ packages:
ajv@8.17.1:
resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
+ algoliasearch@5.48.0:
+ resolution: {integrity: sha512-aD8EQC6KEman6/S79FtPdQmB7D4af/etcRL/KwiKFKgAE62iU8c5PeEQvpvIcBPurC3O/4Lj78nOl7ZcoazqSw==}
+ engines: {node: '>= 14.0.0'}
+
alien-signals@3.1.2:
resolution: {integrity: sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw==}
@@ -4707,8 +4782,8 @@ packages:
peerDependencies:
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
- babel-plugin-polyfill-corejs3@0.13.0:
- resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==}
+ babel-plugin-polyfill-corejs3@0.14.0:
+ resolution: {integrity: sha512-AvDcMxJ34W4Wgy4KBIIePQTAOP1Ie2WFwkQp3dB7FQ/f0lI5+nM96zUnYEOE1P9sEg0es5VCP0HxiWu5fUHZAQ==}
peerDependencies:
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
@@ -5437,6 +5512,10 @@ packages:
resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==}
engines: {node: '>=10.13.0'}
+ enhanced-resolve@5.19.0:
+ resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==}
+ engines: {node: '>=10.13.0'}
+
entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
@@ -6499,8 +6578,8 @@ packages:
jackspeak@3.4.3:
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
- jackspeak@4.1.1:
- resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==}
+ jackspeak@4.2.3:
+ resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==}
engines: {node: 20 || >=22}
jake@10.9.4:
@@ -7121,6 +7200,10 @@ packages:
resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==}
engines: {node: 20 || >=22}
+ minimatch@10.1.2:
+ resolution: {integrity: sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==}
+ engines: {node: 20 || >=22}
+
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -9646,6 +9729,90 @@ packages:
snapshots:
+ '@algolia/abtesting@1.14.0':
+ dependencies:
+ '@algolia/client-common': 5.48.0
+ '@algolia/requester-browser-xhr': 5.48.0
+ '@algolia/requester-fetch': 5.48.0
+ '@algolia/requester-node-http': 5.48.0
+
+ '@algolia/client-abtesting@5.48.0':
+ dependencies:
+ '@algolia/client-common': 5.48.0
+ '@algolia/requester-browser-xhr': 5.48.0
+ '@algolia/requester-fetch': 5.48.0
+ '@algolia/requester-node-http': 5.48.0
+
+ '@algolia/client-analytics@5.48.0':
+ dependencies:
+ '@algolia/client-common': 5.48.0
+ '@algolia/requester-browser-xhr': 5.48.0
+ '@algolia/requester-fetch': 5.48.0
+ '@algolia/requester-node-http': 5.48.0
+
+ '@algolia/client-common@5.48.0': {}
+
+ '@algolia/client-insights@5.48.0':
+ dependencies:
+ '@algolia/client-common': 5.48.0
+ '@algolia/requester-browser-xhr': 5.48.0
+ '@algolia/requester-fetch': 5.48.0
+ '@algolia/requester-node-http': 5.48.0
+
+ '@algolia/client-personalization@5.48.0':
+ dependencies:
+ '@algolia/client-common': 5.48.0
+ '@algolia/requester-browser-xhr': 5.48.0
+ '@algolia/requester-fetch': 5.48.0
+ '@algolia/requester-node-http': 5.48.0
+
+ '@algolia/client-query-suggestions@5.48.0':
+ dependencies:
+ '@algolia/client-common': 5.48.0
+ '@algolia/requester-browser-xhr': 5.48.0
+ '@algolia/requester-fetch': 5.48.0
+ '@algolia/requester-node-http': 5.48.0
+
+ '@algolia/client-search@5.48.0':
+ dependencies:
+ '@algolia/client-common': 5.48.0
+ '@algolia/requester-browser-xhr': 5.48.0
+ '@algolia/requester-fetch': 5.48.0
+ '@algolia/requester-node-http': 5.48.0
+
+ '@algolia/ingestion@1.48.0':
+ dependencies:
+ '@algolia/client-common': 5.48.0
+ '@algolia/requester-browser-xhr': 5.48.0
+ '@algolia/requester-fetch': 5.48.0
+ '@algolia/requester-node-http': 5.48.0
+
+ '@algolia/monitoring@1.48.0':
+ dependencies:
+ '@algolia/client-common': 5.48.0
+ '@algolia/requester-browser-xhr': 5.48.0
+ '@algolia/requester-fetch': 5.48.0
+ '@algolia/requester-node-http': 5.48.0
+
+ '@algolia/recommend@5.48.0':
+ dependencies:
+ '@algolia/client-common': 5.48.0
+ '@algolia/requester-browser-xhr': 5.48.0
+ '@algolia/requester-fetch': 5.48.0
+ '@algolia/requester-node-http': 5.48.0
+
+ '@algolia/requester-browser-xhr@5.48.0':
+ dependencies:
+ '@algolia/client-common': 5.48.0
+
+ '@algolia/requester-fetch@5.48.0':
+ dependencies:
+ '@algolia/client-common': 5.48.0
+
+ '@algolia/requester-node-http@5.48.0':
+ dependencies:
+ '@algolia/client-common': 5.48.0
+
'@alloc/quick-lru@5.2.0': {}
'@antfu/install-pkg@1.1.0':
@@ -9932,6 +10099,8 @@ snapshots:
'@babel/compat-data@7.28.6': {}
+ '@babel/compat-data@7.29.0': {}
+
'@babel/core@7.29.0':
dependencies:
'@babel/code-frame': 7.29.0
@@ -10173,7 +10342,7 @@ snapshots:
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
- '@babel/plugin-transform-async-generator-functions@7.28.6(@babel/core@7.29.0)':
+ '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
@@ -10254,7 +10423,7 @@ snapshots:
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
- '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.28.6(@babel/core@7.29.0)':
+ '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.29.0
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0)
@@ -10336,7 +10505,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@babel/plugin-transform-modules-systemjs@7.28.5(@babel/core@7.29.0)':
+ '@babel/plugin-transform-modules-systemjs@7.29.0(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.29.0
'@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0)
@@ -10354,7 +10523,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.29.0)':
+ '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.29.0
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0)
@@ -10434,7 +10603,7 @@ snapshots:
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
- '@babel/plugin-transform-regenerator@7.28.6(@babel/core@7.29.0)':
+ '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
@@ -10512,9 +10681,9 @@ snapshots:
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0)
'@babel/helper-plugin-utils': 7.28.6
- '@babel/preset-env@7.28.6(@babel/core@7.29.0)':
+ '@babel/preset-env@7.29.0(@babel/core@7.29.0)':
dependencies:
- '@babel/compat-data': 7.28.6
+ '@babel/compat-data': 7.29.0
'@babel/core': 7.29.0
'@babel/helper-compilation-targets': 7.28.6
'@babel/helper-plugin-utils': 7.28.6
@@ -10529,7 +10698,7 @@ snapshots:
'@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0)
'@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0)
'@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0)
- '@babel/plugin-transform-async-generator-functions': 7.28.6(@babel/core@7.29.0)
+ '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0)
'@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0)
'@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0)
'@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0)
@@ -10540,7 +10709,7 @@ snapshots:
'@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0)
'@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0)
'@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0)
- '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.28.6(@babel/core@7.29.0)
+ '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0)
'@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0)
'@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0)
'@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0)
@@ -10553,9 +10722,9 @@ snapshots:
'@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0)
'@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0)
'@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0)
- '@babel/plugin-transform-modules-systemjs': 7.28.5(@babel/core@7.29.0)
+ '@babel/plugin-transform-modules-systemjs': 7.29.0(@babel/core@7.29.0)
'@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0)
- '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.29.0)
+ '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0)
'@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0)
'@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0)
'@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0)
@@ -10567,7 +10736,7 @@ snapshots:
'@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0)
'@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0)
'@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0)
- '@babel/plugin-transform-regenerator': 7.28.6(@babel/core@7.29.0)
+ '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0)
'@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0)
'@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0)
'@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0)
@@ -10581,7 +10750,7 @@ snapshots:
'@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0)
'@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0)
babel-plugin-polyfill-corejs2: 0.4.15(@babel/core@7.29.0)
- babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0)
+ babel-plugin-polyfill-corejs3: 0.14.0(@babel/core@7.29.0)
babel-plugin-polyfill-regenerator: 0.6.6(@babel/core@7.29.0)
core-js-compat: 3.48.0
semver: 6.3.1
@@ -11182,6 +11351,10 @@ snapshots:
dependencies:
'@isaacs/balanced-match': 4.0.1
+ '@isaacs/brace-expansion@5.0.1':
+ dependencies:
+ '@isaacs/balanced-match': 4.0.1
+
'@isaacs/cliui@8.0.2':
dependencies:
string-width: 5.1.2
@@ -11191,6 +11364,8 @@ snapshots:
wrap-ansi: 8.1.0
wrap-ansi-cjs: wrap-ansi@7.0.0
+ '@isaacs/cliui@9.0.0': {}
+
'@isaacs/fs-minipass@4.0.1':
dependencies:
minipass: 7.1.2
@@ -14539,6 +14714,23 @@ snapshots:
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
+ algoliasearch@5.48.0:
+ dependencies:
+ '@algolia/abtesting': 1.14.0
+ '@algolia/client-abtesting': 5.48.0
+ '@algolia/client-analytics': 5.48.0
+ '@algolia/client-common': 5.48.0
+ '@algolia/client-insights': 5.48.0
+ '@algolia/client-personalization': 5.48.0
+ '@algolia/client-query-suggestions': 5.48.0
+ '@algolia/client-search': 5.48.0
+ '@algolia/ingestion': 1.48.0
+ '@algolia/monitoring': 1.48.0
+ '@algolia/recommend': 5.48.0
+ '@algolia/requester-browser-xhr': 5.48.0
+ '@algolia/requester-fetch': 5.48.0
+ '@algolia/requester-node-http': 5.48.0
+
alien-signals@3.1.2: {}
ansi-escapes@7.2.0:
@@ -14689,14 +14881,14 @@ snapshots:
babel-plugin-polyfill-corejs2@0.4.15(@babel/core@7.29.0):
dependencies:
- '@babel/compat-data': 7.28.6
+ '@babel/compat-data': 7.29.0
'@babel/core': 7.29.0
'@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0)
semver: 6.3.1
transitivePeerDependencies:
- supports-color
- babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0):
+ babel-plugin-polyfill-corejs3@0.14.0(@babel/core@7.29.0):
dependencies:
'@babel/core': 7.29.0
'@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0)
@@ -15479,6 +15671,11 @@ snapshots:
graceful-fs: 4.2.11
tapable: 2.3.0
+ enhanced-resolve@5.19.0:
+ dependencies:
+ graceful-fs: 4.2.11
+ tapable: 2.3.0
+
entities@4.5.0: {}
entities@6.0.1: {}
@@ -16206,8 +16403,8 @@ snapshots:
glob@11.1.0:
dependencies:
foreground-child: 3.3.1
- jackspeak: 4.1.1
- minimatch: 10.1.1
+ jackspeak: 4.2.3
+ minimatch: 10.1.2
minipass: 7.1.2
package-json-from-dist: 1.0.1
path-scurry: 2.0.1
@@ -16878,9 +17075,9 @@ snapshots:
optionalDependencies:
'@pkgjs/parseargs': 0.11.0
- jackspeak@4.1.1:
+ jackspeak@4.2.3:
dependencies:
- '@isaacs/cliui': 8.0.2
+ '@isaacs/cliui': 9.0.0
jake@10.9.4:
dependencies:
@@ -17636,6 +17833,10 @@ snapshots:
dependencies:
'@isaacs/brace-expansion': 5.0.0
+ minimatch@10.1.2:
+ dependencies:
+ '@isaacs/brace-expansion': 5.0.1
+
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.12
@@ -20903,7 +21104,7 @@ snapshots:
acorn-import-phases: 1.0.4(acorn@8.15.0)
browserslist: 4.28.1
chrome-trace-event: 1.0.4
- enhanced-resolve: 5.18.4
+ enhanced-resolve: 5.19.0
es-module-lexer: 2.0.0
eslint-scope: 5.1.1
events: 3.3.0
@@ -21003,7 +21204,7 @@ snapshots:
dependencies:
'@apideck/better-ajv-errors': 0.3.6(ajv@8.17.1)
'@babel/core': 7.29.0
- '@babel/preset-env': 7.28.6(@babel/core@7.29.0)
+ '@babel/preset-env': 7.29.0(@babel/core@7.29.0)
'@babel/runtime': 7.28.6
'@rollup/plugin-babel': 5.3.1(@babel/core@7.29.0)(rollup@2.79.2)
'@rollup/plugin-node-resolve': 15.3.1(rollup@2.79.2)
diff --git a/test/nuxt/a11y.spec.ts b/test/nuxt/a11y.spec.ts
index cc270bd51..17774db29 100644
--- a/test/nuxt/a11y.spec.ts
+++ b/test/nuxt/a11y.spec.ts
@@ -138,6 +138,7 @@ import {
ProvenanceBadge,
Readme,
ReadmeTocDropdown,
+ SearchProviderToggle,
SearchSuggestionCard,
SettingsAccentColorPicker,
SettingsBgThemePicker,
@@ -159,6 +160,7 @@ import {
import HeaderAccountMenuServer from '~/components/Header/AccountMenu.server.vue'
import ToggleServer from '~/components/Settings/Toggle.server.vue'
import PackageDownloadAnalytics from '~/components/Package/DownloadAnalytics.vue'
+import SearchProviderToggleServer from '~/components/SearchProviderToggle.server.vue'
describe('component accessibility audits', () => {
describe('DateTime', () => {
@@ -2165,6 +2167,22 @@ describe('component accessibility audits', () => {
})
})
+ describe('SearchProviderToggle', () => {
+ it('should have no accessibility violations', async () => {
+ const component = await mountSuspended(SearchProviderToggle)
+ const results = await runAxe(component)
+ expect(results.violations).toEqual([])
+ })
+ })
+
+ describe('SearchProviderToggle.server', () => {
+ it('should have no accessibility violations', async () => {
+ const component = await mountSuspended(SearchProviderToggleServer)
+ const results = await runAxe(component)
+ expect(results.violations).toEqual([])
+ })
+ })
+
describe('Toggle.server', () => {
it('should have no accessibility violations', async () => {
const component = await mountSuspended(ToggleServer, {
{{ error?.message ?? $t('user.page.failed_to_load') }}
@@ -260,7 +218,7 @@ defineOgImageComponent('Default', { v-else :results="filteredAndSortedPackages" :has-more="hasMore" - :is-loading="isLoadingMore || (status === 'pending' && currentPage > 1)" + :is-loading="isLoadingMore" :page-size="pageSize" :initial-page="initialPage" @load-more="loadMore" diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 7518f7024..6fd6a7947 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -36,6 +36,7 @@ "claim_button": "Claim \"{name}\"", "want_to_claim": "Want to claim this package name?", "start_typing": "Start typing to search packages", + "algolia_disclaimer": "Powered by Algolia", "exact_match": "exact", "suggestion": { "user": "user", @@ -63,8 +64,17 @@ "sections": { "appearance": "Appearance", "display": "Display", + "search": "Data source", "language": "Language" }, + "data_source": { + "label": "Data source", + "description": "Choose where npmx gets search data. Individual package pages always use the npm registry directly.", + "npm": "npm Registry", + "npm_description": "Fetches search, org and user listings directly from the official npm registry. Authoritative, but can be slower.", + "algolia": "Algolia", + "algolia_description": "Uses Algolia for faster search, org and user pages." + }, "relative_dates": "Relative dates", "include_types": "Include {'@'}types in install", "include_types_description": "Add {'@'}types package to install commands for untyped packages", diff --git a/lunaria/files/en-GB.json b/lunaria/files/en-GB.json index fe8c669e7..22d33f0a5 100644 --- a/lunaria/files/en-GB.json +++ b/lunaria/files/en-GB.json @@ -36,6 +36,7 @@ "claim_button": "Claim \"{name}\"", "want_to_claim": "Want to claim this package name?", "start_typing": "Start typing to search packages", + "algolia_disclaimer": "Powered by Algolia", "exact_match": "exact", "suggestion": { "user": "user", @@ -63,8 +64,17 @@ "sections": { "appearance": "Appearance", "display": "Display", + "search": "Data source", "language": "Language" }, + "data_source": { + "label": "Data source", + "description": "Choose where npmx gets search data. Individual package pages always use the npm registry directly.", + "npm": "npm Registry", + "npm_description": "Fetches search, org and user listings directly from the official npm registry. Authoritative, but can be slower.", + "algolia": "Algolia", + "algolia_description": "Uses Algolia for faster search, org and user pages." + }, "relative_dates": "Relative dates", "include_types": "Include {'@'}types in install", "include_types_description": "Add {'@'}types package to install commands for untyped packages", diff --git a/lunaria/files/en-US.json b/lunaria/files/en-US.json index 7518f7024..6fd6a7947 100644 --- a/lunaria/files/en-US.json +++ b/lunaria/files/en-US.json @@ -36,6 +36,7 @@ "claim_button": "Claim \"{name}\"", "want_to_claim": "Want to claim this package name?", "start_typing": "Start typing to search packages", + "algolia_disclaimer": "Powered by Algolia", "exact_match": "exact", "suggestion": { "user": "user", @@ -63,8 +64,17 @@ "sections": { "appearance": "Appearance", "display": "Display", + "search": "Data source", "language": "Language" }, + "data_source": { + "label": "Data source", + "description": "Choose where npmx gets search data. Individual package pages always use the npm registry directly.", + "npm": "npm Registry", + "npm_description": "Fetches search, org and user listings directly from the official npm registry. Authoritative, but can be slower.", + "algolia": "Algolia", + "algolia_description": "Uses Algolia for faster search, org and user pages." + }, "relative_dates": "Relative dates", "include_types": "Include {'@'}types in install", "include_types_description": "Add {'@'}types package to install commands for untyped packages", diff --git a/nuxt.config.ts b/nuxt.config.ts index a4baaf79d..7d512685e 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -33,6 +33,14 @@ export default defineNuxtConfig({ redisRestUrl: process.env.UPSTASH_KV_REST_API_URL || process.env.KV_REST_API_URL || '', redisRestToken: process.env.UPSTASH_KV_REST_API_TOKEN || process.env.KV_REST_API_TOKEN || '', }, + public: { + // Algolia npm-search index (maintained by Algolia & jsDelivr, used by yarnpkg.com et al.) + algolia: { + appId: 'OFCNCOG2CU', + apiKey: 'f54e21fa3a2a0160595bb058179bfb1e', + indexName: 'npm-search', + }, + }, }, devtools: { enabled: true }, diff --git a/package.json b/package.json index c8ec225ed..5c9484409 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "@vueuse/nuxt": "14.2.0", "@vueuse/router": "^14.2.0", "@vueuse/shared": "14.2.0", + "algoliasearch": "5.48.0", "defu": "6.1.4", "fast-npm-meta": "1.0.0", "focus-trap": "^7.8.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 50953c709..4903d2079 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -122,6 +122,9 @@ importers: '@vueuse/shared': specifier: 14.2.0 version: 14.2.0(vue@3.5.27(typescript@5.9.3)) + algoliasearch: + specifier: 5.48.0 + version: 5.48.0 defu: specifier: 6.1.4 version: 6.1.4 @@ -340,6 +343,62 @@ importers: packages: + '@algolia/abtesting@1.14.0': + resolution: {integrity: sha512-cZfj+1Z1dgrk3YPtNQNt0H9Rr67P8b4M79JjUKGS0d7/EbFbGxGgSu6zby5f22KXo3LT0LZa4O2c6VVbupJuDg==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-abtesting@5.48.0': + resolution: {integrity: sha512-n17WSJ7vazmM6yDkWBAjY12J8ERkW9toOqNgQ1GEZu/Kc4dJDJod1iy+QP5T/UlR3WICgZDi/7a/VX5TY5LAPQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-analytics@5.48.0': + resolution: {integrity: sha512-v5bMZMEqW9U2l40/tTAaRyn4AKrYLio7KcRuHmLaJtxuJAhvZiE7Y62XIsF070juz4MN3eyvfQmI+y5+OVbZuA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-common@5.48.0': + resolution: {integrity: sha512-7H3DgRyi7UByScc0wz7EMrhgNl7fKPDjKX9OcWixLwCj7yrRXDSIzwunykuYUUO7V7HD4s319e15FlJ9CQIIFQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-insights@5.48.0': + resolution: {integrity: sha512-tXmkB6qrIGAXrtRYHQNpfW0ekru/qymV02bjT0w5QGaGw0W91yT+53WB6dTtRRsIrgS30Al6efBvyaEosjZ5uw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-personalization@5.48.0': + resolution: {integrity: sha512-4tXEsrdtcBZbDF73u14Kb3otN+xUdTVGop1tBjict+Rc/FhsJQVIwJIcTrOJqmvhtBfc56Bu65FiVOnpAZCxcw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-query-suggestions@5.48.0': + resolution: {integrity: sha512-unzSUwWFpsDrO8935RhMAlyK0Ttua/5XveVIwzfjs5w+GVBsHgIkbOe8VbBJccMU/z1LCwvu1AY3kffuSLAR5Q==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-search@5.48.0': + resolution: {integrity: sha512-RB9bKgYTVUiOcEb5bOcZ169jiiVW811dCsJoLT19DcbbFmU4QaK0ghSTssij35QBQ3SCOitXOUrHcGgNVwS7sQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/ingestion@1.48.0': + resolution: {integrity: sha512-rhoSoPu+TDzDpvpk3cY/pYgbeWXr23DxnAIH/AkN0dUC+GCnVIeNSQkLaJ+CL4NZ51cjLIjksrzb4KC5Xu+ktw==} + engines: {node: '>= 14.0.0'} + + '@algolia/monitoring@1.48.0': + resolution: {integrity: sha512-aSe6jKvWt+8VdjOaq2ERtsXp9+qMXNJ3mTyTc1VMhNfgPl7ArOhRMRSQ8QBnY8ZL4yV5Xpezb7lAg8pdGrrulg==} + engines: {node: '>= 14.0.0'} + + '@algolia/recommend@5.48.0': + resolution: {integrity: sha512-p9tfI1bimAaZrdiVExL/dDyGUZ8gyiSHsktP1ZWGzt5hXpM3nhv4tSjyHtXjEKtA0UvsaHKwSfFE8aAAm1eIQA==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-browser-xhr@5.48.0': + resolution: {integrity: sha512-XshyfpsQB7BLnHseMinp3fVHOGlTv6uEHOzNK/3XrEF9mjxoZAcdVfY1OCXObfwRWX5qXZOq8FnrndFd44iVsQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-fetch@5.48.0': + resolution: {integrity: sha512-Q4XNSVQU89bKNAPuvzSYqTH9AcbOOiIo6AeYMQTxgSJ2+uvT78CLPMG89RIIloYuAtSfE07s40OLV50++l1Bbw==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-node-http@5.48.0': + resolution: {integrity: sha512-ZgxV2+5qt3NLeUYBTsi6PLyHcENQWC0iFppFZekHSEDA2wcLdTUjnaJzimTEULHIvJuLRCkUs4JABdhuJktEag==} + engines: {node: '>= 14.0.0'} + '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -483,6 +542,10 @@ packages: resolution: {integrity: sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + '@babel/core@7.29.0': resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} engines: {node: '>=6.9.0'} @@ -677,8 +740,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-generator-functions@7.28.6': - resolution: {integrity: sha512-9knsChgsMzBV5Yh3kkhrZNxH3oCYAfMBkNNaVN4cP2RVlFPe8wYdwwcnOsAbkdDoV9UjFtOXWrWB52M8W4jNeA==} + '@babel/plugin-transform-async-generator-functions@7.29.0': + resolution: {integrity: sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -743,8 +806,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.28.6': - resolution: {integrity: sha512-5suVoXjC14lUN6ZL9OLKIHCNVWCrqGqlmEp/ixdXjvgnEl/kauLvvMO/Xw9NyMc95Joj1AeLVPVMvibBgSoFlA==} + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -821,8 +884,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-systemjs@7.28.5': - resolution: {integrity: sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==} + '@babel/plugin-transform-modules-systemjs@7.29.0': + resolution: {integrity: sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -833,8 +896,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1': - resolution: {integrity: sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==} + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -905,8 +968,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.28.6': - resolution: {integrity: sha512-eZhoEZHYQLL5uc1gS5e9/oTknS0sSSAtd5TkKMUp3J+S/CaUjagc0kOUPsEbDmMeva0nC3WWl4SxVY6+OBuxfw==} + '@babel/plugin-transform-regenerator@7.29.0': + resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -983,8 +1046,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/preset-env@7.28.6': - resolution: {integrity: sha512-GaTI4nXDrs7l0qaJ6Rg06dtOXTBCG6TMDB44zbqofCIC4PqC7SEvmFFtpxzCDw9W5aJ7RKVshgXTLvLdBFV/qw==} + '@babel/preset-env@7.29.0': + resolution: {integrity: sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1747,10 +1810,18 @@ packages: resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} engines: {node: 20 || >=22} + '@isaacs/brace-expansion@5.0.1': + resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==} + engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/cliui@9.0.0': + resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==} + engines: {node: '>=18'} + '@isaacs/fs-minipass@4.0.1': resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} @@ -4575,6 +4646,10 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + algoliasearch@5.48.0: + resolution: {integrity: sha512-aD8EQC6KEman6/S79FtPdQmB7D4af/etcRL/KwiKFKgAE62iU8c5PeEQvpvIcBPurC3O/4Lj78nOl7ZcoazqSw==} + engines: {node: '>= 14.0.0'} + alien-signals@3.1.2: resolution: {integrity: sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw==} @@ -4707,8 +4782,8 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-corejs3@0.13.0: - resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==} + babel-plugin-polyfill-corejs3@0.14.0: + resolution: {integrity: sha512-AvDcMxJ34W4Wgy4KBIIePQTAOP1Ie2WFwkQp3dB7FQ/f0lI5+nM96zUnYEOE1P9sEg0es5VCP0HxiWu5fUHZAQ==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -5437,6 +5512,10 @@ packages: resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} engines: {node: '>=10.13.0'} + enhanced-resolve@5.19.0: + resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} + engines: {node: '>=10.13.0'} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -6499,8 +6578,8 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jackspeak@4.1.1: - resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} + jackspeak@4.2.3: + resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==} engines: {node: 20 || >=22} jake@10.9.4: @@ -7121,6 +7200,10 @@ packages: resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} engines: {node: 20 || >=22} + minimatch@10.1.2: + resolution: {integrity: sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -9646,6 +9729,90 @@ packages: snapshots: + '@algolia/abtesting@1.14.0': + dependencies: + '@algolia/client-common': 5.48.0 + '@algolia/requester-browser-xhr': 5.48.0 + '@algolia/requester-fetch': 5.48.0 + '@algolia/requester-node-http': 5.48.0 + + '@algolia/client-abtesting@5.48.0': + dependencies: + '@algolia/client-common': 5.48.0 + '@algolia/requester-browser-xhr': 5.48.0 + '@algolia/requester-fetch': 5.48.0 + '@algolia/requester-node-http': 5.48.0 + + '@algolia/client-analytics@5.48.0': + dependencies: + '@algolia/client-common': 5.48.0 + '@algolia/requester-browser-xhr': 5.48.0 + '@algolia/requester-fetch': 5.48.0 + '@algolia/requester-node-http': 5.48.0 + + '@algolia/client-common@5.48.0': {} + + '@algolia/client-insights@5.48.0': + dependencies: + '@algolia/client-common': 5.48.0 + '@algolia/requester-browser-xhr': 5.48.0 + '@algolia/requester-fetch': 5.48.0 + '@algolia/requester-node-http': 5.48.0 + + '@algolia/client-personalization@5.48.0': + dependencies: + '@algolia/client-common': 5.48.0 + '@algolia/requester-browser-xhr': 5.48.0 + '@algolia/requester-fetch': 5.48.0 + '@algolia/requester-node-http': 5.48.0 + + '@algolia/client-query-suggestions@5.48.0': + dependencies: + '@algolia/client-common': 5.48.0 + '@algolia/requester-browser-xhr': 5.48.0 + '@algolia/requester-fetch': 5.48.0 + '@algolia/requester-node-http': 5.48.0 + + '@algolia/client-search@5.48.0': + dependencies: + '@algolia/client-common': 5.48.0 + '@algolia/requester-browser-xhr': 5.48.0 + '@algolia/requester-fetch': 5.48.0 + '@algolia/requester-node-http': 5.48.0 + + '@algolia/ingestion@1.48.0': + dependencies: + '@algolia/client-common': 5.48.0 + '@algolia/requester-browser-xhr': 5.48.0 + '@algolia/requester-fetch': 5.48.0 + '@algolia/requester-node-http': 5.48.0 + + '@algolia/monitoring@1.48.0': + dependencies: + '@algolia/client-common': 5.48.0 + '@algolia/requester-browser-xhr': 5.48.0 + '@algolia/requester-fetch': 5.48.0 + '@algolia/requester-node-http': 5.48.0 + + '@algolia/recommend@5.48.0': + dependencies: + '@algolia/client-common': 5.48.0 + '@algolia/requester-browser-xhr': 5.48.0 + '@algolia/requester-fetch': 5.48.0 + '@algolia/requester-node-http': 5.48.0 + + '@algolia/requester-browser-xhr@5.48.0': + dependencies: + '@algolia/client-common': 5.48.0 + + '@algolia/requester-fetch@5.48.0': + dependencies: + '@algolia/client-common': 5.48.0 + + '@algolia/requester-node-http@5.48.0': + dependencies: + '@algolia/client-common': 5.48.0 + '@alloc/quick-lru@5.2.0': {} '@antfu/install-pkg@1.1.0': @@ -9932,6 +10099,8 @@ snapshots: '@babel/compat-data@7.28.6': {} + '@babel/compat-data@7.29.0': {} + '@babel/core@7.29.0': dependencies: '@babel/code-frame': 7.29.0 @@ -10173,7 +10342,7 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-async-generator-functions@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 @@ -10254,7 +10423,7 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) @@ -10336,7 +10505,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.28.5(@babel/core@7.29.0)': + '@babel/plugin-transform-modules-systemjs@7.29.0(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) @@ -10354,7 +10523,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) @@ -10434,7 +10603,7 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-regenerator@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 @@ -10512,9 +10681,9 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 - '@babel/preset-env@7.28.6(@babel/core@7.29.0)': + '@babel/preset-env@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/compat-data': 7.28.6 + '@babel/compat-data': 7.29.0 '@babel/core': 7.29.0 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 @@ -10529,7 +10698,7 @@ snapshots: '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-async-generator-functions': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0) '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) @@ -10540,7 +10709,7 @@ snapshots: '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0) '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0) @@ -10553,9 +10722,9 @@ snapshots: '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-modules-systemjs': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-modules-systemjs': 7.29.0(@babel/core@7.29.0) '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) @@ -10567,7 +10736,7 @@ snapshots: '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-regenerator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0) '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0) '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) @@ -10581,7 +10750,7 @@ snapshots: '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) babel-plugin-polyfill-corejs2: 0.4.15(@babel/core@7.29.0) - babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.14.0(@babel/core@7.29.0) babel-plugin-polyfill-regenerator: 0.6.6(@babel/core@7.29.0) core-js-compat: 3.48.0 semver: 6.3.1 @@ -11182,6 +11351,10 @@ snapshots: dependencies: '@isaacs/balanced-match': 4.0.1 + '@isaacs/brace-expansion@5.0.1': + dependencies: + '@isaacs/balanced-match': 4.0.1 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -11191,6 +11364,8 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/cliui@9.0.0': {} + '@isaacs/fs-minipass@4.0.1': dependencies: minipass: 7.1.2 @@ -14539,6 +14714,23 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 + algoliasearch@5.48.0: + dependencies: + '@algolia/abtesting': 1.14.0 + '@algolia/client-abtesting': 5.48.0 + '@algolia/client-analytics': 5.48.0 + '@algolia/client-common': 5.48.0 + '@algolia/client-insights': 5.48.0 + '@algolia/client-personalization': 5.48.0 + '@algolia/client-query-suggestions': 5.48.0 + '@algolia/client-search': 5.48.0 + '@algolia/ingestion': 1.48.0 + '@algolia/monitoring': 1.48.0 + '@algolia/recommend': 5.48.0 + '@algolia/requester-browser-xhr': 5.48.0 + '@algolia/requester-fetch': 5.48.0 + '@algolia/requester-node-http': 5.48.0 + alien-signals@3.1.2: {} ansi-escapes@7.2.0: @@ -14689,14 +14881,14 @@ snapshots: babel-plugin-polyfill-corejs2@0.4.15(@babel/core@7.29.0): dependencies: - '@babel/compat-data': 7.28.6 + '@babel/compat-data': 7.29.0 '@babel/core': 7.29.0 '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): + babel-plugin-polyfill-corejs3@0.14.0(@babel/core@7.29.0): dependencies: '@babel/core': 7.29.0 '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) @@ -15479,6 +15671,11 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.3.0 + enhanced-resolve@5.19.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + entities@4.5.0: {} entities@6.0.1: {} @@ -16206,8 +16403,8 @@ snapshots: glob@11.1.0: dependencies: foreground-child: 3.3.1 - jackspeak: 4.1.1 - minimatch: 10.1.1 + jackspeak: 4.2.3 + minimatch: 10.1.2 minipass: 7.1.2 package-json-from-dist: 1.0.1 path-scurry: 2.0.1 @@ -16878,9 +17075,9 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 - jackspeak@4.1.1: + jackspeak@4.2.3: dependencies: - '@isaacs/cliui': 8.0.2 + '@isaacs/cliui': 9.0.0 jake@10.9.4: dependencies: @@ -17636,6 +17833,10 @@ snapshots: dependencies: '@isaacs/brace-expansion': 5.0.0 + minimatch@10.1.2: + dependencies: + '@isaacs/brace-expansion': 5.0.1 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 @@ -20903,7 +21104,7 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.15.0) browserslist: 4.28.1 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.18.4 + enhanced-resolve: 5.19.0 es-module-lexer: 2.0.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -21003,7 +21204,7 @@ snapshots: dependencies: '@apideck/better-ajv-errors': 0.3.6(ajv@8.17.1) '@babel/core': 7.29.0 - '@babel/preset-env': 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': 7.29.0(@babel/core@7.29.0) '@babel/runtime': 7.28.6 '@rollup/plugin-babel': 5.3.1(@babel/core@7.29.0)(rollup@2.79.2) '@rollup/plugin-node-resolve': 15.3.1(rollup@2.79.2) diff --git a/test/nuxt/a11y.spec.ts b/test/nuxt/a11y.spec.ts index cc270bd51..17774db29 100644 --- a/test/nuxt/a11y.spec.ts +++ b/test/nuxt/a11y.spec.ts @@ -138,6 +138,7 @@ import { ProvenanceBadge, Readme, ReadmeTocDropdown, + SearchProviderToggle, SearchSuggestionCard, SettingsAccentColorPicker, SettingsBgThemePicker, @@ -159,6 +160,7 @@ import { import HeaderAccountMenuServer from '~/components/Header/AccountMenu.server.vue' import ToggleServer from '~/components/Settings/Toggle.server.vue' import PackageDownloadAnalytics from '~/components/Package/DownloadAnalytics.vue' +import SearchProviderToggleServer from '~/components/SearchProviderToggle.server.vue' describe('component accessibility audits', () => { describe('DateTime', () => { @@ -2165,6 +2167,22 @@ describe('component accessibility audits', () => { }) }) + describe('SearchProviderToggle', () => { + it('should have no accessibility violations', async () => { + const component = await mountSuspended(SearchProviderToggle) + const results = await runAxe(component) + expect(results.violations).toEqual([]) + }) + }) + + describe('SearchProviderToggle.server', () => { + it('should have no accessibility violations', async () => { + const component = await mountSuspended(SearchProviderToggleServer) + const results = await runAxe(component) + expect(results.violations).toEqual([]) + }) + }) + describe('Toggle.server', () => { it('should have no accessibility violations', async () => { const component = await mountSuspended(ToggleServer, {