From de8ef70e509876d927fa9c2ec5c7e5cd591aead5 Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Tue, 16 Jul 2024 09:47:28 +0200 Subject: [PATCH] chore: types running with v4 locally, but also v4 and v3 (#6271) * chore: change type * WIP: expand search parameters doesn't work as there still are v4 v5 differences of course * do it correctly * use regular client * not sure if this should stay * WIP * changes rule * fix dependency * change order to make script work * almost all types fixed * improve test * fix(types): accepts client with wrong types will be fixed once https://github.com/algolia/api-clients-automation/pull/3357 is done * tests * chore(helper): compatibility * chore(legacy): correct replacement * don't remove v5 fully * fix errors * safer (or less safe lol) * correct import * fix fake type * v5 only works * tests * script for examples too * script for examples too * chore(answers): bleh get rid of this! * stuff * simplify --- examples/js/calendar-widget/app.js | 2 +- examples/js/calendar-widget/package.json | 2 +- examples/js/e-commerce-umd/package.json | 2 +- examples/js/e-commerce-umd/src/search.ts | 2 +- examples/js/e-commerce/package.json | 2 +- examples/js/e-commerce/src/search.ts | 2 +- examples/js/getting-started/package.json | 2 +- examples/js/getting-started/products.html | 2 +- examples/js/getting-started/src/app.js | 2 +- .../src/{products.js => products.ts} | 6 +- examples/js/media/package.json | 2 +- examples/js/media/src/search.ts | 2 +- examples/js/tourism/package.json | 2 +- examples/js/tourism/search.js | 2 +- examples/react/default-theme/package.json | 2 +- examples/react/default-theme/src/App.tsx | 2 +- examples/react/e-commerce/App.tsx | 2 +- examples/react/e-commerce/package.json | 2 +- examples/react/getting-started/package.json | 2 +- examples/react/getting-started/src/App.tsx | 2 +- .../react/getting-started/src/Product.tsx | 2 +- examples/react/next-app-router/app/Search.tsx | 2 +- examples/react/next-app-router/package.json | 2 +- examples/react/next-routing/package.json | 2 +- examples/react/next-routing/pages/index.tsx | 2 +- examples/react/next-routing/pages/test.tsx | 2 +- examples/react/next/package.json | 2 +- examples/react/next/pages/index.tsx | 2 +- examples/react/react-native/App.tsx | 2 +- examples/react/react-native/package.json | 2 +- examples/react/react-native/src/Highlight.tsx | 4 +- .../react/react-native/src/InfiniteHits.tsx | 2 +- .../react/react-native/types/ProductHit.ts | 2 +- examples/react/ssr/package.json | 2 +- examples/react/ssr/src/searchClient.js | 2 +- examples/vue/default-theme/package.json | 2 +- examples/vue/default-theme/src/App.vue | 2 +- examples/vue/e-commerce/package.json | 2 +- examples/vue/e-commerce/src/App.vue | 2 +- examples/vue/getting-started/package.json | 2 +- examples/vue/getting-started/src/App.vue | 2 +- examples/vue/media/package.json | 2 +- examples/vue/media/src/App.vue | 2 +- examples/vue/nuxt/package.json | 2 +- examples/vue/nuxt/pages/search.vue | 2 +- examples/vue/ssr/package.json | 2 +- examples/vue/ssr/src/main.js | 2 +- package.json | 9 +- packages/algoliasearch-helper/index.d.ts | 48 ++--- .../SearchResults/getFacetValues.dataset.js | 1 + .../SearchResults/getRefinements.dataset.js | 1 + .../test/integration-utils.js | 1 + packages/algoliasearch-helper/test/run.js | 1 + .../test/spec/algoliasearch.helper/client.js | 1 + .../algoliasearch.helper/numericFilters.js | 7 +- .../algoliasearch.helper/pendingSearch.js | 13 +- .../hierarchical-facets/attributes-order.js | 1 + .../spec/hierarchical-facets/breadcrumb.js | 3 + .../hierarchical-facets/custom-prefix-path.js | 1 + .../hierarchical-facets/custom-separator.js | 1 + .../do-not-show-parent-level.js | 1 + .../hierarchical-facets/facet-value-length.js | 1 + .../spec/hierarchical-facets/no-refinement.js | 1 + .../test/spec/hierarchical-facets/no-trim.js | 1 + .../objects-with-multiple-categories.js | 1 + .../spec/hierarchical-facets/one-level.js | 1 + .../spec/hierarchical-facets/pagination.js | 1 + .../parent-toggleRefine.js | 3 + .../hierarchical-facets/refined-no-result.js | 1 + .../hierarchical-facets/show-parent-level.js | 1 + .../spec/hierarchical-facets/simple-usage.js | 1 + .../test/spec/hierarchical-facets/sort-by.js | 1 + .../spec/hierarchical-facets/two-facets.js | 1 + .../spec/hierarchical-facets/unknown-facet.js | 1 + .../with-a-disjunctive-facet.js | 1 + packages/algoliasearch-helper/test/types.ts | 10 +- .../types/algoliasearch.d.ts | 171 +++++++++++++++-- .../src/types/Recommend.ts | 3 +- .../.storybook/decorators/withHits.ts | 17 +- .../src/connectors/answers/connectAnswers.ts | 18 +- .../__tests__/connectAutocomplete-test.ts | 11 +- .../__tests__/connectConfigure-test.ts | 4 +- .../connectFrequentlyBoughtTogether.ts | 24 ++- .../hits/__tests__/connectHits-test.ts | 30 +-- .../looking-similar/connectLookingSimilar.ts | 19 +- .../__tests__/connectRefinementList-test.ts | 5 + .../connectRelatedProducts.ts | 19 +- .../__tests__/connectTrendingItems-test.ts | 5 +- .../trending-items/connectTrendingItems.ts | 23 +-- .../__tests__/connectVoiceSearch-test.ts | 3 + .../voice-search/connectVoiceSearch.ts | 3 +- .../src/lib/__tests__/InstantSearch-test.tsx | 2 +- packages/instantsearch.js/src/lib/server.ts | 2 +- .../utils/__tests__/getAppIdAndApiKey-test.ts | 2 +- .../src/lib/utils/hydrateSearchClient.ts | 2 +- .../__tests__/createMetadataMiddleware.ts | 176 +++++++++++++++--- packages/instantsearch.js/src/types/widget.ts | 4 +- .../frequently-bought-together.tsx | 16 +- .../src/widgets/index/__tests__/index-test.ts | 9 +- .../src/widgets/index/index.ts | 4 +- .../looking-similar/looking-similar.tsx | 16 +- .../__tests__/refinement-list.test.tsx | 1 + .../related-products/related-products.tsx | 16 +- .../widgets/trending-items/trending-items.tsx | 16 +- .../__tests__/voice-search-test.ts | 8 +- .../InstantSearchSSRProvider.test.tsx | 121 ++++++------ .../src/InitializePromise.tsx | 2 +- .../src/widgets/FrequentlyBoughtTogether.tsx | 6 +- .../src/widgets/LookingSimilar.tsx | 6 +- .../src/widgets/RelatedProducts.tsx | 4 +- .../src/widgets/TrendingItems.tsx | 4 +- .../widgets/__tests__/RefinementList.test.tsx | 1 + .../downgrade-algoliasearch-dependency.js | 24 ++- tests/common/connectors/pagination/routing.ts | 2 +- tests/common/shared/insights.ts | 6 +- tests/common/shared/routing.ts | 2 +- .../widgets/infinite-hits/optimistic-ui.ts | 18 +- .../widgets/instantsearch/algolia-agent.ts | 72 ++++++- .../widgets/pagination/optimistic-ui.ts | 4 +- .../common/widgets/refinement-list/options.ts | 6 +- tests/mocks/createAPIResponse.ts | 43 ++++- tests/mocks/createAlgoliaSearchClient.ts | 29 ++- tests/mocks/createSearchClient.ts | 1 + yarn.lock | 160 +++++++--------- 124 files changed, 892 insertions(+), 463 deletions(-) rename examples/js/getting-started/src/{products.js => products.ts} (91%) diff --git a/examples/js/calendar-widget/app.js b/examples/js/calendar-widget/app.js index 8a55ca8991..80405d59d6 100644 --- a/examples/js/calendar-widget/app.js +++ b/examples/js/calendar-widget/app.js @@ -1,5 +1,5 @@ /* global moment Calendar $ */ -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import instantsearch from 'instantsearch.js'; import { connectRange } from 'instantsearch.js/es/connectors'; import { searchBox, hits } from 'instantsearch.js/es/widgets'; diff --git a/examples/js/calendar-widget/package.json b/examples/js/calendar-widget/package.json index d96b98a030..b0fdc5cad7 100644 --- a/examples/js/calendar-widget/package.json +++ b/examples/js/calendar-widget/package.json @@ -8,7 +8,7 @@ "website:examples": "BABEL_ENV=parcel parcel build index.html --public-url . --dist-dir=../../../website/examples/js/calendar-widget" }, "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "instantsearch.js": "4.73.0" }, "devDependencies": { diff --git a/examples/js/e-commerce-umd/package.json b/examples/js/e-commerce-umd/package.json index 05e0098462..277be8dc88 100644 --- a/examples/js/e-commerce-umd/package.json +++ b/examples/js/e-commerce-umd/package.json @@ -9,7 +9,7 @@ }, "browserslist": "firefox 68, chrome 78, IE 11", "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "instantsearch.js": "4.73.0" }, "devDependencies": { diff --git a/examples/js/e-commerce-umd/src/search.ts b/examples/js/e-commerce-umd/src/search.ts index 5ed993e1c5..32510323fe 100644 --- a/examples/js/e-commerce-umd/src/search.ts +++ b/examples/js/e-commerce-umd/src/search.ts @@ -1,4 +1,4 @@ -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import getRouting from './routing'; import { diff --git a/examples/js/e-commerce/package.json b/examples/js/e-commerce/package.json index 7e83a5dbf5..d09157cec2 100644 --- a/examples/js/e-commerce/package.json +++ b/examples/js/e-commerce/package.json @@ -9,7 +9,7 @@ }, "browserslist": "firefox 68, chrome 78, IE 11", "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "instantsearch.js": "4.73.0" }, "devDependencies": { diff --git a/examples/js/e-commerce/src/search.ts b/examples/js/e-commerce/src/search.ts index 5af2268b1d..dda821efbf 100644 --- a/examples/js/e-commerce/src/search.ts +++ b/examples/js/e-commerce/src/search.ts @@ -1,4 +1,4 @@ -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import instantsearch from 'instantsearch.js'; import getRouting from './routing'; diff --git a/examples/js/getting-started/package.json b/examples/js/getting-started/package.json index fef106f036..ade145f2cc 100644 --- a/examples/js/getting-started/package.json +++ b/examples/js/getting-started/package.json @@ -9,7 +9,7 @@ "lint:fix": "npm run lint -- --fix" }, "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "instantsearch.js": "4.73.0" }, "devDependencies": { diff --git a/examples/js/getting-started/products.html b/examples/js/getting-started/products.html index 524fea7931..03adf36379 100644 --- a/examples/js/getting-started/products.html +++ b/examples/js/getting-started/products.html @@ -43,6 +43,6 @@

- + diff --git a/examples/js/getting-started/src/app.js b/examples/js/getting-started/src/app.js index 47424686fc..01cb5a0d46 100644 --- a/examples/js/getting-started/src/app.js +++ b/examples/js/getting-started/src/app.js @@ -1,4 +1,4 @@ -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import instantsearch from 'instantsearch.js'; import { configure, diff --git a/examples/js/getting-started/src/products.js b/examples/js/getting-started/src/products.ts similarity index 91% rename from examples/js/getting-started/src/products.js rename to examples/js/getting-started/src/products.ts index bd641b758f..0302bfa70b 100644 --- a/examples/js/getting-started/src/products.js +++ b/examples/js/getting-started/src/products.ts @@ -1,4 +1,4 @@ -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import instantsearch from 'instantsearch.js'; import { configure, hits, relatedProducts } from 'instantsearch.js/es/widgets'; @@ -6,6 +6,10 @@ const searchParams = new URLSearchParams(document.location.search); const pid = searchParams.get('pid'); +if (!pid) { + throw new Error('No product ID provided'); +} + const searchClient = algoliasearch( 'latency', '6be0576ff61c053d5f9a3225e2a90f76' diff --git a/examples/js/media/package.json b/examples/js/media/package.json index d590c35142..bc9ccc510b 100644 --- a/examples/js/media/package.json +++ b/examples/js/media/package.json @@ -8,7 +8,7 @@ "website:examples": "BABEL_ENV=parcel parcel build index.html --public-url . --dist-dir=../../../website/examples/js/media" }, "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "date-fns": "2.25.0", "instantsearch.js": "4.73.0" }, diff --git a/examples/js/media/src/search.ts b/examples/js/media/src/search.ts index 3c21c66cd4..702764e777 100644 --- a/examples/js/media/src/search.ts +++ b/examples/js/media/src/search.ts @@ -1,4 +1,4 @@ -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import instantsearch from 'instantsearch.js'; import { singleIndex } from 'instantsearch.js/es/lib/stateMappings'; diff --git a/examples/js/tourism/package.json b/examples/js/tourism/package.json index ceb7024f3a..4cdc4069af 100644 --- a/examples/js/tourism/package.json +++ b/examples/js/tourism/package.json @@ -8,7 +8,7 @@ "website:examples": "BABEL_ENV=parcel parcel build index.html --public-url . --dist-dir=../../../website/examples/js/tourism" }, "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "instantsearch.js": "4.73.0" }, "devDependencies": { diff --git a/examples/js/tourism/search.js b/examples/js/tourism/search.js index 6947738dc8..15b6df0b32 100644 --- a/examples/js/tourism/search.js +++ b/examples/js/tourism/search.js @@ -1,4 +1,4 @@ -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import instantsearch from 'instantsearch.js'; import { configure, diff --git a/examples/react/default-theme/package.json b/examples/react/default-theme/package.json index 239ff607a4..2f750c4777 100644 --- a/examples/react/default-theme/package.json +++ b/examples/react/default-theme/package.json @@ -7,7 +7,7 @@ "start": "BABEL_ENV=parcel parcel index.html" }, "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "instantsearch.js": "4.73.0", "react": "18.2.0", "react-dom": "18.2.0", diff --git a/examples/react/default-theme/src/App.tsx b/examples/react/default-theme/src/App.tsx index cc8d1d0684..f3ac4516d5 100644 --- a/examples/react/default-theme/src/App.tsx +++ b/examples/react/default-theme/src/App.tsx @@ -1,4 +1,4 @@ -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import { Hit as AlgoliaHit } from 'instantsearch.js'; import React from 'react'; import { diff --git a/examples/react/e-commerce/App.tsx b/examples/react/e-commerce/App.tsx index 253b131a14..92fb9f45e7 100644 --- a/examples/react/e-commerce/App.tsx +++ b/examples/react/e-commerce/App.tsx @@ -1,4 +1,4 @@ -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import React, { useRef } from 'react'; import { Configure, diff --git a/examples/react/e-commerce/package.json b/examples/react/e-commerce/package.json index f1d2fc051c..31ec170ae3 100644 --- a/examples/react/e-commerce/package.json +++ b/examples/react/e-commerce/package.json @@ -9,7 +9,7 @@ }, "browserslist": "firefox 68, chrome 78, IE 11", "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "instantsearch.js": "4.73.0", "react": "18.2.0", "react-compound-slider": "3.4.0", diff --git a/examples/react/getting-started/package.json b/examples/react/getting-started/package.json index 79d026cfe7..d20c12d6fb 100644 --- a/examples/react/getting-started/package.json +++ b/examples/react/getting-started/package.json @@ -7,7 +7,7 @@ "start": "BABEL_ENV=parcel parcel index.html products.html --port 3000" }, "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "instantsearch.js": "4.73.0", "react": "18.2.0", "react-dom": "18.2.0", diff --git a/examples/react/getting-started/src/App.tsx b/examples/react/getting-started/src/App.tsx index 0780024e41..154a53bf76 100644 --- a/examples/react/getting-started/src/App.tsx +++ b/examples/react/getting-started/src/App.tsx @@ -1,4 +1,4 @@ -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import { Hit } from 'instantsearch.js'; import React from 'react'; import { diff --git a/examples/react/getting-started/src/Product.tsx b/examples/react/getting-started/src/Product.tsx index ef76252e75..759bf5ec4e 100644 --- a/examples/react/getting-started/src/Product.tsx +++ b/examples/react/getting-started/src/Product.tsx @@ -1,4 +1,4 @@ -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import { type Hit } from 'instantsearch.js'; import React from 'react'; import { diff --git a/examples/react/next-app-router/app/Search.tsx b/examples/react/next-app-router/app/Search.tsx index 2bdf9af74f..caafd4fd45 100644 --- a/examples/react/next-app-router/app/Search.tsx +++ b/examples/react/next-app-router/app/Search.tsx @@ -1,6 +1,6 @@ 'use client'; -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import { Hit as AlgoliaHit } from 'instantsearch.js'; import React from 'react'; import { diff --git a/examples/react/next-app-router/package.json b/examples/react/next-app-router/package.json index 2c0ecb1c65..aaf53f69ce 100644 --- a/examples/react/next-app-router/package.json +++ b/examples/react/next-app-router/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "instantsearch.css": "8.3.0", "next": "13.5.1", "react": "18.2.0", diff --git a/examples/react/next-routing/package.json b/examples/react/next-routing/package.json index bc7e823ca8..7625795f8c 100644 --- a/examples/react/next-routing/package.json +++ b/examples/react/next-routing/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "instantsearch.css": "8.3.0", "next": "13.5.1", "react": "18.2.0", diff --git a/examples/react/next-routing/pages/index.tsx b/examples/react/next-routing/pages/index.tsx index 8baf36434e..8cb6260227 100644 --- a/examples/react/next-routing/pages/index.tsx +++ b/examples/react/next-routing/pages/index.tsx @@ -1,4 +1,4 @@ -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import { Hit as AlgoliaHit } from 'instantsearch.js'; import { GetServerSideProps } from 'next'; import Head from 'next/head'; diff --git a/examples/react/next-routing/pages/test.tsx b/examples/react/next-routing/pages/test.tsx index 6703306cf9..2ca680aecf 100644 --- a/examples/react/next-routing/pages/test.tsx +++ b/examples/react/next-routing/pages/test.tsx @@ -1,5 +1,5 @@ // This is only to test `onStateChange` does not get called twice -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import { GetServerSideProps } from 'next'; import Head from 'next/head'; import Link from 'next/link'; diff --git a/examples/react/next/package.json b/examples/react/next/package.json index 871d0a5446..963ffb7450 100644 --- a/examples/react/next/package.json +++ b/examples/react/next/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "instantsearch.css": "8.3.0", "next": "13.5.1", "react": "18.2.0", diff --git a/examples/react/next/pages/index.tsx b/examples/react/next/pages/index.tsx index ba29a7022c..2ae1971f83 100644 --- a/examples/react/next/pages/index.tsx +++ b/examples/react/next/pages/index.tsx @@ -1,4 +1,4 @@ -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import { Hit as AlgoliaHit } from 'instantsearch.js'; import { GetServerSideProps } from 'next'; import Head from 'next/head'; diff --git a/examples/react/react-native/App.tsx b/examples/react/react-native/App.tsx index 579c82c939..515fa74640 100644 --- a/examples/react/react-native/App.tsx +++ b/examples/react/react-native/App.tsx @@ -1,7 +1,7 @@ import React, { useRef } from 'react'; import { FlatList, SafeAreaView, StyleSheet, Text, View } from 'react-native'; import { StatusBar } from 'expo-status-bar'; -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; import { InstantSearch } from 'react-instantsearch-core'; import { InfiniteHits } from './src/InfiniteHits'; diff --git a/examples/react/react-native/package.json b/examples/react/react-native/package.json index ec8085115a..9332e01594 100644 --- a/examples/react/react-native/package.json +++ b/examples/react/react-native/package.json @@ -11,7 +11,7 @@ "eject": "expo eject" }, "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "expo": "~44.0.0", "expo-status-bar": "~1.2.0", "instantsearch.js": "4.73.0", diff --git a/examples/react/react-native/src/Highlight.tsx b/examples/react/react-native/src/Highlight.tsx index d25f35c698..f0785cf89d 100644 --- a/examples/react/react-native/src/Highlight.tsx +++ b/examples/react/react-native/src/Highlight.tsx @@ -1,6 +1,6 @@ import React, { Fragment } from 'react'; import { StyleSheet, Text } from 'react-native'; -import { Hit as AlgoliaHit } from '@algolia/client-search'; +import { Hit as AlgoliaHit } from 'instantsearch.js'; import { getHighlightedParts, getPropertyByPath, @@ -26,7 +26,7 @@ type HighlightProps = { separator?: string; }; -export function Highlight>>({ +export function Highlight({ hit, attribute, separator = ', ', diff --git a/examples/react/react-native/src/InfiniteHits.tsx b/examples/react/react-native/src/InfiniteHits.tsx index b9648c08b2..becb8a0701 100644 --- a/examples/react/react-native/src/InfiniteHits.tsx +++ b/examples/react/react-native/src/InfiniteHits.tsx @@ -1,6 +1,6 @@ import React, { forwardRef } from 'react'; import { StyleSheet, View, FlatList } from 'react-native'; -import { Hit as AlgoliaHit } from '@algolia/client-search'; +import { Hit as AlgoliaHit } from 'instantsearch.js'; import { useInfiniteHits, UseInfiniteHitsProps, diff --git a/examples/react/react-native/types/ProductHit.ts b/examples/react/react-native/types/ProductHit.ts index 94883fbc6d..a41d0c54fd 100644 --- a/examples/react/react-native/types/ProductHit.ts +++ b/examples/react/react-native/types/ProductHit.ts @@ -1,4 +1,4 @@ -import { Hit as AlgoliaHit } from '@algolia/client-search'; +import { Hit as AlgoliaHit } from 'instantsearch.js'; export type ProductHit = AlgoliaHit<{ brand: string; diff --git a/examples/react/ssr/package.json b/examples/react/ssr/package.json index 2d925b2be9..c9f9b54caa 100644 --- a/examples/react/ssr/package.json +++ b/examples/react/ssr/package.json @@ -22,7 +22,7 @@ "webpack-node-externals": "1.7.2" }, "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "express": "4.17.1", "react": "18.2.0", "react-dom": "18.2.0", diff --git a/examples/react/ssr/src/searchClient.js b/examples/react/ssr/src/searchClient.js index f902ad319b..36f20ea227 100644 --- a/examples/react/ssr/src/searchClient.js +++ b/examples/react/ssr/src/searchClient.js @@ -1,4 +1,4 @@ -import { liteClient as algoliasearch } from 'algoliasearch-v5/lite'; +import { liteClient as algoliasearch } from 'algoliasearch/lite'; export const searchClient = algoliasearch( 'latency', diff --git a/examples/vue/default-theme/package.json b/examples/vue/default-theme/package.json index 9dcc3e4d8b..f231c92245 100644 --- a/examples/vue/default-theme/package.json +++ b/examples/vue/default-theme/package.json @@ -8,7 +8,7 @@ "website:examples": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build --dest ../../../website/examples/vue/default-theme" }, "dependencies": { - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch": "npm:algoliasearch@5.0.0-beta.9", "core-js": "2", "instantsearch.js": "4.73.0", "vue": "2.7.14", diff --git a/examples/vue/default-theme/src/App.vue b/examples/vue/default-theme/src/App.vue index 896a5a0d6f..418c118e75 100644 --- a/examples/vue/default-theme/src/App.vue +++ b/examples/vue/default-theme/src/App.vue @@ -123,7 +123,7 @@ `, + matchLevel: 'full' as const, + matchedWords: ['foobar'], }, }, objectID: '1', @@ -252,6 +254,8 @@ search.addWidgets([ _highlightResult: { foobar: { value: '<script>foobar</script>', + matchLevel: 'full', + matchedWords: ['foobar'], }, }, objectID: '1', @@ -268,7 +272,9 @@ search.addWidgets([ { indexId: 'index0', results: new SearchResults(helper.state, [ - createSingleSearchResponse({ hits }), + createSingleSearchResponse({ + hits, + }), ]), helper, }, @@ -295,9 +301,12 @@ search.addWidgets([ const hits = [ { + foobar: 'foobar', _highlightResult: { foobar: { value: ``, + matchLevel: 'full' as const, + matchedWords: ['foobar'], }, }, objectID: '1', diff --git a/packages/instantsearch.js/src/connectors/configure/__tests__/connectConfigure-test.ts b/packages/instantsearch.js/src/connectors/configure/__tests__/connectConfigure-test.ts index e3809dd910..9889d0394d 100644 --- a/packages/instantsearch.js/src/connectors/configure/__tests__/connectConfigure-test.ts +++ b/packages/instantsearch.js/src/connectors/configure/__tests__/connectConfigure-test.ts @@ -289,7 +289,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/configure/j configure: { refine() {}, widgetParams: { - searchParameters: { removeStopWords: ['group'] }, + searchParameters: { removeStopWords: ['en'] }, }, }, }, @@ -300,7 +300,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/configure/j refine: expect.any(Function), widgetParams: { searchParameters: { - removeStopWords: ['group'], + removeStopWords: ['en'], facetFilters: ['brand:Samsung'], }, }, diff --git a/packages/instantsearch.js/src/connectors/frequently-bought-together/connectFrequentlyBoughtTogether.ts b/packages/instantsearch.js/src/connectors/frequently-bought-together/connectFrequentlyBoughtTogether.ts index 4190ef67a9..14866a9c40 100644 --- a/packages/instantsearch.js/src/connectors/frequently-bought-together/connectFrequentlyBoughtTogether.ts +++ b/packages/instantsearch.js/src/connectors/frequently-bought-together/connectFrequentlyBoughtTogether.ts @@ -9,16 +9,14 @@ import { import type { Connector, TransformItems, - Hit, BaseHit, Renderer, Unmounter, UnknownWidgetParams, + RecommendResponse, + AlgoliaHit, } from '../../types'; -import type { - PlainSearchParameters, - RecommendResultItem, -} from 'algoliasearch-helper'; +import type { PlainSearchParameters } from 'algoliasearch-helper'; const withUsage = createDocumentationMessageGenerator({ name: 'frequently-bought-together', @@ -31,7 +29,7 @@ export type FrequentlyBoughtTogetherRenderState< /** * The matched recommendations from Algolia API. */ - items: Array>; + items: Array>; }; export type FrequentlyBoughtTogetherConnectorParams< @@ -70,7 +68,10 @@ export type FrequentlyBoughtTogetherConnectorParams< /** * Function to transform the items passed to the templates. */ - transformItems?: TransformItems, { results: RecommendResultItem }>; + transformItems?: TransformItems< + AlgoliaHit, + { results: RecommendResponse> } + >; }; export type FrequentlyBoughtTogetherWidgetDescription< @@ -156,9 +157,12 @@ export default (function connectFrequentlyBoughtTogether< results.hits = escapeHits(results.hits); } - const transformedItems = transformItems(results.hits, { - results: results as RecommendResultItem, - }); + const transformedItems = transformItems( + results.hits as Array>, + { + results: results as RecommendResponse>, + } + ); return { items: transformedItems, widgetParams }; }, diff --git a/packages/instantsearch.js/src/connectors/hits/__tests__/connectHits-test.ts b/packages/instantsearch.js/src/connectors/hits/__tests__/connectHits-test.ts index 971ff1a172..6185e2055a 100644 --- a/packages/instantsearch.js/src/connectors/hits/__tests__/connectHits-test.ts +++ b/packages/instantsearch.js/src/connectors/hits/__tests__/connectHits-test.ts @@ -178,21 +178,23 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co expect.anything() ); - const hits = [ - { - objectID: '1', - _highlightResult: { - foobar: { - value: ``, - matchLevel: 'partial', - matchedWords: ['foobar'], - }, - }, - }, - ]; - const results = new SearchResults(helper.state, [ - createSingleSearchResponse(createSingleSearchResponse({ hits })), + createSingleSearchResponse( + createSingleSearchResponse({ + hits: [ + { + objectID: '1', + _highlightResult: { + foobar: { + value: ``, + matchLevel: 'partial', + matchedWords: ['foobar'], + }, + }, + }, + ], + }) + ), ]); widget.render( createRenderOptions({ diff --git a/packages/instantsearch.js/src/connectors/looking-similar/connectLookingSimilar.ts b/packages/instantsearch.js/src/connectors/looking-similar/connectLookingSimilar.ts index 34c86903c6..a487d5b8e8 100644 --- a/packages/instantsearch.js/src/connectors/looking-similar/connectLookingSimilar.ts +++ b/packages/instantsearch.js/src/connectors/looking-similar/connectLookingSimilar.ts @@ -9,16 +9,14 @@ import { import type { Connector, TransformItems, - Hit, BaseHit, Renderer, Unmounter, UnknownWidgetParams, + RecommendResponse, + AlgoliaHit, } from '../../types'; -import type { - PlainSearchParameters, - RecommendResultItem, -} from 'algoliasearch-helper'; +import type { PlainSearchParameters } from 'algoliasearch-helper'; const withUsage = createDocumentationMessageGenerator({ name: 'looking-similar', @@ -31,7 +29,7 @@ export type LookingSimilarRenderState< /** * The matched recommendations from the Algolia API. */ - items: Array>; + items: Array>; }; export type LookingSimilarConnectorParams< @@ -72,7 +70,10 @@ export type LookingSimilarConnectorParams< /** * Function to transform the items passed to the templates. */ - transformItems?: TransformItems, { results: RecommendResultItem }>; + transformItems?: TransformItems< + AlgoliaHit, + { results: RecommendResponse> } + >; }; export type LookingSimilarWidgetDescription< @@ -160,8 +161,8 @@ export default (function connectLookingSimilar< } return { - items: transformItems(results.hits, { - results: results as RecommendResultItem, + items: transformItems(results.hits as Array>, { + results: results as RecommendResponse>, }), widgetParams, }; diff --git a/packages/instantsearch.js/src/connectors/refinement-list/__tests__/connectRefinementList-test.ts b/packages/instantsearch.js/src/connectors/refinement-list/__tests__/connectRefinementList-test.ts index 067b47186b..ad66420c5b 100644 --- a/packages/instantsearch.js/src/connectors/refinement-list/__tests__/connectRefinementList-test.ts +++ b/packages/instantsearch.js/src/connectors/refinement-list/__tests__/connectRefinementList-test.ts @@ -1598,6 +1598,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/refinement- const helper = jsHelper( createSearchClient({ + // @ts-ignore v5 expects `search({ type: 'facet' })` only searchForFacetValues() { return Promise.resolve([ { @@ -1719,6 +1720,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/refinement- const helper = jsHelper( createSearchClient({ + // @ts-ignore v5 expects `search({ type: 'facet' })` only searchForFacetValues() { return Promise.resolve([ { @@ -1801,6 +1803,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/refinement- const helper = jsHelper( createSearchClient({ + // @ts-ignore v5 expects `search({ type: 'facet' })` only searchForFacetValues() { return Promise.resolve([ { @@ -1911,6 +1914,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/refinement- const helper = jsHelper( createSearchClient({ + // @ts-ignore v5 expects `search({ type: 'facet' })` only searchForFacetValues() { return Promise.resolve([ { @@ -2029,6 +2033,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/refinement- const helper = jsHelper( createSearchClient({ + // @ts-ignore v5 expects `search({ type: 'facet' })` only searchForFacetValues() { return Promise.resolve([ { diff --git a/packages/instantsearch.js/src/connectors/related-products/connectRelatedProducts.ts b/packages/instantsearch.js/src/connectors/related-products/connectRelatedProducts.ts index db6c8678c6..9e23a7401f 100644 --- a/packages/instantsearch.js/src/connectors/related-products/connectRelatedProducts.ts +++ b/packages/instantsearch.js/src/connectors/related-products/connectRelatedProducts.ts @@ -9,16 +9,14 @@ import { import type { Connector, TransformItems, - Hit, BaseHit, Renderer, Unmounter, UnknownWidgetParams, + RecommendResponse, + AlgoliaHit, } from '../../types'; -import type { - PlainSearchParameters, - RecommendResultItem, -} from 'algoliasearch-helper'; +import type { PlainSearchParameters } from 'algoliasearch-helper'; const withUsage = createDocumentationMessageGenerator({ name: 'related-products', @@ -31,7 +29,7 @@ export type RelatedProductsRenderState< /** * The matched recommendations from the Algolia API. */ - items: Array>; + items: Array>; }; export type RelatedProductsConnectorParams< @@ -72,7 +70,10 @@ export type RelatedProductsConnectorParams< /** * Function to transform the items passed to the templates. */ - transformItems?: TransformItems, { results: RecommendResultItem }>; + transformItems?: TransformItems< + AlgoliaHit, + { results: RecommendResponse> } + >; }; export type RelatedProductsWidgetDescription< @@ -160,8 +161,8 @@ export default (function connectRelatedProducts< } return { - items: transformItems(results.hits, { - results: results as RecommendResultItem, + items: transformItems(results.hits as Array>, { + results: results as RecommendResponse>, }), widgetParams, }; diff --git a/packages/instantsearch.js/src/connectors/trending-items/__tests__/connectTrendingItems-test.ts b/packages/instantsearch.js/src/connectors/trending-items/__tests__/connectTrendingItems-test.ts index 1d955bbf3c..6514c5449a 100644 --- a/packages/instantsearch.js/src/connectors/trending-items/__tests__/connectTrendingItems-test.ts +++ b/packages/instantsearch.js/src/connectors/trending-items/__tests__/connectTrendingItems-test.ts @@ -129,8 +129,9 @@ describe('connectTrendingItems', () => { new RecommendParameters().addTrendingItems({ // @ts-expect-error $$id: widget.$$id, - facetName: undefined, - facetValue: undefined, + // v5 expects only string values for facetName and facetValue + facetName: undefined as unknown as string, + facetValue: undefined as unknown as string, maxRecommendations: 10, threshold: 95, queryParameters: { userToken: 'token' }, diff --git a/packages/instantsearch.js/src/connectors/trending-items/connectTrendingItems.ts b/packages/instantsearch.js/src/connectors/trending-items/connectTrendingItems.ts index 3e44e2bb1d..d6025a7abc 100644 --- a/packages/instantsearch.js/src/connectors/trending-items/connectTrendingItems.ts +++ b/packages/instantsearch.js/src/connectors/trending-items/connectTrendingItems.ts @@ -10,16 +10,14 @@ import { import type { Connector, TransformItems, - Hit, BaseHit, Renderer, Unmounter, UnknownWidgetParams, + RecommendResponse, + AlgoliaHit, } from '../../types'; -import type { - PlainSearchParameters, - RecommendResultItem, -} from 'algoliasearch-helper'; +import type { PlainSearchParameters } from 'algoliasearch-helper'; const withUsage = createDocumentationMessageGenerator({ name: 'trending-items', @@ -32,7 +30,7 @@ export type TrendingItemsRenderState< /** * The matched recommendations from the Algolia API. */ - items: Array>; + items: Array>; }; export type TrendingItemsConnectorParams< @@ -84,7 +82,10 @@ export type TrendingItemsConnectorParams< /** * Function to transform the items passed to the templates. */ - transformItems?: TransformItems, { results: RecommendResultItem }>; + transformItems?: TransformItems< + AlgoliaHit, + { results: RecommendResponse> } + >; }; export type TrendingItemsWidgetDescription< @@ -180,8 +181,8 @@ export default (function connectTrendingItems< } return { - items: transformItems(results.hits, { - results: results as RecommendResultItem, + items: transformItems(results.hits as Array>, { + results: results as RecommendResponse>, }), widgetParams, }; @@ -194,8 +195,8 @@ export default (function connectTrendingItems< getWidgetParameters(state) { return state.removeParams(this.$$id!).addTrendingItems({ - facetName, - facetValue, + facetName: facetName as string, + facetValue: facetValue as string, maxRecommendations: limit, threshold, fallbackParameters: { diff --git a/packages/instantsearch.js/src/connectors/voice-search/__tests__/connectVoiceSearch-test.ts b/packages/instantsearch.js/src/connectors/voice-search/__tests__/connectVoiceSearch-test.ts index a357de938e..01de808d1e 100644 --- a/packages/instantsearch.js/src/connectors/voice-search/__tests__/connectVoiceSearch-test.ts +++ b/packages/instantsearch.js/src/connectors/voice-search/__tests__/connectVoiceSearch-test.ts @@ -472,6 +472,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/voice-searc new SearchParameters({ ignorePlurals: true, removeStopWords: true, + // @ts-ignore we send optionalWords as a string optionalWords: 'query', queryLanguages: undefined, index: '', @@ -494,6 +495,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/voice-searc queryLanguages: ['en'], // regular removeStopWords: true, + // @ts-ignore we send optionalWords as a string optionalWords: 'query', ignorePlurals: true, query: 'query', @@ -516,6 +518,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/voice-searc new SearchParameters({ ignorePlurals: true, removeStopWords: true, + // @ts-ignore we send optionalWords as a string optionalWords: 'query', queryLanguages: undefined, index: '', diff --git a/packages/instantsearch.js/src/connectors/voice-search/connectVoiceSearch.ts b/packages/instantsearch.js/src/connectors/voice-search/connectVoiceSearch.ts index 22e9ebb2be..ad252d07f7 100644 --- a/packages/instantsearch.js/src/connectors/voice-search/connectVoiceSearch.ts +++ b/packages/instantsearch.js/src/connectors/voice-search/connectVoiceSearch.ts @@ -106,6 +106,7 @@ const connectVoiceSearch: VoiceSearchConnector = function connectVoiceSearch( const queryLanguages = language ? [language.split('-')[0]] : undefined; + // @ts-ignore queryLanguages is allowed to be a string, not just an array helper.setQueryParameter('queryLanguages', queryLanguages); if (typeof additionalQueryParameters === 'function') { @@ -113,7 +114,7 @@ const connectVoiceSearch: VoiceSearchConnector = function connectVoiceSearch( helper.state.setQueryParameters({ ignorePlurals: true, removeStopWords: true, - // @ts-ignore (optionalWords only allows array in v3, while string is also valid) + // @ts-ignore optionalWords is allowed to be a string too optionalWords: query, ...additionalQueryParameters({ query }), }) diff --git a/packages/instantsearch.js/src/lib/__tests__/InstantSearch-test.tsx b/packages/instantsearch.js/src/lib/__tests__/InstantSearch-test.tsx index fceddbcbed..c1b78d2cad 100644 --- a/packages/instantsearch.js/src/lib/__tests__/InstantSearch-test.tsx +++ b/packages/instantsearch.js/src/lib/__tests__/InstantSearch-test.tsx @@ -486,7 +486,7 @@ See https://www.algolia.com/doc/api-reference/widgets/configure/js/`); ? { _automaticInsights: true } : undefined), index: request.indexName, - query: request.query, + query: (request as any).query || request.params.query, ...(request.indexName === 'indexNameWithAutomaticInsights' ? { queryID: 'queryID' } : undefined), diff --git a/packages/instantsearch.js/src/lib/server.ts b/packages/instantsearch.js/src/lib/server.ts index 1911fc92b9..e669107b2a 100644 --- a/packages/instantsearch.js/src/lib/server.ts +++ b/packages/instantsearch.js/src/lib/server.ts @@ -24,7 +24,7 @@ export function waitForResults( helper.setClient({ ...client, search(queries) { - requestParamsList = queries.map(({ params }) => params!); + requestParamsList = queries.map(({ params }) => params); return client.search(queries); }, }); diff --git a/packages/instantsearch.js/src/lib/utils/__tests__/getAppIdAndApiKey-test.ts b/packages/instantsearch.js/src/lib/utils/__tests__/getAppIdAndApiKey-test.ts index 543dbbf865..710ea43499 100644 --- a/packages/instantsearch.js/src/lib/utils/__tests__/getAppIdAndApiKey-test.ts +++ b/packages/instantsearch.js/src/lib/utils/__tests__/getAppIdAndApiKey-test.ts @@ -1,5 +1,5 @@ -import algoliasearchV4 from 'algoliasearch'; import algoliasearchV3 from 'algoliasearch-v3'; +import algoliasearchV4 from 'algoliasearch-v4'; import { liteClient as algoliasearchV5 } from 'algoliasearch-v5/lite'; import { getAppIdAndApiKey } from '../getAppIdAndApiKey'; diff --git a/packages/instantsearch.js/src/lib/utils/hydrateSearchClient.ts b/packages/instantsearch.js/src/lib/utils/hydrateSearchClient.ts index e867c52d5c..212942f8f5 100644 --- a/packages/instantsearch.js/src/lib/utils/hydrateSearchClient.ts +++ b/packages/instantsearch.js/src/lib/utils/hydrateSearchClient.ts @@ -83,7 +83,7 @@ export function hydrateSearchClient( client.search = (requests, ...methodArgs) => { const requestsWithSerializedParams = requests.map((request) => ({ ...request, - params: serializeQueryParameters(request.params!), + params: serializeQueryParameters(request.params), })); return (client as ClientWithTransporter).transporter.responsesCache.get( diff --git a/packages/instantsearch.js/src/middlewares/__tests__/createMetadataMiddleware.ts b/packages/instantsearch.js/src/middlewares/__tests__/createMetadataMiddleware.ts index b886a2853a..60f85874ba 100644 --- a/packages/instantsearch.js/src/middlewares/__tests__/createMetadataMiddleware.ts +++ b/packages/instantsearch.js/src/middlewares/__tests__/createMetadataMiddleware.ts @@ -4,8 +4,9 @@ import { createSearchClient } from '@instantsearch/mocks'; import { wait } from '@instantsearch/testutils/wait'; -import algoliasearch from 'algoliasearch'; import algoliasearchV3 from 'algoliasearch-v3'; +import algoliasearchV4 from 'algoliasearch-v4'; +import { algoliasearch as algoliasearchV5 } from 'algoliasearch-v5'; import { createMetadataMiddleware } from '..'; import instantsearch from '../..'; @@ -236,10 +237,9 @@ describe('createMetadataMiddleware', () => { }); describe('fills it with user agent after start', () => { - it('for the v4 client', async () => { + it('for the v5 client', async () => { const fakeSearchClient = createSearchClient(); - const searchClient = algoliasearch('', ''); - // @ts-expect-error overriding the search method for testing + const searchClient = algoliasearchV5('qsdf', 'qsdf') as any; searchClient.search = fakeSearchClient.search; // not using createMetadataMiddleware() here, @@ -256,20 +256,109 @@ describe('createMetadataMiddleware', () => { expect(document.head.children).toHaveLength(1); expect(document.head.children[0]).toEqual(expect.any(HTMLMetaElement)); + const metadata = JSON.parse( + document.head.querySelector('meta')!.content + ); + + expect(metadata).toEqual({ + ua: expect.any(String), + widgets: expect.any(Array), + }); + expect( - JSON.parse(document.head.querySelector('meta')!.content) - ).toEqual({ - ua: expect.stringMatching( - /^Algolia for JavaScript \(4\.(\d+\.?)+\); Node\.js \((\d+\.?)+\); instantsearch\.js \((\d+\.?)+\); JS Helper \((\d+\.?)+\)$/ - ), + metadata.ua.split(';').map((part: string) => part.trim()) + ).toEqual([ + expect.stringMatching(/Algolia for JavaScript \(5\..*\)/), + expect.stringMatching(/Search \(5\..*\)/), + expect.stringMatching(/Node.js \(.*\)/), + expect.stringMatching(/instantsearch.js \(4\..*\)/), + expect.stringMatching(/JS Helper \(3\..*\)/), + ]); + }); + + it('for the v5 client with custom user agent', async () => { + const fakeSearchClient = createSearchClient(); + const searchClient = algoliasearchV5('qsdf', 'qsdf') as any; + searchClient.search = fakeSearchClient.search; + + // not using createMetadataMiddleware() here, + // since metadata is built into instantsearch + const search = instantsearch({ + searchClient, + indexName: 'test', + }); + + search.start(); + + searchClient.addAlgoliaAgent('test', 'cool'); + + await wait(100); + + expect(document.head.children).toHaveLength(1); + expect(document.head.children[0]).toEqual(expect.any(HTMLMetaElement)); + + const metadata = JSON.parse( + document.head.querySelector('meta')!.content + ); + + expect(metadata).toEqual({ + ua: expect.any(String), + widgets: expect.any(Array), + }); + + expect( + metadata.ua.split(';').map((part: string) => part.trim()) + ).toEqual([ + expect.stringMatching(/Algolia for JavaScript \(5\..*\)/), + expect.stringMatching(/Search \(5\..*\)/), + expect.stringMatching(/Node.js \(.*\)/), + expect.stringMatching(/instantsearch.js \(4\..*\)/), + expect.stringMatching(/JS Helper \(3\..*\)/), + 'test (cool)', + ]); + }); + + it('for the v4 client', async () => { + const fakeSearchClient = createSearchClient(); + const searchClient = algoliasearchV4('', '') as any; + searchClient.search = fakeSearchClient.search; + + // not using createMetadataMiddleware() here, + // since metadata is built into instantsearch + const search = instantsearch({ + searchClient, + indexName: 'test', + }); + + search.start(); + + await wait(100); + + expect(document.head.children).toHaveLength(1); + expect(document.head.children[0]).toEqual(expect.any(HTMLMetaElement)); + + const metadata = JSON.parse( + document.head.querySelector('meta')!.content + ); + + expect(metadata).toEqual({ + ua: expect.any(String), widgets: expect.any(Array), }); + + expect( + metadata.ua.split(';').map((part: string) => part.trim()) + ).toEqual([ + expect.stringMatching(/Algolia for JavaScript \(4\..*\)/), + expect.stringMatching(/Node.js \(.*\)/), + expect.stringMatching(/instantsearch.js \(4\..*\)/), + expect.stringMatching(/JS Helper \(3\..*\)/), + ]); }); it('for the v4 client with custom user agent', async () => { const fakeSearchClient = createSearchClient(); - const searchClient = algoliasearch('', ''); - // @ts-expect-error overriding the search method for testing + const searchClient = algoliasearchV4('', '') as any; searchClient.search = fakeSearchClient.search; // not using createMetadataMiddleware() here, @@ -288,14 +377,24 @@ describe('createMetadataMiddleware', () => { expect(document.head.children).toHaveLength(1); expect(document.head.children[0]).toEqual(expect.any(HTMLMetaElement)); - expect( - JSON.parse(document.head.querySelector('meta')!.content) - ).toEqual({ - ua: expect.stringMatching( - /^Algolia for JavaScript \(4\.(\d+\.?)+\); Node\.js \((\d+\.?)+\); instantsearch\.js \((\d+\.?)+\); JS Helper \((\d+\.?)+\); test \(cool\)$/ - ), + const metadata = JSON.parse( + document.head.querySelector('meta')!.content + ); + + expect(metadata).toEqual({ + ua: expect.any(String), widgets: expect.any(Array), }); + + expect( + metadata.ua.split(';').map((part: string) => part.trim()) + ).toEqual([ + expect.stringMatching(/Algolia for JavaScript \(4\..*\)/), + expect.stringMatching(/Node.js \(.*\)/), + expect.stringMatching(/instantsearch.js \(4\..*\)/), + expect.stringMatching(/JS Helper \(3\..*\)/), + 'test (cool)', + ]); }); it('for the v3 client', async () => { @@ -317,14 +416,23 @@ describe('createMetadataMiddleware', () => { expect(document.head.children).toHaveLength(1); expect(document.head.children[0]).toEqual(expect.any(HTMLMetaElement)); - expect( - JSON.parse(document.head.querySelector('meta')!.content) - ).toEqual({ - ua: expect.stringMatching( - /^Algolia for JavaScript \(3\.(\d+\.?)+\); Node\.js \((\d+\.?)+\); instantsearch\.js \((\d+\.?)+\); JS Helper \((\d+\.?)+\)$/ - ), + const metadata = JSON.parse( + document.head.querySelector('meta')!.content + ); + + expect(metadata).toEqual({ + ua: expect.any(String), widgets: expect.any(Array), }); + + expect( + metadata.ua.split(';').map((part: string) => part.trim()) + ).toEqual([ + expect.stringMatching(/Algolia for JavaScript \(3\..*\)/), + expect.stringMatching(/Node.js \(.*\)/), + expect.stringMatching(/instantsearch.js \(4\..*\)/), + expect.stringMatching(/JS Helper \(3\..*\)/), + ]); }); it('for the v3 client with custom user agent', async () => { @@ -348,14 +456,24 @@ describe('createMetadataMiddleware', () => { expect(document.head.children).toHaveLength(1); expect(document.head.children[0]).toEqual(expect.any(HTMLMetaElement)); - expect( - JSON.parse(document.head.querySelector('meta')!.content) - ).toEqual({ - ua: expect.stringMatching( - /^Algolia for JavaScript \(3\.(\d+\.?)+\); Node\.js \((\d+\.?)+\); instantsearch\.js \((\d+\.?)+\); JS Helper \((\d+\.?)+\); test \(cool\)$/ - ), + const metadata = JSON.parse( + document.head.querySelector('meta')!.content + ); + + expect(metadata).toEqual({ + ua: expect.any(String), widgets: expect.any(Array), }); + + expect( + metadata.ua.split(';').map((part: string) => part.trim()) + ).toEqual([ + expect.stringMatching(/Algolia for JavaScript \(3\..*\)/), + expect.stringMatching(/Node.js \(.*\)/), + expect.stringMatching(/instantsearch.js \(4\..*\)/), + expect.stringMatching(/JS Helper \(3\..*\)/), + 'test (cool)', + ]); }); it('for a custom client (does not error)', async () => { diff --git a/packages/instantsearch.js/src/types/widget.ts b/packages/instantsearch.js/src/types/widget.ts index 3888b0a06a..031339fc9d 100644 --- a/packages/instantsearch.js/src/types/widget.ts +++ b/packages/instantsearch.js/src/types/widget.ts @@ -1,4 +1,5 @@ import type { IndexWidget } from '../widgets'; +import type { RecommendResponse } from './algoliasearch'; import type { InstantSearch } from './instantsearch'; import type { IndexRenderState, WidgetRenderState } from './render-state'; import type { IndexUiState, UiState } from './ui-state'; @@ -8,7 +9,6 @@ import type { SearchParameters, SearchResults, RecommendParameters, - RecommendResultItem, } from 'algoliasearch-helper'; export type ScopedResult = { @@ -161,7 +161,7 @@ type SearchWidget = { }; type RecommendRenderOptions = SharedRenderOptions & { - results: RecommendResultItem; + results: RecommendResponse; }; type RecommendWidget< diff --git a/packages/instantsearch.js/src/widgets/frequently-bought-together/frequently-bought-together.tsx b/packages/instantsearch.js/src/widgets/frequently-bought-together/frequently-bought-together.tsx index ee8e132d84..261dd12748 100644 --- a/packages/instantsearch.js/src/widgets/frequently-bought-together/frequently-bought-together.tsx +++ b/packages/instantsearch.js/src/widgets/frequently-bought-together/frequently-bought-together.tsx @@ -20,11 +20,11 @@ import type { PreparedTemplateProps } from '../../lib/templating'; import type { Template, WidgetFactory, - Hit, + AlgoliaHit, Renderer, BaseHit, + RecommendResponse, } from '../../types'; -import type { RecommendResultItem } from 'algoliasearch-helper'; import type { RecommendClassNames, FrequentlyBoughtTogetherProps as FrequentlyBoughtTogetherUiProps, @@ -81,7 +81,7 @@ const renderer = /> ) : undefined - ) as FrequentlyBoughtTogetherUiProps['headerComponent']; + ) as FrequentlyBoughtTogetherUiProps['headerComponent']; const itemComponent = ( templates.item @@ -96,7 +96,7 @@ const renderer = ); } : undefined - ) as FrequentlyBoughtTogetherUiProps['itemComponent']; + ) as FrequentlyBoughtTogetherUiProps['itemComponent']; const emptyComponent = ( templates.empty @@ -109,7 +109,7 @@ const renderer = /> ) : undefined - ) as FrequentlyBoughtTogetherUiProps['emptyComponent']; + ) as FrequentlyBoughtTogetherUiProps['emptyComponent']; render( >>; + empty: Template>>; /** * Template to use for the header of the widget. @@ -142,7 +142,7 @@ export type FrequentlyBoughtTogetherTemplates< Pick< Parameters< NonNullable< - FrequentlyBoughtTogetherUiProps>['headerComponent'] + FrequentlyBoughtTogetherUiProps>['headerComponent'] > >[0], 'items' @@ -152,7 +152,7 @@ export type FrequentlyBoughtTogetherTemplates< /** * Template to use for each result. This template will receive an object containing a single record. */ - item: Template>; + item: Template>; }>; type FrequentlyBoughtTogetherWidgetParams< diff --git a/packages/instantsearch.js/src/widgets/index/__tests__/index-test.ts b/packages/instantsearch.js/src/widgets/index/__tests__/index-test.ts index 237ab721ea..29fe4d1bee 100644 --- a/packages/instantsearch.js/src/widgets/index/__tests__/index-test.ts +++ b/packages/instantsearch.js/src/widgets/index/__tests__/index-test.ts @@ -4,6 +4,7 @@ import { createSearchClient, + createSingleRecommendResponse, createSingleSearchResponse, } from '@instantsearch/mocks'; import { wait } from '@instantsearch/testutils'; @@ -3484,7 +3485,9 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/index-widge recommendResults: { params: [{ $$id: 0, objectID: '1' }], results: { - 0: createSingleSearchResponse({ hits: [{ objectID: '1' }] }), + 0: createSingleRecommendResponse({ + hits: [{ objectID: '1', _score: 0 }], + }), }, }, }, @@ -3497,7 +3500,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/index-widge 0: { exhaustiveFacetsCount: true, exhaustiveNbHits: true, - hits: [{ objectID: '1' }], + hits: [{ objectID: '1', _score: 0 }], hitsPerPage: 20, nbHits: 1, nbPages: 1, @@ -3513,7 +3516,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/index-widge 0: { exhaustiveFacetsCount: true, exhaustiveNbHits: true, - hits: [{ objectID: '1' }], + hits: [{ objectID: '1', _score: 0 }], hitsPerPage: 20, nbHits: 1, nbPages: 1, diff --git a/packages/instantsearch.js/src/widgets/index/index.ts b/packages/instantsearch.js/src/widgets/index/index.ts index 79c05b938c..1818b65a19 100644 --- a/packages/instantsearch.js/src/widgets/index/index.ts +++ b/packages/instantsearch.js/src/widgets/index/index.ts @@ -21,6 +21,7 @@ import type { SearchClient, IndexRenderState, RenderOptions, + RecommendResponse, } from '../../types'; import type { AlgoliaSearchHelper as Helper, @@ -30,7 +31,6 @@ import type { SearchResults, AlgoliaSearchHelper, RecommendParameters, - RecommendResultItem, } from 'algoliasearch-helper'; const withUsage = createDocumentationMessageGenerator({ @@ -77,7 +77,7 @@ export type IndexWidget = Omit< getResults: () => SearchResults | null; getResultsForWidget: ( widget: IndexWidget | Widget - ) => SearchResults | RecommendResultItem | null; + ) => SearchResults | RecommendResponse | null; getPreviousState: () => SearchParameters | null; getScopedResults: () => ScopedResult[]; getParent: () => IndexWidget | null; diff --git a/packages/instantsearch.js/src/widgets/looking-similar/looking-similar.tsx b/packages/instantsearch.js/src/widgets/looking-similar/looking-similar.tsx index c71ee1bc1a..e8bb0772b5 100644 --- a/packages/instantsearch.js/src/widgets/looking-similar/looking-similar.tsx +++ b/packages/instantsearch.js/src/widgets/looking-similar/looking-similar.tsx @@ -20,11 +20,11 @@ import type { PreparedTemplateProps } from '../../lib/templating'; import type { Template, WidgetFactory, - Hit, + AlgoliaHit, Renderer, BaseHit, + RecommendResponse, } from '../../types'; -import type { RecommendResultItem } from 'algoliasearch-helper'; import type { RecommendClassNames, LookingSimilarProps as LookingSimilarUiProps, @@ -77,7 +77,7 @@ function createRenderer = BaseHit>({ /> ) : undefined - ) as LookingSimilarUiProps['headerComponent']; + ) as LookingSimilarUiProps['headerComponent']; const itemComponent = ( templates.item @@ -92,7 +92,7 @@ function createRenderer = BaseHit>({ ); } : undefined - ) as LookingSimilarUiProps['itemComponent']; + ) as LookingSimilarUiProps['itemComponent']; const emptyComponent = ( templates.empty @@ -105,7 +105,7 @@ function createRenderer = BaseHit>({ /> ) : undefined - ) as LookingSimilarUiProps['emptyComponent']; + ) as LookingSimilarUiProps['emptyComponent']; render( >>; + empty: Template>>; /** * Template to use for the header of the widget. @@ -138,7 +138,7 @@ export type LookingSimilarTemplates< header: Template< Pick< Parameters< - NonNullable>['headerComponent']> + NonNullable>['headerComponent']> >[0], 'items' > & { cssClasses: RecommendClassNames } @@ -147,7 +147,7 @@ export type LookingSimilarTemplates< /** * Template to use for each result. This template will receive an object containing a single record. */ - item: Template>; + item: Template>; }>; type LookingSimilarWidgetParams = BaseHit> = { diff --git a/packages/instantsearch.js/src/widgets/refinement-list/__tests__/refinement-list.test.tsx b/packages/instantsearch.js/src/widgets/refinement-list/__tests__/refinement-list.test.tsx index 058481e8e0..7a2aed7213 100644 --- a/packages/instantsearch.js/src/widgets/refinement-list/__tests__/refinement-list.test.tsx +++ b/packages/instantsearch.js/src/widgets/refinement-list/__tests__/refinement-list.test.tsx @@ -1182,6 +1182,7 @@ function createMockedSearchClient() { ) ); }), + // @ts-ignore v5 only accepts `search({ type: 'facet' })`, but v4, v3 has an explicit method searchForFacetValues: jest.fn((requests) => { return Promise.resolve([ createSFFVResponse({ diff --git a/packages/instantsearch.js/src/widgets/related-products/related-products.tsx b/packages/instantsearch.js/src/widgets/related-products/related-products.tsx index 55359282b4..691c4c3d42 100644 --- a/packages/instantsearch.js/src/widgets/related-products/related-products.tsx +++ b/packages/instantsearch.js/src/widgets/related-products/related-products.tsx @@ -20,11 +20,11 @@ import type { PreparedTemplateProps } from '../../lib/templating'; import type { Template, WidgetFactory, - Hit, + AlgoliaHit, Renderer, BaseHit, + RecommendResponse, } from '../../types'; -import type { RecommendResultItem } from 'algoliasearch-helper'; import type { RecommendClassNames, RelatedProductsProps as RelatedProductsUiProps, @@ -87,7 +87,7 @@ function createRenderer = BaseHit>({ /> ) : undefined - ) as RelatedProductsUiProps['headerComponent']; + ) as RelatedProductsUiProps['headerComponent']; const itemComponent = ( templates.item @@ -102,7 +102,7 @@ function createRenderer = BaseHit>({ ); } : undefined - ) as RelatedProductsUiProps['itemComponent']; + ) as RelatedProductsUiProps['itemComponent']; const emptyComponent = ( templates.empty @@ -115,7 +115,7 @@ function createRenderer = BaseHit>({ /> ) : undefined - ) as RelatedProductsUiProps['emptyComponent']; + ) as RelatedProductsUiProps['emptyComponent']; render( >>; + empty: Template>>; /** * Template to use for the header of the widget. @@ -148,7 +148,7 @@ export type RelatedProductsTemplates< header: Template< Pick< Parameters< - NonNullable>['headerComponent']> + NonNullable>['headerComponent']> >[0], 'items' > & { cssClasses: RecommendClassNames } @@ -157,7 +157,7 @@ export type RelatedProductsTemplates< /** * Template to use for each result. This template will receive an object containing a single record. */ - item: Template>; + item: Template>; }>; type RelatedProductsWidgetParams = BaseHit> = { diff --git a/packages/instantsearch.js/src/widgets/trending-items/trending-items.tsx b/packages/instantsearch.js/src/widgets/trending-items/trending-items.tsx index 842f3787e6..ad343b60fe 100644 --- a/packages/instantsearch.js/src/widgets/trending-items/trending-items.tsx +++ b/packages/instantsearch.js/src/widgets/trending-items/trending-items.tsx @@ -20,11 +20,11 @@ import type { PreparedTemplateProps } from '../../lib/templating'; import type { Template, WidgetFactory, - Hit, + AlgoliaHit, Renderer, BaseHit, + RecommendResponse, } from '../../types'; -import type { RecommendResultItem } from 'algoliasearch-helper'; import type { RecommendClassNames, TrendingItemsProps as TrendingItemsUiProps, @@ -87,7 +87,7 @@ function createRenderer = BaseHit>({ /> ) : undefined - ) as TrendingItemsUiProps['headerComponent']; + ) as TrendingItemsUiProps['headerComponent']; const itemComponent = ( templates.item @@ -102,7 +102,7 @@ function createRenderer = BaseHit>({ ); } : undefined - ) as TrendingItemsUiProps['itemComponent']; + ) as TrendingItemsUiProps['itemComponent']; const emptyComponent = ( templates.empty @@ -115,7 +115,7 @@ function createRenderer = BaseHit>({ /> ) : undefined - ) as TrendingItemsUiProps['emptyComponent']; + ) as TrendingItemsUiProps['emptyComponent']; render( = BaseHit> = /** * Template to use when there are no results. */ - empty: Template>>; + empty: Template>>; /** * Template to use for the header of the widget. @@ -147,7 +147,7 @@ export type TrendingItemsTemplates = BaseHit> = header: Template< Pick< Parameters< - NonNullable>['headerComponent']> + NonNullable>['headerComponent']> >[0], 'items' > & { cssClasses: RecommendClassNames } @@ -156,7 +156,7 @@ export type TrendingItemsTemplates = BaseHit> = /** * Template to use for each result. This template will receive an object containing a single record. */ - item: Template>; + item: Template>; }>; type TrendingItemsWidgetParams = BaseHit> = { diff --git a/packages/instantsearch.js/src/widgets/voice-search/__tests__/voice-search-test.ts b/packages/instantsearch.js/src/widgets/voice-search/__tests__/voice-search-test.ts index ea946a5bcd..210d147dc8 100644 --- a/packages/instantsearch.js/src/widgets/voice-search/__tests__/voice-search-test.ts +++ b/packages/instantsearch.js/src/widgets/voice-search/__tests__/voice-search-test.ts @@ -2,9 +2,11 @@ * @jest-environment jsdom */ -import { createSingleSearchResponse } from '@instantsearch/mocks'; +import { + createSearchClient, + createSingleSearchResponse, +} from '@instantsearch/mocks'; import { castToJestMock } from '@instantsearch/testutils/castToJestMock'; -import algoliasearch from 'algoliasearch'; import algoliasearchHelper, { SearchResults, SearchParameters, @@ -84,7 +86,7 @@ describe('voiceSearch()', () => { beforeEach(() => { render.mockClear(); - helper = algoliasearchHelper(algoliasearch('APP_ID', 'API_KEY'), '', {}); + helper = algoliasearchHelper(createSearchClient(), '', {}); helper.setQuery = jest.fn(); helper.search = jest.fn(); helper.state = new SearchParameters({ query: '' }); diff --git a/packages/react-instantsearch-core/src/components/__tests__/InstantSearchSSRProvider.test.tsx b/packages/react-instantsearch-core/src/components/__tests__/InstantSearchSSRProvider.test.tsx index fc9ff38d4d..8550583390 100644 --- a/packages/react-instantsearch-core/src/components/__tests__/InstantSearchSSRProvider.test.tsx +++ b/packages/react-instantsearch-core/src/components/__tests__/InstantSearchSSRProvider.test.tsx @@ -9,7 +9,8 @@ import { } from '@instantsearch/mocks'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import algoliasearch from 'algoliasearch'; +import algoliasearchV4 from 'algoliasearch-v4'; +import { algoliasearch as algoliasearchV5 } from 'algoliasearch-v5'; import { history } from 'instantsearch.js/es/lib/routers'; import { simple } from 'instantsearch.js/es/lib/stateMappings'; import React, { StrictMode } from 'react'; @@ -18,7 +19,7 @@ import { Hits, RefinementList, SearchBox } from 'react-instantsearch'; import { InstantSearch } from '../InstantSearch'; import { InstantSearchSSRProvider } from '../InstantSearchSSRProvider'; -import type { Hit as AlgoliaHit } from 'instantsearch.js'; +import type { Hit as AlgoliaHit, SearchClient } from 'instantsearch.js'; function HitComponent({ hit }: { hit: AlgoliaHit }) { return <>{hit.objectID}; @@ -471,66 +472,72 @@ describe('InstantSearchSSRProvider', () => { }); }); - test('caches the initial results to avoid a client-side request', async () => { - const send = jest.fn(() => - Promise.resolve({ - content: JSON.stringify(createMultiSearchResponse()), - isTimedOut: false, - status: 200, - }) - ); - const searchClient = algoliasearch('appId', 'apiKey', { - requester: { send }, - }); - const initialResults = { - indexName: { - state: {}, - results: [ - { - exhaustiveFacetsCount: true, - exhaustiveNbHits: true, - hits: [{ objectID: '1' }, { objectID: '2' }, { objectID: '3' }], - hitsPerPage: 20, - index: 'indexName', - nbHits: 0, - nbPages: 0, - page: 0, - params: '', - processingTimeMS: 0, - query: '', - }, - ], - }, - }; - - function App() { - return ( - - - - - - - + test.each([ + ['v4', algoliasearchV4], + ['v5', algoliasearchV5], + ])( + 'caches the initial results to avoid a client-side request (%s)', + async (_, ctor) => { + const send = jest.fn(() => + Promise.resolve({ + content: JSON.stringify(createMultiSearchResponse()), + isTimedOut: false, + status: 200, + }) ); - } + const searchClient = ctor('appId', 'apiKey', { + requester: { send }, + }) as unknown as SearchClient; + const initialResults = { + indexName: { + state: {}, + results: [ + { + exhaustiveFacetsCount: true, + exhaustiveNbHits: true, + hits: [{ objectID: '1' }, { objectID: '2' }, { objectID: '3' }], + hitsPerPage: 20, + index: 'indexName', + nbHits: 0, + nbPages: 0, + page: 0, + params: '', + processingTimeMS: 0, + query: '', + }, + ], + }, + }; + + function App() { + return ( + + + + + + + + ); + } - render(); + render(); - await waitFor(() => { - expect(send).toHaveBeenCalledTimes(0); - }); + await waitFor(() => { + expect(send).toHaveBeenCalledTimes(0); + }); - userEvent.type(screen.getByRole('searchbox'), 'i'); + userEvent.type(screen.getByRole('searchbox'), 'i'); - await waitFor(() => { - expect(send).toHaveBeenCalledTimes(1); - }); + await waitFor(() => { + expect(send).toHaveBeenCalledTimes(1); + }); - userEvent.clear(screen.getByRole('searchbox')); + userEvent.clear(screen.getByRole('searchbox')); - await waitFor(() => { - expect(send).toHaveBeenCalledTimes(1); - }); - }); + await waitFor(() => { + expect(send).toHaveBeenCalledTimes(1); + }); + } + ); }); diff --git a/packages/react-instantsearch-nextjs/src/InitializePromise.tsx b/packages/react-instantsearch-nextjs/src/InitializePromise.tsx index 1b98293c0e..2fb3e96509 100644 --- a/packages/react-instantsearch-nextjs/src/InitializePromise.tsx +++ b/packages/react-instantsearch-nextjs/src/InitializePromise.tsx @@ -36,7 +36,7 @@ export function InitializePromise({ nonce }: InitializePromiseProps) { search.mainHelper!.setClient({ ...search.mainHelper!.getClient(), search(queries) { - requestParamsList = queries.map(({ params }) => params!); + requestParamsList = queries.map(({ params }) => params); return search.client.search(queries); }, }); diff --git a/packages/react-instantsearch/src/widgets/FrequentlyBoughtTogether.tsx b/packages/react-instantsearch/src/widgets/FrequentlyBoughtTogether.tsx index 07b13c6623..dc54fb48e9 100644 --- a/packages/react-instantsearch/src/widgets/FrequentlyBoughtTogether.tsx +++ b/packages/react-instantsearch/src/widgets/FrequentlyBoughtTogether.tsx @@ -9,11 +9,11 @@ import type { FrequentlyBoughtTogetherProps as FrequentlyBoughtTogetherPropsUiComponentProps, Pragma, } from 'instantsearch-ui-components'; -import type { Hit, BaseHit } from 'instantsearch.js'; +import type { AlgoliaHit, BaseHit } from 'instantsearch.js'; import type { UseFrequentlyBoughtTogetherProps } from 'react-instantsearch-core'; type UiProps = Pick< - FrequentlyBoughtTogetherPropsUiComponentProps>, + FrequentlyBoughtTogetherPropsUiComponentProps>, | 'items' | 'itemComponent' | 'headerComponent' @@ -23,7 +23,7 @@ type UiProps = Pick< >; export type FrequentlyBoughtTogetherProps = Omit< - FrequentlyBoughtTogetherPropsUiComponentProps>, + FrequentlyBoughtTogetherPropsUiComponentProps>, keyof UiProps > & UseFrequentlyBoughtTogetherProps & { diff --git a/packages/react-instantsearch/src/widgets/LookingSimilar.tsx b/packages/react-instantsearch/src/widgets/LookingSimilar.tsx index aea86ec091..948240d408 100644 --- a/packages/react-instantsearch/src/widgets/LookingSimilar.tsx +++ b/packages/react-instantsearch/src/widgets/LookingSimilar.tsx @@ -6,11 +6,11 @@ import type { LookingSimilarProps as LookingSimilarPropsUiComponentProps, Pragma, } from 'instantsearch-ui-components'; -import type { Hit, BaseHit } from 'instantsearch.js'; +import type { AlgoliaHit, BaseHit } from 'instantsearch.js'; import type { UseLookingSimilarProps } from 'react-instantsearch-core'; type UiProps = Pick< - LookingSimilarPropsUiComponentProps>, + LookingSimilarPropsUiComponentProps>, | 'items' | 'itemComponent' | 'headerComponent' @@ -20,7 +20,7 @@ type UiProps = Pick< >; export type LookingSimilarProps = Omit< - LookingSimilarPropsUiComponentProps>, + LookingSimilarPropsUiComponentProps>, keyof UiProps > & UseLookingSimilarProps & { diff --git a/packages/react-instantsearch/src/widgets/RelatedProducts.tsx b/packages/react-instantsearch/src/widgets/RelatedProducts.tsx index 89087fb0de..4dd565a6d0 100644 --- a/packages/react-instantsearch/src/widgets/RelatedProducts.tsx +++ b/packages/react-instantsearch/src/widgets/RelatedProducts.tsx @@ -6,7 +6,7 @@ import type { RelatedProductsProps as RelatedProductsUiComponentProps, Pragma, } from 'instantsearch-ui-components'; -import type { Hit, BaseHit } from 'instantsearch.js'; +import type { AlgoliaHit, BaseHit } from 'instantsearch.js'; import type { UseRelatedProductsProps } from 'react-instantsearch-core'; type UiProps = Pick< @@ -62,7 +62,7 @@ export function RelatedProducts({ ); const uiProps: UiProps = { - items: items as Array>, + items: items as Array>, itemComponent, headerComponent, emptyComponent, diff --git a/packages/react-instantsearch/src/widgets/TrendingItems.tsx b/packages/react-instantsearch/src/widgets/TrendingItems.tsx index 1196c46fa8..2a9516cddb 100644 --- a/packages/react-instantsearch/src/widgets/TrendingItems.tsx +++ b/packages/react-instantsearch/src/widgets/TrendingItems.tsx @@ -6,7 +6,7 @@ import type { TrendingItemsProps as TrendingItemsUiComponentProps, Pragma, } from 'instantsearch-ui-components'; -import type { Hit, BaseHit } from 'instantsearch.js'; +import type { AlgoliaHit, BaseHit } from 'instantsearch.js'; import type { UseTrendingItemsProps } from 'react-instantsearch-core'; type UiProps = Pick< @@ -66,7 +66,7 @@ export function TrendingItems({ ); const uiProps: UiProps = { - items: items as Array>, + items: items as Array>, itemComponent, headerComponent, emptyComponent, diff --git a/packages/react-instantsearch/src/widgets/__tests__/RefinementList.test.tsx b/packages/react-instantsearch/src/widgets/__tests__/RefinementList.test.tsx index 492fe4fad9..6b078a950b 100644 --- a/packages/react-instantsearch/src/widgets/__tests__/RefinementList.test.tsx +++ b/packages/react-instantsearch/src/widgets/__tests__/RefinementList.test.tsx @@ -104,6 +104,7 @@ function createMockedSearchClient(parameters: Record = {}) { ) ); }), + // @ts-ignore v5 accepts only `search({ type: 'facet' })`, v3, v4 accept `searchForFacetValues` searchForFacetValues: jest.fn(() => Promise.resolve([ createSFFVResponse({ diff --git a/scripts/legacy/downgrade-algoliasearch-dependency.js b/scripts/legacy/downgrade-algoliasearch-dependency.js index d79da39dd9..ac608d4007 100755 --- a/scripts/legacy/downgrade-algoliasearch-dependency.js +++ b/scripts/legacy/downgrade-algoliasearch-dependency.js @@ -23,7 +23,7 @@ console.log( // change main dependency shell.sed( '-i', - /"algoliasearch": "4.*"(,?)/, + /"algoliasearch": "5.*"(,?)/, '"algoliasearch": "3.35.1","@types/algoliasearch": "3.34.10"$1', packageJsonPaths ); @@ -31,17 +31,29 @@ shell.sed( // remove other v4 dependencies shell.sed( '-i', - /"@algolia\/(cache-.*|client-.*|logger-.*|requester-.*|transporter)": "4.*",?/, + /"@algolia\/(cache-.*|client-.*|logger-.*|requester-.*|transporter|recommend)": "(4|5).*",?/, '', packageJsonPaths ); -// remove v5 dependency +// remove resolution +shell.sed('-i', /"places.js\/algoliasearch": "5.*"(,?)/, '', packageJsonPaths); + +// replace import in examples shell.sed( '-i', - /"algoliasearch-v5": "npm:algoliasearch@5.*"(,?)/, - '', - packageJsonPaths + /import { liteClient as algoliasearch } from 'algoliasearch\/lite'/, + "import algoliasearch from 'algoliasearch/lite'", + ...shell.ls('examples/*/*/*.{js,ts,tsx,vue}'), + ...shell.ls('examples/*/*/{src,pages,app}/*.{js,ts,tsx,vue}') +); + +// replace dependency in examples +shell.sed( + '-i', + /"algoliasearch": ".*"(,)?/, + '"algoliasearch": "3.35.1","@types/algoliasearch": "3.34.10"$1', + ...shell.ls('examples/*/*/package.json') ); shell.exec('yarn install'); diff --git a/tests/common/connectors/pagination/routing.ts b/tests/common/connectors/pagination/routing.ts index d39dbd88fc..7f260f0b33 100644 --- a/tests/common/connectors/pagination/routing.ts +++ b/tests/common/connectors/pagination/routing.ts @@ -41,7 +41,7 @@ export function createRoutingTests( return createMultiSearchResponse( ...requests.map(({ params }) => createSingleSearchResponse({ - page: params!.page, + page: params.page, nbPages: 20, }) ) diff --git a/tests/common/shared/insights.ts b/tests/common/shared/insights.ts index 2925e94153..00b1303a2a 100644 --- a/tests/common/shared/insights.ts +++ b/tests/common/shared/insights.ts @@ -39,7 +39,7 @@ export function createInsightsTests( params, }: Parameters[0][number]) => createSingleSearchResponse({ - // @ts-expect-error this key is private, thus not in the types + // @ts-ignore this key doesn't exist in v3, v4 types _automaticInsights: true, hits: [{ objectID: '1' }], facets: { @@ -48,7 +48,7 @@ export function createInsightsTests( Apple: 200, }, }, - page: params!.page, + page: params.page, nbPages: 20, }) ) @@ -131,7 +131,7 @@ export function createInsightsTests( Apple: 200, }, }, - page: params!.page, + page: params.page, nbPages: 20, }) ) diff --git a/tests/common/shared/routing.ts b/tests/common/shared/routing.ts index 1b4e72c4b2..60a260e1a5 100644 --- a/tests/common/shared/routing.ts +++ b/tests/common/shared/routing.ts @@ -51,7 +51,7 @@ export function createRoutingTests( Apple: 200, }, }, - page: params!.page, + page: params.page, nbPages: 20, }) ) diff --git a/tests/common/widgets/infinite-hits/optimistic-ui.ts b/tests/common/widgets/infinite-hits/optimistic-ui.ts index d01737aab4..5a25cd014a 100644 --- a/tests/common/widgets/infinite-hits/optimistic-ui.ts +++ b/tests/common/widgets/infinite-hits/optimistic-ui.ts @@ -33,11 +33,11 @@ export function createOptimisticUiTests( createSingleSearchResponse({ hits: Array.from({ length: hitsPerPage }).map( (_, index) => ({ - objectID: `${params!.page! * hitsPerPage + index}`, + objectID: `${params.page! * hitsPerPage + index}`, }) ), - query: params!.query, - page: params!.page, + query: params.query, + page: params.page, nbPages: 20, }) ) @@ -108,11 +108,11 @@ export function createOptimisticUiTests( createSingleSearchResponse({ hits: Array.from({ length: hitsPerPage }).map( (_, index) => ({ - objectID: `${params!.page! * hitsPerPage + index}`, + objectID: `${params.page! * hitsPerPage + index}`, }) ), - query: params!.query, - page: params!.page, + query: params.query, + page: params.page, nbPages: 20, }) ) @@ -186,11 +186,11 @@ export function createOptimisticUiTests( createSingleSearchResponse({ hits: Array.from({ length: hitsPerPage }).map( (_, index) => ({ - objectID: `${params!.page! * hitsPerPage + index}`, + objectID: `${params.page! * hitsPerPage + index}`, }) ), - query: params!.query, - page: params!.page, + query: params.query, + page: params.page, nbPages: 20, }) ) diff --git a/tests/common/widgets/instantsearch/algolia-agent.ts b/tests/common/widgets/instantsearch/algolia-agent.ts index 95a97f9cd4..6abd3c3860 100644 --- a/tests/common/widgets/instantsearch/algolia-agent.ts +++ b/tests/common/widgets/instantsearch/algolia-agent.ts @@ -1,15 +1,65 @@ -import algoliasearch from 'algoliasearch'; +import algoliasearchV3 from 'algoliasearch-v3'; +import algoliasearchV4 from 'algoliasearch-v4'; +import { algoliasearch as algoliasearchV5 } from 'algoliasearch-v5'; import type { InstantSearchWidgetSetup } from '.'; import type { TestOptions } from '../../common'; +import type { SearchClient } from 'instantsearch.js'; export function createAlgoliaAgentTests( setup: InstantSearchWidgetSetup, _options: Required ) { describe('algolia agent', () => { + test('sets the correct algolia agents with v3', async () => { + const searchClient = algoliasearchV3( + 'appId', + 'apiKey' + ) as unknown as SearchClient; + const options = { + instantSearchOptions: { + indexName: 'indexName', + searchClient, + }, + widgetParams: {}, + }; + + const { algoliaAgents } = await setup(options); + + const algoliaAgent: string = getAgent(searchClient); + + expect(algoliaAgent.split(';').map((agent) => agent.trim())).toEqual( + expect.arrayContaining(algoliaAgents) + ); + }); + + test('sets the correct algolia agents with v4', async () => { + const searchClient = algoliasearchV4( + 'appId', + 'apiKey' + ) as unknown as SearchClient; + const options = { + instantSearchOptions: { + indexName: 'indexName', + searchClient, + }, + widgetParams: {}, + }; + + const { algoliaAgents } = await setup(options); + + const algoliaAgent: string = getAgent(searchClient); + + expect(algoliaAgent.split(';').map((agent) => agent.trim())).toEqual( + expect.arrayContaining(algoliaAgents) + ); + }); + test('sets the correct algolia agents', async () => { - const searchClient = algoliasearch('appId', 'apiKey'); + const searchClient = algoliasearchV5( + 'appId', + 'apiKey' + ) as unknown as SearchClient; const options = { instantSearchOptions: { indexName: 'indexName', @@ -20,9 +70,7 @@ export function createAlgoliaAgentTests( const { algoliaAgents } = await setup(options); - const algoliaAgent: string = (searchClient as any).transporter - ? (searchClient as any).transporter.userAgent.value - : (searchClient as any)._ua; + const algoliaAgent: string = getAgent(searchClient); expect(algoliaAgent.split(';').map((agent) => agent.trim())).toEqual( expect.arrayContaining(algoliaAgents) @@ -30,3 +78,17 @@ export function createAlgoliaAgentTests( }); }); } + +function getAgent(searchClient: any) { + if (searchClient.transporter && searchClient.transporter.userAgent) { + return searchClient.transporter.userAgent.value; + } + if (searchClient.transporter && searchClient.transporter.algoliaAgent) { + return searchClient.transporter.algoliaAgent.value; + } + if (searchClient._ua) { + return searchClient._ua; + } + + throw new Error('Could not find the algolia agent'); +} diff --git a/tests/common/widgets/pagination/optimistic-ui.ts b/tests/common/widgets/pagination/optimistic-ui.ts index 0665685196..39ade775d7 100644 --- a/tests/common/widgets/pagination/optimistic-ui.ts +++ b/tests/common/widgets/pagination/optimistic-ui.ts @@ -26,7 +26,7 @@ export function createOptimisticUiTests( return createMultiSearchResponse( ...requests.map(({ params }) => createSingleSearchResponse({ - page: params!.page, + page: params.page, nbPages: 20, }) ) @@ -148,7 +148,7 @@ export function createOptimisticUiTests( return createMultiSearchResponse( ...requests.map(({ params }) => createSingleSearchResponse({ - page: params!.page, + page: params.page, nbPages: 20, }) ) diff --git a/tests/common/widgets/refinement-list/options.ts b/tests/common/widgets/refinement-list/options.ts index a6691fdc80..87abf5e225 100644 --- a/tests/common/widgets/refinement-list/options.ts +++ b/tests/common/widgets/refinement-list/options.ts @@ -1,6 +1,6 @@ import { - createAlgoliaSearchClient, createMultiSearchResponse, + createSearchClient, createSFFVResponse, createSingleSearchResponse, } from '@instantsearch/mocks'; @@ -1491,7 +1491,7 @@ const FACET_HITS = [ ]; function createMockedSearchClient(parameters: Record = {}) { - return createAlgoliaSearchClient({ + return createSearchClient({ search: jest.fn((requests) => { return Promise.resolve( createMultiSearchResponse( @@ -1532,7 +1532,7 @@ function createMockedSearchClient(parameters: Record = {}) { facetHits: FACET_HITS, }), ]) - ), + ) as any, // @TODO: for now casted as any, because v5 only has `type: facet` in search ...parameters, }); } diff --git a/tests/mocks/createAPIResponse.ts b/tests/mocks/createAPIResponse.ts index 5c9058c472..5a34ab1f34 100644 --- a/tests/mocks/createAPIResponse.ts +++ b/tests/mocks/createAPIResponse.ts @@ -1,8 +1,9 @@ -import type { RecommendQueriesResponse } from '@algolia/recommend'; import type { SearchResponse, SearchResponses, SearchForFacetValuesResponse, + RecommendResponse, + RecommendResponses, } from 'instantsearch.js'; export const defaultRenderingContent: SearchResponse['renderingContent'] = @@ -88,8 +89,42 @@ export const createSFFVResponse = ( ...args, }); +export const createSingleRecommendResponse = ( + subset: Partial> = {} +): RecommendResponse => { + const { + query = '', + page = 0, + hitsPerPage = 20, + hits = [], + nbHits = hits.length, + nbPages = Math.ceil(nbHits / hitsPerPage), + params = '', + exhaustiveNbHits = true, + exhaustiveFacetsCount = true, + processingTimeMS = 0, + ...rest + } = subset; + + return { + page, + hitsPerPage, + nbHits, + nbPages, + processingTimeMS, + hits, + query, + params, + exhaustiveNbHits, + exhaustiveFacetsCount, + ...rest, + }; +}; + export const createRecommendResponse = ( - requests: readonly any[] -): RecommendQueriesResponse => { - return { results: requests.map(createSingleSearchResponse) }; + requests: any[] +): RecommendResponses => { + return { + results: requests.map(createSingleRecommendResponse), + }; }; diff --git a/tests/mocks/createAlgoliaSearchClient.ts b/tests/mocks/createAlgoliaSearchClient.ts index 9027a08594..3dbab976a3 100644 --- a/tests/mocks/createAlgoliaSearchClient.ts +++ b/tests/mocks/createAlgoliaSearchClient.ts @@ -1,14 +1,18 @@ import { createNullCache } from '@algolia/cache-common'; import { createInMemoryCache } from '@algolia/cache-in-memory'; import { createNullLogger } from '@algolia/logger-common'; -import { createNodeHttpRequester } from '@algolia/requester-node-http'; +import * as HTTPRequester from '@algolia/requester-node-http'; import { serializeQueryParameters, createTransporter, CallEnum, createUserAgent, } from '@algolia/transporter'; -import algoliasearch from 'algoliasearch'; +import { + // @ts-ignore fails in v3, v4 + algoliasearch as namedConstructor, + default as defaultConstructor, +} from 'algoliasearch'; import { createSingleSearchResponse, @@ -17,19 +21,25 @@ import { } from './createAPIResponse'; import type { HostOptions } from '@algolia/transporter'; +import type { SearchClient } from 'algoliasearch-helper/types/algoliasearch'; type OverrideKeys = TOptions extends Record ? TTarget : Omit & TOptions; -type SearchClient = ReturnType; +const algoliasearch = (namedConstructor || defaultConstructor) as unknown as ( + appId: string, + apiKey: string +) => SearchClient; export type MockSearchClient = OverrideKeys< SearchClient, - { - search: jest.Mock; - searchForFacetValues: jest.Mock; - } + SearchClient extends { searchForFacetValues: (...args: any[]) => any } + ? { + search: jest.Mock; + searchForFacetValues: jest.Mock; + } + : { search: jest.Mock } >; export function createAlgoliaSearchClient< @@ -47,7 +57,10 @@ export function createAlgoliaSearchClient< write: 30, }, userAgent: createUserAgent('test'), - requester: createNodeHttpRequester(), + requester: ( + (HTTPRequester as any) /* v4*/.createNodeHttpRequester || + (HTTPRequester as any) /* v5*/.createHttpRequester + )(), logger: createNullLogger(), responsesCache: createNullCache(), requestsCache: createNullCache(), diff --git a/tests/mocks/createSearchClient.ts b/tests/mocks/createSearchClient.ts index 2e3569377f..6c3dae245e 100644 --- a/tests/mocks/createSearchClient.ts +++ b/tests/mocks/createSearchClient.ts @@ -20,6 +20,7 @@ export const createSearchClient = ( ) ) ), + // @ts-ignore v5 does not have this method, but it's easier to have it here. In a future version we can remove this method and its usages to search({ type: 'facet }) searchForFacetValues: jest.fn(() => Promise.resolve([createSFFVResponse()])), // @ts-ignore this allows us to test insights initialization without warning applicationID: 'appId', diff --git a/yarn.lock b/yarn.lock index baa171e330..58a785cb02 100644 --- a/yarn.lock +++ b/yarn.lock @@ -51,14 +51,14 @@ dependencies: "@algolia/cache-common" "4.23.2" -"@algolia/client-abtesting@5.0.0-beta.8": - version "5.0.0-beta.8" - resolved "https://registry.yarnpkg.com/@algolia/client-abtesting/-/client-abtesting-5.0.0-beta.8.tgz#07950e042e19abe473b6659660dbbaf3d5ae5750" - integrity sha512-SX9/v/1CinWhn8UyPS4zoiCuqLepAoaPiwiJvMal1q8huQzHPYgaQRGu5SwXf/jzUnXnWLiWakyZZ0WkGHj6yA== +"@algolia/client-abtesting@5.0.0-beta.9": + version "5.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@algolia/client-abtesting/-/client-abtesting-5.0.0-beta.9.tgz#892fe5ed4146d10d0a6bddcb7e1eee78a3355fd5" + integrity sha512-TdAJzrQ4RTiTChae1r8qv+ab3IBfuHDVgpJ9npDhxfWBUG8tkE+JuMdLhAEaDYbr6RGMJ/l+W/GCrqV2QdgqyA== dependencies: - "@algolia/client-common" "5.0.0-beta.9" - "@algolia/requester-browser-xhr" "5.0.0-beta.9" - "@algolia/requester-node-http" "5.0.0-beta.9" + "@algolia/client-common" "5.0.0-beta.10" + "@algolia/requester-browser-xhr" "5.0.0-beta.10" + "@algolia/requester-node-http" "5.0.0-beta.10" "@algolia/client-account@4.23.2": version "4.23.2" @@ -79,14 +79,14 @@ "@algolia/requester-common" "4.23.2" "@algolia/transporter" "4.23.2" -"@algolia/client-analytics@5.0.0-beta.8": - version "5.0.0-beta.8" - resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-5.0.0-beta.8.tgz#86d110bed99ca28359bd4e70eaeff568cb6462bb" - integrity sha512-SzMg3FeF7do/+plUawHRw2Lr3/KebKF8rCkswdR907kUa/aMVCFzsginL3xc/k8bIxx6wU8fk5iKLeK1+Ykxnw== +"@algolia/client-analytics@5.0.0-beta.9": + version "5.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-5.0.0-beta.9.tgz#d5e1d3247c1b531fc8c5e894a55d5fcdb441948c" + integrity sha512-/KHnIi+OGLX5pfG3Xow2fJYWg9Xd6GKHeY4+9Qgb/3EH3JOeVWtANCraNdsXAixjAfp69tXm+52ZK6Znhpy/tA== dependencies: - "@algolia/client-common" "5.0.0-beta.9" - "@algolia/requester-browser-xhr" "5.0.0-beta.9" - "@algolia/requester-node-http" "5.0.0-beta.9" + "@algolia/client-common" "5.0.0-beta.10" + "@algolia/requester-browser-xhr" "5.0.0-beta.10" + "@algolia/requester-node-http" "5.0.0-beta.10" "@algolia/client-common@4.23.2": version "4.23.2" @@ -96,10 +96,10 @@ "@algolia/requester-common" "4.23.2" "@algolia/transporter" "4.23.2" -"@algolia/client-common@5.0.0-beta.9": - version "5.0.0-beta.9" - resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-5.0.0-beta.9.tgz#f659c0fca45663a09f7bcf5eb36318ef5ab39b40" - integrity sha512-TWf6l4/pWMk8CgV+8A4zTe49XaygaCZ6ir8bwf4WnpDgAxx8Y5X/I6e7vPzl7sljQEEB9q1+qlkss1nxNeRJPw== +"@algolia/client-common@5.0.0-beta.10": + version "5.0.0-beta.10" + resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-5.0.0-beta.10.tgz#68db8891e3c06740465fe72509b6a4f4253d95fa" + integrity sha512-0Ke2/kuhc5WOctotTJ/VRlfNhMy0keKHEHg7JJ3IR8lXO8WFh7O45Eexxa4hOHZRPUeblPaOCT3AmcHW71XCBA== "@algolia/client-personalization@4.23.2": version "4.23.2" @@ -110,14 +110,14 @@ "@algolia/requester-common" "4.23.2" "@algolia/transporter" "4.23.2" -"@algolia/client-personalization@5.0.0-beta.8": - version "5.0.0-beta.8" - resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-5.0.0-beta.8.tgz#18b624c9e268da3c36c5416e593e778cdaca338c" - integrity sha512-8mGxWE3TA3+2ekc+rM38JAwFfpwPyWyPxjjOe33afiFkmDliLrsGDAyoCasu7w34JhpuLeR1wfgo58g9s9+OLw== +"@algolia/client-personalization@5.0.0-beta.9": + version "5.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-5.0.0-beta.9.tgz#3675dc26430f056bb306bbac84f2befee16d82ad" + integrity sha512-xCOWOuQno2c+7A78iZ5MukvUumRblxEW9cPkpMwDd+ZNNbou8rPRTONZnakyzq1j3Jki4ioU0LKzUNuDEDo7yw== dependencies: - "@algolia/client-common" "5.0.0-beta.9" - "@algolia/requester-browser-xhr" "5.0.0-beta.9" - "@algolia/requester-node-http" "5.0.0-beta.9" + "@algolia/client-common" "5.0.0-beta.10" + "@algolia/requester-browser-xhr" "5.0.0-beta.10" + "@algolia/requester-node-http" "5.0.0-beta.10" "@algolia/client-search@4.23.2": version "4.23.2" @@ -128,14 +128,14 @@ "@algolia/requester-common" "4.23.2" "@algolia/transporter" "4.23.2" -"@algolia/client-search@5.0.0-beta.8": - version "5.0.0-beta.8" - resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-5.0.0-beta.8.tgz#5abeb90de119ee868aa6a2d898c9d98cf8292258" - integrity sha512-Ub7CEFLDvCF13tq6imE7sEKnxmo177k4euXjaKGUMlznUf9qLWT5g6HuvBH4Nrxwaotima3cRnIw3zkq4JZORw== +"@algolia/client-search@5.0.0-beta.9": + version "5.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-5.0.0-beta.9.tgz#3f1e3cf1d5f4a0d2f2895f9498c8a0a08b4117f4" + integrity sha512-KJx+BA6QPCUJkId/OQWn+zAlGNzAPadGyFe49kp+o/jmPbaogsBVNA0Txwevkuf3F376wPpoyPbeSnl9/lQtAw== dependencies: - "@algolia/client-common" "5.0.0-beta.9" - "@algolia/requester-browser-xhr" "5.0.0-beta.9" - "@algolia/requester-node-http" "5.0.0-beta.9" + "@algolia/client-common" "5.0.0-beta.10" + "@algolia/requester-browser-xhr" "5.0.0-beta.10" + "@algolia/requester-node-http" "5.0.0-beta.10" "@algolia/events@^4.0.1": version "4.0.1" @@ -171,14 +171,14 @@ "@algolia/requester-node-http" "4.23.2" "@algolia/transporter" "4.23.2" -"@algolia/recommend@5.0.0-beta.8": - version "5.0.0-beta.8" - resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-5.0.0-beta.8.tgz#eff81537479a3390a33ddbffcbf82ae194160019" - integrity sha512-B7tuqYF2YlPmRH5jfDbbC3V1sq8X3a7oadwzAOPGGC1qwi2tO8BoBLM2iIwJRAAesw4NRVeBVDDmdsdiStHeEQ== +"@algolia/recommend@5.0.0-beta.9": + version "5.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-5.0.0-beta.9.tgz#2114058828156b4da4222177ed9ce071b3e92908" + integrity sha512-NTgwfgrPnWz14o7PWqKu8QN60X6RGSS9OtTKg/VuQ306eaKZV85wye5GeSqHRfo+lJJ+T0OVlO/fiL5fDptPrw== dependencies: - "@algolia/client-common" "5.0.0-beta.9" - "@algolia/requester-browser-xhr" "5.0.0-beta.9" - "@algolia/requester-node-http" "5.0.0-beta.9" + "@algolia/client-common" "5.0.0-beta.10" + "@algolia/requester-browser-xhr" "5.0.0-beta.10" + "@algolia/requester-node-http" "5.0.0-beta.10" "@algolia/requester-browser-xhr@4.23.2": version "4.23.2" @@ -187,12 +187,12 @@ dependencies: "@algolia/requester-common" "4.23.2" -"@algolia/requester-browser-xhr@5.0.0-beta.9": - version "5.0.0-beta.9" - resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.0.0-beta.9.tgz#7b43b57cfabe9328e54fb4a96dd10026d27329f1" - integrity sha512-zw/ZmZv/CLjLqBUfukk5kR8N/xF/TbUt6xLdXF1LkaEJDj7BWU1RqMMDeSU5SEcehPMqNumfzFjpaz8D0rZ/jw== +"@algolia/requester-browser-xhr@5.0.0-beta.10": + version "5.0.0-beta.10" + resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.0.0-beta.10.tgz#307809046e443cc1a23a795a9208fe7a745b902a" + integrity sha512-+XfVx89sWbm9UuRFX/SDwWHLAFfpLkTXBjw4oRQFTaSZap0DtruyxXSZXeACA63zqM7/phP2h7y1e40M8ppQXA== dependencies: - "@algolia/client-common" "5.0.0-beta.9" + "@algolia/client-common" "5.0.0-beta.10" "@algolia/requester-common@4.23.2": version "4.23.2" @@ -206,12 +206,12 @@ dependencies: "@algolia/requester-common" "4.23.2" -"@algolia/requester-node-http@5.0.0-beta.9": - version "5.0.0-beta.9" - resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-5.0.0-beta.9.tgz#afc04a658c1b624e03e378ea076020a51e737637" - integrity sha512-/32llTTdZ0zMNwn8I8FA12Pw4wZW93AvoHU/8Si2UR8S+FyL8dAkwgmQAvRZinNXD/Bo45Mpjwgydhx9UNZNBA== +"@algolia/requester-node-http@5.0.0-beta.10": + version "5.0.0-beta.10" + resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-5.0.0-beta.10.tgz#5ff02223e55df3c67c142b01918e7289d21ba5e7" + integrity sha512-pnrLHWn+5yIzz8waaBlv1cuBRMh1g1W2TYVDKvetQARkYNri/JbPttOxyKQqlhC+5YEQ1R/T3qEljTLf/gfQdA== dependencies: - "@algolia/client-common" "5.0.0-beta.9" + "@algolia/client-common" "5.0.0-beta.10" "@algolia/transporter@4.23.2": version "4.23.2" @@ -8083,21 +8083,8 @@ algoliasearch-helper@3.14.0: semver "^5.1.0" tunnel-agent "^0.6.0" -"algoliasearch-v5@npm:algoliasearch@5.0.0-beta.8": - version "5.0.0-beta.8" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-5.0.0-beta.8.tgz#df9ae7351f4d16ef20f04c7ed90203bfb8bdc9df" - integrity sha512-HeHubssxYRD9OEBySLXM8DdsrDthdyVSogncyQkxO3U+EYfg94Fxe7Kn9ooDm4sX88HS+lOaIV3I+JSwpvoy6A== - dependencies: - "@algolia/client-abtesting" "5.0.0-beta.8" - "@algolia/client-analytics" "5.0.0-beta.8" - "@algolia/client-common" "5.0.0-beta.9" - "@algolia/client-personalization" "5.0.0-beta.8" - "@algolia/client-search" "5.0.0-beta.8" - "@algolia/recommend" "5.0.0-beta.8" - "@algolia/requester-browser-xhr" "5.0.0-beta.9" - "@algolia/requester-node-http" "5.0.0-beta.9" - -algoliasearch@4, algoliasearch@4.23.2: +"algoliasearch-v4@npm:algoliasearch@4.23.2", algoliasearch@4, algoliasearch@4.23.2: + name algoliasearch-v4 version "4.23.2" resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.23.2.tgz#3b7bc93d98f3965628c73a06cbf9203531324a9d" integrity sha512-8aCl055IsokLuPU8BzLjwzXjb7ty9TPcUFFOk0pYOwsE5DMVhE3kwCMFtsCFKcnoPZK7oObm+H5mbnSO/9ioxQ== @@ -8118,26 +8105,19 @@ algoliasearch@4, algoliasearch@4.23.2: "@algolia/requester-node-http" "4.23.2" "@algolia/transporter" "4.23.2" -algoliasearch@^3.35.1: - version "3.35.1" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.35.1.tgz#297d15f534a3507cab2f5dfb996019cac7568f0c" - integrity sha512-K4yKVhaHkXfJ/xcUnil04xiSrB8B8yHZoFEhWNpXg23eiCnqvTZw1tn/SqvdsANlYHLJlKl0qi3I/Q2Sqo7LwQ== - dependencies: - agentkeepalive "^2.2.0" - debug "^2.6.9" - envify "^4.0.0" - es6-promise "^4.1.0" - events "^1.1.0" - foreach "^2.0.5" - global "^4.3.2" - inherits "^2.0.1" - isarray "^2.0.1" - load-script "^1.0.0" - object-keys "^1.0.11" - querystring-es3 "^0.2.1" - reduce "^1.0.1" - semver "^5.1.0" - tunnel-agent "^0.6.0" +"algoliasearch-v5@npm:algoliasearch@5.0.0-beta.9", algoliasearch@5.0.0-beta.9, algoliasearch@^3.35.1, "algoliasearch@npm:algoliasearch@5.0.0-beta.9": + version "5.0.0-beta.9" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-5.0.0-beta.9.tgz#4853eef95d13c857dd37baf0fb8593096018a7f4" + integrity sha512-wJgeoNeq34OG9VjXGxQ0Q+DdjLBLUR8nkOHwQt/1+Stoy9PmXo357sINUx6N2e2upIsrFhkHjd0b2GYjUrhliA== + dependencies: + "@algolia/client-abtesting" "5.0.0-beta.9" + "@algolia/client-analytics" "5.0.0-beta.9" + "@algolia/client-common" "5.0.0-beta.10" + "@algolia/client-personalization" "5.0.0-beta.9" + "@algolia/client-search" "5.0.0-beta.9" + "@algolia/recommend" "5.0.0-beta.9" + "@algolia/requester-browser-xhr" "5.0.0-beta.10" + "@algolia/requester-node-http" "5.0.0-beta.10" align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" @@ -30990,16 +30970,16 @@ typedarray@~0.0.5: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.7.tgz#799207136a37f3b3efb8c66c40010d032714dc73" integrity sha512-ueeb9YybpjhivjbHP2LdFDAjbS948fGEPj+ACAMs4xCMmh72OCOMQWBQKlaN4ZNQ04yfLSDLSx1tGRIoWimObQ== -typescript@*, typescript@5.4.2: - version "5.4.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.2.tgz#0ae9cebcfae970718474fe0da2c090cad6577372" - integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ== - -typescript@5.5.2: +typescript@*, typescript@5.5.2: version "5.5.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.2.tgz#c26f023cb0054e657ce04f72583ea2d85f8d0507" integrity sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew== +typescript@5.4.2: + version "5.4.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.2.tgz#0ae9cebcfae970718474fe0da2c090cad6577372" + integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ== + "typescript@^3 || ^4": version "4.9.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78"