From 341d6de2005f2f9d254b8c2373b2a08a10954899 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/package.json | 2 +- examples/js/e-commerce-umd/package.json | 2 +- examples/js/e-commerce/package.json | 2 +- examples/js/getting-started/package.json | 2 +- examples/js/getting-started/products.html | 2 +- .../src/{products.js => products.ts} | 4 + examples/js/media/package.json | 2 +- examples/js/tourism/package.json | 2 +- examples/react/default-theme/package.json | 2 +- examples/react/e-commerce/package.json | 2 +- examples/react/getting-started/package.json | 2 +- examples/react/next-app-router/package.json | 2 +- examples/react/next-routing/package.json | 2 +- examples/react/next/package.json | 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/vue/default-theme/package.json | 2 +- examples/vue/e-commerce/package.json | 2 +- examples/vue/getting-started/package.json | 2 +- examples/vue/media/package.json | 2 +- examples/vue/nuxt/package.json | 2 +- examples/vue/ssr/package.json | 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 | 161 +++++++--------- 102 files changed, 869 insertions(+), 441 deletions(-) rename examples/js/getting-started/src/{products.js => products.ts} (95%) diff --git a/examples/js/calendar-widget/package.json b/examples/js/calendar-widget/package.json index 0083930c94..4abb5423bf 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": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "instantsearch.js": "4.73.2" }, "devDependencies": { diff --git a/examples/js/e-commerce-umd/package.json b/examples/js/e-commerce-umd/package.json index b372c9a658..506cb79d6b 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": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "instantsearch.js": "4.73.2" }, "devDependencies": { diff --git a/examples/js/e-commerce/package.json b/examples/js/e-commerce/package.json index 5190deaed4..6d9a88ff4a 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": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "instantsearch.js": "4.73.2" }, "devDependencies": { diff --git a/examples/js/getting-started/package.json b/examples/js/getting-started/package.json index f28a88647f..be6c3f95ba 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": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "instantsearch.js": "4.73.2" }, "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/products.js b/examples/js/getting-started/src/products.ts similarity index 95% rename from examples/js/getting-started/src/products.js rename to examples/js/getting-started/src/products.ts index ae93a75e9d..0302bfa70b 100644 --- a/examples/js/getting-started/src/products.js +++ b/examples/js/getting-started/src/products.ts @@ -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 e097efa869..5450ded8db 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": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "date-fns": "2.25.0", "instantsearch.js": "4.73.2" }, diff --git a/examples/js/tourism/package.json b/examples/js/tourism/package.json index d66b6495bd..2cd84dcde5 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": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "instantsearch.js": "4.73.2" }, "devDependencies": { diff --git a/examples/react/default-theme/package.json b/examples/react/default-theme/package.json index 5a8f5a11f1..de57942209 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": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "instantsearch.js": "4.73.2", "react": "18.2.0", "react-dom": "18.2.0", diff --git a/examples/react/e-commerce/package.json b/examples/react/e-commerce/package.json index 68e432e8d0..4b2d8b52ee 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": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "instantsearch.js": "4.73.2", "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 7c0b4c3017..bb9543496c 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": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "instantsearch.js": "4.73.2", "react": "18.2.0", "react-dom": "18.2.0", diff --git a/examples/react/next-app-router/package.json b/examples/react/next-app-router/package.json index e9bd5dc1b8..20ec101c36 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": "5.0.0-beta.8", + "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 3c7a1f11c9..4d4dc2ce7f 100644 --- a/examples/react/next-routing/package.json +++ b/examples/react/next-routing/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "algoliasearch": "5.0.0-beta.8", + "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/package.json b/examples/react/next/package.json index 7978c97bac..e94d69cf5c 100644 --- a/examples/react/next/package.json +++ b/examples/react/next/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "algoliasearch": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "instantsearch.css": "8.3.0", "next": "13.5.1", "react": "18.2.0", diff --git a/examples/react/react-native/package.json b/examples/react/react-native/package.json index 66707fde44..b90dc02502 100644 --- a/examples/react/react-native/package.json +++ b/examples/react/react-native/package.json @@ -11,7 +11,7 @@ "eject": "expo eject" }, "dependencies": { - "algoliasearch": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "expo": "~44.0.0", "expo-status-bar": "~1.2.0", "instantsearch.js": "4.73.2", 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 f3419cc56b..5036f4a1e8 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": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "express": "4.17.1", "react": "18.2.0", "react-dom": "18.2.0", diff --git a/examples/vue/default-theme/package.json b/examples/vue/default-theme/package.json index 0d32634525..808b21dc0f 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": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "core-js": "2", "instantsearch.js": "4.73.2", "vue": "2.7.14", diff --git a/examples/vue/e-commerce/package.json b/examples/vue/e-commerce/package.json index a3932c93fb..ccc5addc83 100644 --- a/examples/vue/e-commerce/package.json +++ b/examples/vue/e-commerce/package.json @@ -8,7 +8,7 @@ "website:examples": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build --dest ../../../website/examples/vue/e-commerce" }, "dependencies": { - "algoliasearch": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "core-js": "2", "instantsearch.js": "4.73.2", "vue": "2.7.14", diff --git a/examples/vue/getting-started/package.json b/examples/vue/getting-started/package.json index 15866afcfd..17cc68943d 100644 --- a/examples/vue/getting-started/package.json +++ b/examples/vue/getting-started/package.json @@ -7,7 +7,7 @@ "build": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build" }, "dependencies": { - "algoliasearch": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "core-js": "2", "instantsearch.js": "4.73.2", "vue": "2.7.14", diff --git a/examples/vue/media/package.json b/examples/vue/media/package.json index 5ef2a4b792..71bbfb3b73 100644 --- a/examples/vue/media/package.json +++ b/examples/vue/media/package.json @@ -8,7 +8,7 @@ "website:examples": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build --dest ../../../website/examples/vue/media" }, "dependencies": { - "algoliasearch": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "core-js": "2", "instantsearch.js": "4.73.2", "vue": "2.7.14", diff --git a/examples/vue/nuxt/package.json b/examples/vue/nuxt/package.json index afb7a4dc2b..eecc2f2085 100644 --- a/examples/vue/nuxt/package.json +++ b/examples/vue/nuxt/package.json @@ -11,7 +11,7 @@ "generate": "nuxt generate" }, "dependencies": { - "algoliasearch": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "cross-env": "^5.2.0", "css-loader": "^4.3.0", "nuxt": "^2.4.5", diff --git a/examples/vue/ssr/package.json b/examples/vue/ssr/package.json index ea08194019..04b2e27a05 100644 --- a/examples/vue/ssr/package.json +++ b/examples/vue/ssr/package.json @@ -8,7 +8,7 @@ "start": "NODE_ENV=production NODE_OPTIONS=--openssl-legacy-provider vue-cli-service ssr:serve --mode production" }, "dependencies": { - "algoliasearch": "5.0.0-beta.8", + "algoliasearch": "5.0.0-beta.9", "core-js": "2", "instantsearch.css": "8.3.0", "qs": "6.9.7", diff --git a/package.json b/package.json index 402def5fc6..07efb56d3e 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,8 @@ "devDependencies": { "@algolia/cache-common": "4.23.2", "@algolia/cache-in-memory": "4.23.2", - "@algolia/client-search": "4.23.2", + "@algolia/client-search": "5.0.0-beta.9", + "@algolia/client-common": "5.0.0-beta.10", "@algolia/logger-common": "4.23.2", "@algolia/requester-node-http": "4.23.2", "@algolia/transporter": "4.23.2", @@ -87,9 +88,10 @@ "@wdio/selenium-standalone-service": "5.16.5", "@wdio/spec-reporter": "5.16.5", "@wdio/static-server-service": "5.16.5", - "algoliasearch": "4.23.2", "algoliasearch-v3": "npm:algoliasearch@3.35.0", - "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.8", + "algoliasearch-v4": "npm:algoliasearch@4.23.2", + "algoliasearch-v5": "npm:algoliasearch@5.0.0-beta.9", + "algoliasearch": "5.0.0-beta.9", "babel-eslint": "10.1.0", "babel-jest": "27.4.6", "babel-plugin-inline-replace-variables": "1.3.1", @@ -145,6 +147,7 @@ "typescript": "5.5.2" }, "resolutions": { + "places.js/algoliasearch": "5.0.0-beta.9", "brotli-size": "4.0.0", "webpack": "4.47.0", "babel-loader": "8.2.2" diff --git a/packages/algoliasearch-helper/index.d.ts b/packages/algoliasearch-helper/index.d.ts index 50a2b347d1..8765cf266f 100644 --- a/packages/algoliasearch-helper/index.d.ts +++ b/packages/algoliasearch-helper/index.d.ts @@ -1,23 +1,23 @@ import EventEmitter from '@algolia/events'; +// eslint-disable-next-line @typescript-eslint/consistent-type-imports import type { FindAnswersResponse, + FrequentlyBoughtTogetherQuery, HighlightResult, + LookingSimilarQuery, RankingInfo, + RecommendResponse, + RelatedProductsQuery, SearchClient, SearchOptions, SearchResponse, SnippetResult, + SupportedLanguage, + TrendingFacetsQuery, + TrendingItemsQuery, + PlainRecommendParameters as ClientPlainRecommendParameters, } from './types/algoliasearch'; -// @ts-ignore -import type { - FrequentlyBoughtTogetherQuery as RecommendFrequentlyBoughtTogetherQuery, - LookingSimilarQuery as RecommendLookingSimilarQuery, - RelatedProductsQuery as RecommendRelatedProductsQuery, - TrendingFacetsQuery as RecommendTrendingFacetsQuery, - TrendingItemsQuery as RecommendTrendingItemsQuery, - RecommendQueriesResponse, -} from '@algolia/recommend'; /** * The algoliasearchHelper module is the function that will let its @@ -539,7 +539,7 @@ declare namespace algoliasearchHelper { // types missing in @types/algoliasearch, so duplicated from v4 ruleContexts?: string[]; optionalFilters?: Array; - queryLanguages?: string[]; + queryLanguages?: SupportedLanguage[]; /** * The relevancy threshold to apply to search in a virtual index [0-100]. A bigger @@ -1021,7 +1021,7 @@ declare namespace algoliasearchHelper { * a list of language ISO codes (as a comma-separated string) for which stop words should be enable * https://www.algolia.com/doc/api-reference/api-parameters/removeStopWords/ */ - removeStopWords?: boolean | string[]; + removeStopWords?: boolean | SupportedLanguage[]; /** * List of attributes on which you want to disable the computation of exact criteria * default: [] @@ -1555,23 +1555,7 @@ declare namespace algoliasearchHelper { } } - // We remove `indexName` from the Recommend query types as the helper - // will fill in this value before sending the queries - type FrequentlyBoughtTogetherQuery = Omit< - RecommendFrequentlyBoughtTogetherQuery, - 'indexName' - >; - type LookingSimilarQuery = Omit; - type RelatedProductsQuery = Omit; - type TrendingFacetsQuery = Omit; - type TrendingItemsQuery = Omit; - - export type PlainRecommendParameters = - | FrequentlyBoughtTogetherQuery - | LookingSimilarQuery - | RelatedProductsQuery - | TrendingFacetsQuery - | TrendingItemsQuery; + export type PlainRecommendParameters = ClientPlainRecommendParameters; export type RecommendParametersWithId< T extends PlainRecommendParameters = PlainRecommendParameters @@ -1605,11 +1589,7 @@ declare namespace algoliasearchHelper { ): RecommendParameters; } - type RecommendResponse = - RecommendQueriesResponse['results']; - - type RecommendResultItem = RecommendResponse[0]; - type RecommendResultMap = { [index: number]: RecommendResultItem }; + type RecommendResultMap = { [index: number]: RecommendResponse }; export class RecommendResults { constructor(state: RecommendParameters, results: RecommendResultMap); @@ -1617,7 +1597,7 @@ declare namespace algoliasearchHelper { _state: RecommendParameters; _rawResults: RecommendResultMap; - [index: number]: RecommendResultItem; + [index: number]: RecommendResponse; } } diff --git a/packages/algoliasearch-helper/test/datasets/SearchResults/getFacetValues.dataset.js b/packages/algoliasearch-helper/test/datasets/SearchResults/getFacetValues.dataset.js index 7a36208e5e..a132657175 100644 --- a/packages/algoliasearch-helper/test/datasets/SearchResults/getFacetValues.dataset.js +++ b/packages/algoliasearch-helper/test/datasets/SearchResults/getFacetValues.dataset.js @@ -15,6 +15,7 @@ if (require.main === module) { path.join(__dirname.replace('datasets', 'spec'), 'getFacetValues') ); var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var client = algoliasearch('latency', '6be0576ff61c053d5f9a3225e2a90f76'); var helper = new HelperSaver(client, 'instant_search', { diff --git a/packages/algoliasearch-helper/test/datasets/SearchResults/getRefinements.dataset.js b/packages/algoliasearch-helper/test/datasets/SearchResults/getRefinements.dataset.js index 08b3f51673..1b9f111bb5 100644 --- a/packages/algoliasearch-helper/test/datasets/SearchResults/getRefinements.dataset.js +++ b/packages/algoliasearch-helper/test/datasets/SearchResults/getRefinements.dataset.js @@ -15,6 +15,7 @@ if (require.main === module) { path.join(__dirname.replace('datasets', 'spec'), 'getRefinements') ); var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var client = algoliasearch('latency', '6be0576ff61c053d5f9a3225e2a90f76'); var helper = new HelperSaver(client, 'instant_search', { diff --git a/packages/algoliasearch-helper/test/integration-utils.js b/packages/algoliasearch-helper/test/integration-utils.js index e6dd4b7ce4..86d3fc2dda 100644 --- a/packages/algoliasearch-helper/test/integration-utils.js +++ b/packages/algoliasearch-helper/test/integration-utils.js @@ -1,6 +1,7 @@ 'use strict'; var algoliasearch = require('algoliasearch'); +algoliasearch = algoliasearch.algoliasearch || algoliasearch; function setup(indexName, fn) { var appID = process.env.INTEGRATION_TEST_APPID; diff --git a/packages/algoliasearch-helper/test/run.js b/packages/algoliasearch-helper/test/run.js index 2e93dc9014..0f958d5784 100644 --- a/packages/algoliasearch-helper/test/run.js +++ b/packages/algoliasearch-helper/test/run.js @@ -3,6 +3,7 @@ var path = require('path'); var algoliasearch = require('algoliasearch'); +algoliasearch = algoliasearch.algoliasearch || algoliasearch; var jest = require('jest'); var staticJestConfig = require('../jest.config'); diff --git a/packages/algoliasearch-helper/test/spec/algoliasearch.helper/client.js b/packages/algoliasearch-helper/test/spec/algoliasearch.helper/client.js index b4e0fcccb3..c4b79014e7 100644 --- a/packages/algoliasearch-helper/test/spec/algoliasearch.helper/client.js +++ b/packages/algoliasearch-helper/test/spec/algoliasearch.helper/client.js @@ -1,6 +1,7 @@ 'use strict'; var algoliasearch = require('algoliasearch'); +algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliaSearchHelper = require('../../../'); var version = require('../../../src/version'); diff --git a/packages/algoliasearch-helper/test/spec/algoliasearch.helper/numericFilters.js b/packages/algoliasearch-helper/test/spec/algoliasearch.helper/numericFilters.js index e3fa61e0b0..d91785cef8 100644 --- a/packages/algoliasearch-helper/test/spec/algoliasearch.helper/numericFilters.js +++ b/packages/algoliasearch-helper/test/spec/algoliasearch.helper/numericFilters.js @@ -1,13 +1,14 @@ 'use strict'; -var algoliaSearch = require('algoliasearch'); +var algoliasearch = require('algoliasearch'); +algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../index'); var fakeClient = {}; test('Numeric filters: numeric filters from constructor', function (done) { - var client = algoliaSearch('dsf', 'dsfdf'); + var client = algoliasearch('dsf', 'dsfdf'); client.search = function (queries) { var ps = queries[0].params; @@ -42,7 +43,7 @@ test('Numeric filters: numeric filters from constructor', function (done) { }); test('Numeric filters: numeric filters from setters', function (done) { - var client = algoliaSearch('dsf', 'dsfdf'); + var client = algoliasearch('dsf', 'dsfdf'); client.search = function (queries) { var ps = queries[0].params; diff --git a/packages/algoliasearch-helper/test/spec/algoliasearch.helper/pendingSearch.js b/packages/algoliasearch-helper/test/spec/algoliasearch.helper/pendingSearch.js index b6fdab9bc6..187fa91d0c 100644 --- a/packages/algoliasearch-helper/test/spec/algoliasearch.helper/pendingSearch.js +++ b/packages/algoliasearch-helper/test/spec/algoliasearch.helper/pendingSearch.js @@ -1,12 +1,13 @@ 'use strict'; -var algoliaSearch = require('algoliasearch'); +var algoliasearch = require('algoliasearch'); +algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../index'); test('When searchOnce with callback, hasPendingRequests is true', function (done) { var testData = require('../../datasets/SearchParameters/search.dataset')(); - var client = algoliaSearch('dsf', 'dsfdf'); + var client = algoliasearch('dsf', 'dsfdf'); var triggerCb; client.search = function () { @@ -39,7 +40,7 @@ test('When searchOnce with callback, hasPendingRequests is true', function (done test('When searchOnce with promises, hasPendingRequests is true', function (done) { var testData = require('../../datasets/SearchParameters/search.dataset')(); - var client = algoliaSearch('dsf', 'dsfdf'); + var client = algoliasearch('dsf', 'dsfdf'); var triggerCb; client.search = function () { @@ -71,7 +72,7 @@ test('When searchOnce with promises, hasPendingRequests is true', function (done }); test('When searchForFacetValues, hasPendingRequests is true', function (done) { - var client = algoliaSearch('dsf', 'dsfdf'); + var client = algoliasearch('dsf', 'dsfdf'); var triggerCb; client.searchForFacetValues = function () { @@ -110,7 +111,7 @@ test('When searchForFacetValues, hasPendingRequests is true', function (done) { test('When helper.search(), hasPendingRequests is true', function (done) { var testData = require('../../datasets/SearchParameters/search.dataset')(); - var client = algoliaSearch('dsf', 'dsfdf'); + var client = algoliasearch('dsf', 'dsfdf'); var triggerCb; client.search = function () { @@ -145,7 +146,7 @@ test('When helper.search(), hasPendingRequests is true', function (done) { test('When helper.search() and one request is discarded, hasPendingRequests is true unless all come back', function (done) { var testData = require('../../datasets/SearchParameters/search.dataset')(); - var client = algoliaSearch('dsf', 'dsfdf'); + var client = algoliasearch('dsf', 'dsfdf'); var triggerCbs = []; client.search = function () { diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/attributes-order.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/attributes-order.js index 9803d48ccc..37f0c85a4d 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/attributes-order.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/attributes-order.js @@ -4,6 +4,7 @@ test('hierarchical facets: attributes order', function (done) { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/breadcrumb.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/breadcrumb.js index 5fd0ad29ba..3c27339845 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/breadcrumb.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/breadcrumb.js @@ -2,6 +2,7 @@ test('hierarchical facets: using getHierarchicalFacetBreadcrumb()', function () { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); @@ -35,6 +36,7 @@ test('hierarchical facets: using getHierarchicalFacetBreadcrumb()', function () test('hierarchical facets: using getHierarchicalFacetBreadcrumb before the first refinement', function () { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); @@ -62,6 +64,7 @@ test('hierarchical facets: using getHierarchicalFacetBreadcrumb before the first test('hierarchical facets: using getHierarchicalFacetBreadcrumb on an undefined facet', function () { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/custom-prefix-path.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/custom-prefix-path.js index 29a6593e88..5da483e52a 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/custom-prefix-path.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/custom-prefix-path.js @@ -2,6 +2,7 @@ test('hierarchical facets: custom prefix path', function (done) { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/custom-separator.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/custom-separator.js index d28b9c0aa1..d1328e0a6c 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/custom-separator.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/custom-separator.js @@ -2,6 +2,7 @@ test('hierarchical facets: custom separator', function (done) { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/do-not-show-parent-level.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/do-not-show-parent-level.js index 75af4c3a04..dcde21476e 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/do-not-show-parent-level.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/do-not-show-parent-level.js @@ -2,6 +2,7 @@ test('hierarchical facets: do not show parent level', function (done) { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/facet-value-length.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/facet-value-length.js index 3c34a7b5ae..7799b9ac7e 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/facet-value-length.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/facet-value-length.js @@ -2,6 +2,7 @@ test('hierarchical facets: facet value called length', function (done) { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); var appId = 'hierarchical-simple-appId'; diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/no-refinement.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/no-refinement.js index 58525e94dd..0ff631ed54 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/no-refinement.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/no-refinement.js @@ -2,6 +2,7 @@ test('hierarchical facets: no refinement', function (done) { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/no-trim.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/no-trim.js index 45dc3c6352..deeda58932 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/no-trim.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/no-trim.js @@ -2,6 +2,7 @@ test('hierarchical facets: do not trim facetFilters values', function (done) { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/objects-with-multiple-categories.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/objects-with-multiple-categories.js index fca661819b..e65f107756 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/objects-with-multiple-categories.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/objects-with-multiple-categories.js @@ -2,6 +2,7 @@ test('hierarchical facets: objects with multiple categories', function (done) { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/one-level.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/one-level.js index 5a5b9d3d40..38557be453 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/one-level.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/one-level.js @@ -2,6 +2,7 @@ test('hierarchical facets: only one level deep', function (done) { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/pagination.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/pagination.js index 47971bbdc4..724cecfbd2 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/pagination.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/pagination.js @@ -2,6 +2,7 @@ test('hierarchical facets: pagination', function (done) { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/parent-toggleRefine.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/parent-toggleRefine.js index d2a2e134f1..ccdfc1c890 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/parent-toggleRefine.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/parent-toggleRefine.js @@ -2,6 +2,7 @@ test('hierarchical facets: toggleRefine behavior', function () { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); @@ -52,6 +53,7 @@ test('hierarchical facets: toggleRefine behavior', function () { test('hierarchical facets: toggleRefine behavior when root level', function () { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); @@ -93,6 +95,7 @@ test('hierarchical facets: toggleRefine behavior when root level', function () { test('hierarchical facets: toggleRefine behavior when different root level', function () { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/refined-no-result.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/refined-no-result.js index 208de1c687..9147ee1d47 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/refined-no-result.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/refined-no-result.js @@ -2,6 +2,7 @@ test('hierarchical facets: no results', function (done) { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/show-parent-level.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/show-parent-level.js index 5c06b2788f..6723174451 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/show-parent-level.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/show-parent-level.js @@ -2,6 +2,7 @@ test('hierarchical facets: show parent level', function (done) { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/simple-usage.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/simple-usage.js index 0a23a35a4e..5261f74791 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/simple-usage.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/simple-usage.js @@ -2,6 +2,7 @@ describe('hierarchical facets: simple usage', function () { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); var appId = 'hierarchical-toggleRefine-appId'; var apiKey = 'hierarchical-toggleRefine-apiKey'; diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/sort-by.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/sort-by.js index 4ac4cbd663..b04462f26a 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/sort-by.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/sort-by.js @@ -2,6 +2,7 @@ test('hierarchical facets: using sortBy', function (done) { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/two-facets.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/two-facets.js index 937bc68098..b1a9bdf681 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/two-facets.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/two-facets.js @@ -2,6 +2,7 @@ test('hierarchical facets: two hierarchical facets', function (done) { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/unknown-facet.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/unknown-facet.js index 8c0c0edf61..87d82d86c5 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/unknown-facet.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/unknown-facet.js @@ -1,5 +1,6 @@ 'use strict'; var algoliasearch = require('algoliasearch'); +algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/with-a-disjunctive-facet.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/with-a-disjunctive-facet.js index 2d97bc3731..d024beed04 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/with-a-disjunctive-facet.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/with-a-disjunctive-facet.js @@ -2,6 +2,7 @@ test('hierarchical facets: combined with a disjunctive facet', function () { var algoliasearch = require('algoliasearch'); + algoliasearch = algoliasearch.algoliasearch || algoliasearch; var algoliasearchHelper = require('../../../'); diff --git a/packages/algoliasearch-helper/test/types.ts b/packages/algoliasearch-helper/test/types.ts index 58ad1379a8..682cdf77af 100644 --- a/packages/algoliasearch-helper/test/types.ts +++ b/packages/algoliasearch-helper/test/types.ts @@ -1,13 +1,11 @@ -import algoliasearch from 'algoliasearch'; - import algoliasearchHelper, { SearchParameters, SearchResults } from '..'; import type { AlgoliaSearchHelper } from '..'; +import type { SearchClient } from '../types/algoliasearch'; -const helper: AlgoliaSearchHelper = algoliasearchHelper( - algoliasearch('', ''), - '' -); +const client: SearchClient = {} as any; + +const helper: AlgoliaSearchHelper = algoliasearchHelper(client, ''); helper.derive( () => diff --git a/packages/algoliasearch-helper/types/algoliasearch.d.ts b/packages/algoliasearch-helper/types/algoliasearch.d.ts index 1cc93d2dd1..5f404f1c7b 100644 --- a/packages/algoliasearch-helper/types/algoliasearch.d.ts +++ b/packages/algoliasearch-helper/types/algoliasearch.d.ts @@ -5,6 +5,8 @@ // @ts-ignore import type * as ClientSearch from '@algolia/client-search'; // @ts-ignore +import type * as RecommendClient from '@algolia/recommend'; +// @ts-ignore import type * as AlgoliaSearch from 'algoliasearch'; // @ts-ignore import type algoliasearch from 'algoliasearch/lite'; @@ -16,6 +18,12 @@ import type * as AlgoliaSearchLite from 'algoliasearch/lite'; type AnyToUnknown = (0 extends 1 & T ? true : false) extends true ? unknown : T; +type IsNull = [T] extends [null] ? true : false; +type IsUnknown = unknown extends T // `T` can be `unknown` or `any` + ? IsNull extends false // `any` can be `null`, but `unknown` can't be + ? true + : false + : false; type SearchClientV4Shape = { transporter: unknown; @@ -28,24 +36,32 @@ type SearchClientShape = { // @ts-ignore type ClientV3_4 = ReturnType; -type ClientLiteV5 = AnyToUnknown extends unknown +type ClientLiteV5 = IsUnknown< + AnyToUnknown +> extends true ? unknown - : AnyToUnknown< + : typeof AlgoliaSearchLite extends { liteClient: unknown } + ? AnyToUnknown< // @ts-ignore ReturnType - >; -type ClientFullV5 = AnyToUnknown extends unknown + > + : unknown; +type ClientFullV5 = IsUnknown> extends true ? unknown - : AnyToUnknown< + : typeof AlgoliaSearch extends { algoliasearch: unknown } + ? AnyToUnknown< // @ts-ignore ReturnType - >; -type ClientSearchV5 = AnyToUnknown extends unknown + > + : unknown; +type ClientSearchV5 = IsUnknown> extends true ? unknown - : AnyToUnknown< + : typeof ClientSearch extends { searchClient: unknown } + ? AnyToUnknown< // @ts-ignore ReturnType - >; + > + : unknown; type ClientV5 = ClientLiteV5 extends SearchClientShape ? ClientLiteV5 : ClientSearchV5 extends SearchClientShape @@ -67,6 +83,12 @@ type PickForClient< ? T['v4'] : T['v3']; +type ClientVersion = PickForClient<{ + v3: '3'; + v4: '4'; + v5: '5'; +}>; + type DefaultSearchClient = PickForClient<{ v3: ClientV3_4; v4: ClientV3_4; @@ -132,7 +154,7 @@ export type SearchResponse = PickForClient<{ // @ts-ignore v4: ClientSearch.SearchResponse; // @ts-ignore - v5: AlgoliaSearch.SearchResponse; // TODO: should be generic https://github.com/algolia/api-clients-automation/issues/853 + v5: AlgoliaSearch.SearchResponse; }>; export type SearchResponses = PickForClient<{ @@ -141,9 +163,114 @@ export type SearchResponses = PickForClient<{ // @ts-ignore v4: ClientSearch.MultipleQueriesResponse; // @ts-ignore - v5: AlgoliaSearch.SearchResponses; // TODO: should be generic https://github.com/algolia/api-clients-automation/issues/853 + v5: AlgoliaSearch.SearchResponses; +}>; + +export type RecommendResponse = PickForClient<{ + v3: any; + // @ts-ignore + v4: ClientSearch.SearchResponse; + // @ts-ignore + v5: AlgoliaSearch.RecommendationsResults; }>; +export type RecommendResponses = PickForClient<{ + v3: any; + // @ts-ignore + v4: { results: Array> }; + // @ts-ignore + v5: AlgoliaSearch.GetRecommendationsResponse; +}>; + +// We remove `indexName` from the Recommend query types as the helper +// will fill in this value before sending the queries +type _OptionalKeys = Omit & Partial>; +type _RequiredKeys = Omit & Required>; + +export type FrequentlyBoughtTogetherQuery = PickForClient<{ + v3: any; + // @ts-ignore + v4: Omit; + // @ts-ignore + v5: _OptionalKeys< + // @ts-ignore + Omit, + 'threshold' + >; +}>; +export type LookingSimilarQuery = PickForClient<{ + v3: any; + // @ts-ignore + v4: Omit; + v5: _OptionalKeys< + // @ts-ignore + Omit, + 'threshold' + >; +}>; +export type RelatedProductsQuery = PickForClient<{ + v3: any; + // @ts-ignore + v4: Omit; + v5: _OptionalKeys< + // @ts-ignore + Omit, + 'threshold' + >; +}>; +export type TrendingFacetsQuery = PickForClient<{ + v3: any; + // @ts-ignore + v4: Omit; + v5: _OptionalKeys< + // @ts-ignore + Omit, + 'threshold' + >; +}>; +export type TrendingItemsQuery = PickForClient<{ + v3: any; + // @ts-ignore + v4: Omit; + v5: _OptionalKeys< + // @ts-ignore + Omit, + 'threshold' + >; +}>; + +export type RecommendOptions = + | _RequiredKeys< + FrequentlyBoughtTogetherQuery & { + indexName: string; + model: 'bought-together'; + }, + 'threshold' | 'indexName' | 'model' + > + | _RequiredKeys< + LookingSimilarQuery & { indexName: string; model: 'looking-similar' }, + 'threshold' | 'indexName' | 'model' + > + | _RequiredKeys< + RelatedProductsQuery & { indexName: string; model: 'related-products' }, + 'threshold' | 'indexName' | 'model' + > + | _RequiredKeys< + TrendingFacetsQuery & { indexName: string; model: 'trending-facets' }, + 'threshold' | 'indexName' | 'model' + > + | _RequiredKeys< + TrendingItemsQuery & { indexName: string; model: 'trending-items' }, + 'threshold' | 'indexName' | 'model' + >; + +export type PlainRecommendParameters = + | FrequentlyBoughtTogetherQuery + | LookingSimilarQuery + | RelatedProductsQuery + | TrendingFacetsQuery + | TrendingItemsQuery; + export type SearchForFacetValuesResponse = PickForClient<{ // @ts-ignore v3: AlgoliaSearch.SearchForFacetValues.Response; @@ -159,16 +286,33 @@ export type FindAnswersOptions = PickForClient<{ v4: ClientSearch.FindAnswersOptions; v5: any; // answers only exists in v4 }>; - export type FindAnswersResponse = PickForClient<{ v3: any; // answers only exists in v4 // @ts-ignore v4: ClientSearch.FindAnswersResponse; v5: any; // answers only exists in v4 }>; +export type FindAnswers = PickForClient<{ + v3: any; // answers only exists in v4 + // @ts-ignore + v4: ReturnType['findAnswers']; + v5: any; // answers only exists in v4 +}>; + +export type SupportedLanguage = PickForClient<{ + v3: string; + v4: string; + // @ts-ignore + v5: AlgoliaSearch.SupportedLanguage; +}>; export interface SearchClient { - search: DefaultSearchClient['search']; + search: ( + requests: Array<{ indexName: string; params: SearchOptions }> + ) => Promise>; + getRecommendations?: ( + requests: RecommendOptions[] + ) => Promise>; searchForFacetValues?: DefaultSearchClient extends { searchForFacetValues: unknown; } @@ -178,5 +322,4 @@ export interface SearchClient { ? DefaultSearchClient['initIndex'] : never; addAlgoliaAgent?: DefaultSearchClient['addAlgoliaAgent']; - getRecommendations?: DefaultSearchClient['getRecommendations']; } diff --git a/packages/instantsearch-ui-components/src/types/Recommend.ts b/packages/instantsearch-ui-components/src/types/Recommend.ts index ead3b6c738..a2629435c5 100644 --- a/packages/instantsearch-ui-components/src/types/Recommend.ts +++ b/packages/instantsearch-ui-components/src/types/Recommend.ts @@ -90,8 +90,7 @@ export type RecommendInnerComponentProps = { export type RecordWithObjectID> = TObject & { objectID: string; - __position: number; - __queryID?: string; + // @TODO: once events are implemented, this type needs `__position` and `__queryID` }; export type RecommendItemComponentProps = { diff --git a/packages/instantsearch.js/.storybook/decorators/withHits.ts b/packages/instantsearch.js/.storybook/decorators/withHits.ts index ef3283a6da..45b8dcc206 100644 --- a/packages/instantsearch.js/.storybook/decorators/withHits.ts +++ b/packages/instantsearch.js/.storybook/decorators/withHits.ts @@ -1,8 +1,21 @@ import { action } from '@storybook/addon-actions'; -import algoliasearch from 'algoliasearch/lite'; +import { + // @ts-ignore fails in v3, v4 + liteClient as namedConstructor, + default as defaultConstructor, +} from 'algoliasearch/lite'; import instantsearch from '../../src'; import defaultPlayground from '../playgrounds/default'; -import { InstantSearch, InstantSearchOptions } from '../../src/types'; +import { + InstantSearch, + InstantSearchOptions, + SearchClient, +} from '../../src/types'; + +const algoliasearch = (namedConstructor || defaultConstructor) as unknown as ( + appId: string, + apiKey: string +) => SearchClient; type InstantSearchUMDModule = typeof instantsearch; diff --git a/packages/instantsearch.js/src/connectors/answers/connectAnswers.ts b/packages/instantsearch.js/src/connectors/answers/connectAnswers.ts index d2b1fc4398..47bdadef0b 100644 --- a/packages/instantsearch.js/src/connectors/answers/connectAnswers.ts +++ b/packages/instantsearch.js/src/connectors/answers/connectAnswers.ts @@ -16,7 +16,7 @@ import type { FindAnswersOptions, FindAnswersResponse, WidgetRenderState, - SearchClient, + FindAnswers, } from '../../types'; type IndexWithAnswers = { @@ -140,28 +140,24 @@ const connectAnswers: AnswersConnector = function connectAnswers( let isLoading = false; const debouncedRender = debounce(renderFn, renderDebounceTime); - // this does not directly use DebouncedFunction, since then the generic will disappear - let debouncedRefine: DebouncedFunction< - ReturnType> extends { - findAnswers: infer FindAnswers; - } - ? FindAnswers - : any - >; + let debouncedRefine: DebouncedFunction; return { $$type: 'ais.answers', init(initOptions) { const { state, instantSearchInstance } = initOptions; - const answersIndex = instantSearchInstance.client.initIndex!( + if (typeof instantSearchInstance.client.initIndex !== 'function') { + throw new Error(withUsage('`algoliasearch` <5 required.')); + } + const answersIndex = (instantSearchInstance.client.initIndex as any)( state.index ); if (!hasFindAnswersMethod(answersIndex)) { throw new Error(withUsage('`algoliasearch` >= 4.8.0 required.')); } debouncedRefine = debounce( - answersIndex.findAnswers, + answersIndex.findAnswers as unknown as FindAnswers, searchDebounceTime ); diff --git a/packages/instantsearch.js/src/connectors/autocomplete/__tests__/connectAutocomplete-test.ts b/packages/instantsearch.js/src/connectors/autocomplete/__tests__/connectAutocomplete-test.ts index f45fabdee9..a0287ce795 100644 --- a/packages/instantsearch.js/src/connectors/autocomplete/__tests__/connectAutocomplete-test.ts +++ b/packages/instantsearch.js/src/connectors/autocomplete/__tests__/connectAutocomplete-test.ts @@ -240,6 +240,8 @@ search.addWidgets([ _highlightResult: { foobar: { value: ``, + 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 2c8153b42c..71c34bfcc4 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 e92677305c..8e0009739c 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 4092194030..4165fe411e 100644 --- a/packages/instantsearch.js/src/lib/utils/hydrateSearchClient.ts +++ b/packages/instantsearch.js/src/lib/utils/hydrateSearchClient.ts @@ -93,7 +93,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 6be8fcff88..a8cf693626 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 d59f26ec2c..ae5147ebb5 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,22 +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", algoliasearch@5.0.0-beta.8: - name algoliasearch-v5 - 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== @@ -8119,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: + 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" @@ -30991,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"