From a2e62fc7ca94d5ed5c559a4407349d4d62635e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Thu, 25 Nov 2021 10:54:44 +0100 Subject: [PATCH 1/7] feat(specs): add `settings` spec --- .gitignore | 1 + .prettierignore | 1 + .../client-search/searchApi.ts | 96 +++++- .../git_push.sh | 58 ---- .../model/baseIndexSettings.ts | 50 +++ .../model/baseSearchParams.ts | 134 ++++++++ .../model/indexSettings.ts | 263 +++++++++++++++ .../model/indexSettingsAsSearchParams.ts | 212 ++++++++++++ .../model/models.ts | 7 +- .../model/searchParams.ts | 232 +++++++------- .../model/searchParamsAsString.ts | 3 + .../model/setSettingsResponse.ts | 10 + openapitools.json | 2 +- specs/common/parameters.yml | 60 ++-- .../common/responses/BadRequest.yml | 2 +- .../common/responses/IndexNotFound.yml | 2 +- specs/common/responses/MethodNotAllowed.yml | 5 + specs/common/responses/common.yml | 26 -- specs/search/common/schemas/IndexSettings.yml | 302 ++++++++++++++++++ .../common/schemas/IndexSettingsParams.yml | 85 ----- specs/search/common/schemas/Record.yml | 2 +- specs/search/common/schemas/SearchParams.yml | 234 +------------- .../search/common/schemas/SearchResponse.yml | 14 +- specs/search/paths/objects/batch.yml | 10 +- specs/search/paths/objects/objects.yml | 12 +- specs/search/paths/search/multipleQueries.yml | 8 +- specs/search/paths/search/search.yml | 14 +- specs/search/paths/settings/settings.yml | 55 ++++ specs/search/spec.yml | 4 +- templates/javascript/api-single.mustache | 2 +- 30 files changed, 1340 insertions(+), 566 deletions(-) create mode 100644 .prettierignore delete mode 100644 clients/algoliasearch-client-javascript/git_push.sh create mode 100644 clients/algoliasearch-client-javascript/model/baseIndexSettings.ts create mode 100644 clients/algoliasearch-client-javascript/model/baseSearchParams.ts create mode 100644 clients/algoliasearch-client-javascript/model/indexSettings.ts create mode 100644 clients/algoliasearch-client-javascript/model/indexSettingsAsSearchParams.ts create mode 100644 clients/algoliasearch-client-javascript/model/searchParamsAsString.ts create mode 100644 clients/algoliasearch-client-javascript/model/setSettingsResponse.ts rename specs/{search => }/common/responses/BadRequest.yml (62%) rename specs/{search => }/common/responses/IndexNotFound.yml (57%) create mode 100644 specs/common/responses/MethodNotAllowed.yml delete mode 100644 specs/common/responses/common.yml create mode 100644 specs/search/common/schemas/IndexSettings.yml delete mode 100644 specs/search/common/schemas/IndexSettingsParams.yml diff --git a/.gitignore b/.gitignore index 4d6b8f8cbf..ad91e1b515 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ yarn-error.log **/node_modules **/dist **/.openapi-generator-ignore +**/git_push.sh diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..1521c8b765 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +dist diff --git a/clients/algoliasearch-client-javascript/client-search/searchApi.ts b/clients/algoliasearch-client-javascript/client-search/searchApi.ts index b643e903b3..53fd9dec84 100644 --- a/clients/algoliasearch-client-javascript/client-search/searchApi.ts +++ b/clients/algoliasearch-client-javascript/client-search/searchApi.ts @@ -6,12 +6,14 @@ import { Requester } from '../utils/Requester'; import { BatchObject } from '../model/batchObject'; import { BatchResponse } from '../model/batchResponse'; import { ErrorBase } from '../model/errorBase'; +import { IndexSettings } from '../model/indexSettings'; import { MultipleQueriesObject } from '../model/multipleQueriesObject'; import { MultipleQueriesResponse } from '../model/multipleQueriesResponse'; import { SaveObjectResponse } from '../model/saveObjectResponse'; import { SearchParams } from '../model/searchParams'; -import { SearchParamsString } from '../model/searchParamsString'; +import { SearchParamsAsString } from '../model/searchParamsAsString'; import { SearchResponse } from '../model/searchResponse'; +import { SetSettingsResponse } from '../model/setSettingsResponse'; import { ApiKeyAuth } from '../model/models'; export enum SearchApiApiKeys { @@ -108,6 +110,37 @@ export class SearchApi { return this.sendRequest(request, requestOptions); } + /** + * + * @summary Retrieve settings of a given indexName. + * @param indexName The index in which to perform the request + */ + public async getSettings(indexName: string): Promise { + const path = '/1/indexes/{indexName}/settings'.replace( + '{' + 'indexName' + '}', + encodeURIComponent(String(indexName)) + ); + let headers: Headers = { Accept: 'application/json' }; + let queryParameters: Record = {}; + + if (indexName === null || indexName === undefined) { + throw new Error( + 'Required parameter indexName was null or undefined when calling getSettings.' + ); + } + + const request: Request = { + method: 'GET', + path, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } /** * * @summary Get search results for the given requests. @@ -185,11 +218,11 @@ export class SearchApi { * * @summary Get search results * @param indexName The index in which to perform the request - * @param searchParamsSearchParamsString + * @param searchParamsAsStringSearchParams */ public async search( indexName: string, - searchParamsSearchParamsString: SearchParams | SearchParamsString + searchParamsAsStringSearchParams: SearchParamsAsString | SearchParams ): Promise { const path = '/1/indexes/{indexName}/query'.replace( '{' + 'indexName' + '}', @@ -202,16 +235,67 @@ export class SearchApi { throw new Error('Required parameter indexName was null or undefined when calling search.'); } - if (searchParamsSearchParamsString === null || searchParamsSearchParamsString === undefined) { + if ( + searchParamsAsStringSearchParams === null || + searchParamsAsStringSearchParams === undefined + ) { throw new Error( - 'Required parameter searchParamsSearchParamsString was null or undefined when calling search.' + 'Required parameter searchParamsAsStringSearchParams was null or undefined when calling search.' ); } const request: Request = { method: 'POST', path, - data: searchParamsSearchParamsString, + data: searchParamsAsStringSearchParams, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } + /** + * + * @summary Update settings of a given indexName. Only specified settings are overridden; unspecified settings are left unchanged. Specifying null for a setting resets it to its default value. + * @param indexName The index in which to perform the request + * @param indexSettings + * @param forwardToReplicas When true, changes are also propagated to replicas of the given indexName. + */ + public async setSettings( + indexName: string, + indexSettings: IndexSettings, + forwardToReplicas?: boolean + ): Promise { + const path = '/1/indexes/{indexName}/settings'.replace( + '{' + 'indexName' + '}', + encodeURIComponent(String(indexName)) + ); + let headers: Headers = { Accept: 'application/json' }; + let queryParameters: Record = {}; + + if (indexName === null || indexName === undefined) { + throw new Error( + 'Required parameter indexName was null or undefined when calling setSettings.' + ); + } + + if (indexSettings === null || indexSettings === undefined) { + throw new Error( + 'Required parameter indexSettings was null or undefined when calling setSettings.' + ); + } + + if (forwardToReplicas !== undefined) { + queryParameters['forwardToReplicas'] = forwardToReplicas.toString(); + } + + const request: Request = { + method: 'PUT', + path, + data: indexSettings, }; const requestOptions: RequestOptions = { diff --git a/clients/algoliasearch-client-javascript/git_push.sh b/clients/algoliasearch-client-javascript/git_push.sh deleted file mode 100644 index f47938bb06..0000000000 --- a/clients/algoliasearch-client-javascript/git_push.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/sh -# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ -# -# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" "gitlab.com" - -git_user_id=$1 -git_repo_id=$2 -release_note=$3 -git_host=$4 - -if [ "$git_host" = "" ]; then - git_host="algolia" - echo "[INFO] No command line input provided. Set \$git_host to $git_host" -fi - -if [ "$git_user_id" = "" ]; then - git_user_id="algolia" - echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" -fi - -if [ "$git_repo_id" = "" ]; then - git_repo_id="algoliasearch-client-javascript" - echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" -fi - -if [ "$release_note" = "" ]; then - release_note="Minor update" - echo "[INFO] No command line input provided. Set \$release_note to $release_note" -fi - -# Initialize the local directory as a Git repository -git init - -# Adds the files in the local repository and stages them for commit. -git add . - -# Commits the tracked changes and prepares them to be pushed to a remote repository. -git commit -m "$release_note" - -# Sets the new remote -git_remote=`git remote` -if [ "$git_remote" = "" ]; then # git remote not defined - - if [ "$GIT_TOKEN" = "" ]; then - echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." - git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git - else - git remote add origin https://${git_user_id}:${GIT_TOKEN}@${git_host}/${git_user_id}/${git_repo_id}.git - fi - -fi - -git pull origin master - -# Pushes (Forces) the changes in the local repository up to the remote repository -echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" -git push origin master 2>&1 | grep -v 'To https' - diff --git a/clients/algoliasearch-client-javascript/model/baseIndexSettings.ts b/clients/algoliasearch-client-javascript/model/baseIndexSettings.ts new file mode 100644 index 0000000000..1d3ceebb0c --- /dev/null +++ b/clients/algoliasearch-client-javascript/model/baseIndexSettings.ts @@ -0,0 +1,50 @@ +export type BaseIndexSettings = { + /** + * Creates replicas, exact copies of an index. + */ + replicas?: Array; + /** + * Set the maximum number of hits accessible via pagination. + */ + paginationLimitedTo?: number; + /** + * A list of words for which you want to turn off typo tolerance. + */ + disableTypoToleranceOnWords?: Array; + /** + * Specify on which attributes to apply transliteration. + */ + attributesToTransliterate?: Array; + /** + * List of attributes on which to do a decomposition of camel case words. + */ + camelCaseAttributes?: Array; + /** + * Specify on which attributes in your index Algolia should apply word segmentation, also known as decompounding. + */ + decompoundedAttributes?: { [key: string]: object }; + /** + * Sets the languages at the index level for language-specific processing such as tokenization and normalization. + */ + indexLanguages?: Array; + /** + * Whether promoted results should match the filters of the current search, except for geographic filters. + */ + filterPromotes?: boolean; + /** + * List of attributes on which you want to disable prefix matching. + */ + disablePrefixOnAttributes?: Array; + /** + * Enables compression of large integer arrays. + */ + allowCompressionOfIntegerArray?: boolean; + /** + * List of numeric attributes that can be used as numerical filters. + */ + numericAttributesForFiltering?: Array; + /** + * Lets you store custom data in your indices. + */ + userData?: { [key: string]: object }; +}; diff --git a/clients/algoliasearch-client-javascript/model/baseSearchParams.ts b/clients/algoliasearch-client-javascript/model/baseSearchParams.ts new file mode 100644 index 0000000000..4bedbadf18 --- /dev/null +++ b/clients/algoliasearch-client-javascript/model/baseSearchParams.ts @@ -0,0 +1,134 @@ +export type BaseSearchParams = { + /** + * The text to search in the index. + */ + query: string; + /** + * Overrides the query parameter and performs a more generic search that can be used to find \"similar\" results. + */ + similarQuery?: string; + /** + * Filter the query with numeric, facet and/or tag filters. + */ + filters?: string; + /** + * Filter hits by facet value. + */ + facetFilters?: Array; + /** + * Create filters for ranking purposes, where records that match the filter are ranked higher, or lower in the case of a negative optional filter. + */ + optionalFilters?: Array; + /** + * Filter on numeric attributes. + */ + numericFilters?: Array; + /** + * Filter hits by tags. + */ + tagFilters?: Array; + /** + * Determines how to calculate the total score for filtering. + */ + sumOrFiltersScores?: boolean; + /** + * Retrieve facets and their facet values. + */ + facets?: Array; + /** + * Maximum number of facet values to return for each facet during a regular search. + */ + maxValuesPerFacet?: number; + /** + * Force faceting to be applied after de-duplication (via the Distinct setting). + */ + facetingAfterDistinct?: boolean; + /** + * Controls how facet values are fetched. + */ + sortFacetValuesBy?: string; + /** + * Specify the page to retrieve. + */ + page?: number; + /** + * Specify the offset of the first hit to return. + */ + offset?: number; + /** + * Set the number of hits to retrieve (used only with offset). + */ + length?: number; + /** + * Search for entries around a central geolocation, enabling a geo search within a circular area. + */ + aroundLatLng?: string; + /** + * Search for entries around a given location automatically computed from the requester’s IP address. + */ + aroundLatLngViaIP?: boolean; + /** + * Define the maximum radius for a geo search (in meters). + */ + aroundRadius?: number | string | null; + /** + * Precision of geo search (in meters), to add grouping by geo location to the ranking formula. + */ + aroundPrecision?: number; + /** + * Minimum radius (in meters) used for a geo search when aroundRadius is not set. + */ + minimumAroundRadius?: number; + /** + * Search inside a rectangular area (in geo coordinates). + */ + insideBoundingBox?: Array; + /** + * Search inside a polygon (in geo coordinates). + */ + insidePolygon?: Array; + /** + * This parameter changes the default values of certain parameters and settings that work best for a natural language query, such as ignorePlurals, removeStopWords, removeWordsIfNoResults, analyticsTags and ruleContexts. These parameters and settings work well together when the query is formatted in natural language instead of keywords, for example when your user performs a voice search. + */ + naturalLanguages?: Array; + /** + * Enables contextual rules. + */ + ruleContexts?: Array; + /** + * Define the impact of the Personalization feature. + */ + personalizationImpact?: number; + /** + * Associates a certain user token with the current search. + */ + userToken?: string; + /** + * Retrieve detailed ranking information. + */ + getRankingInfo?: boolean; + /** + * Enable the Click Analytics feature. + */ + clickAnalytics?: boolean; + /** + * Whether the current query will be taken into account in the Analytics. + */ + analytics?: boolean; + /** + * List of tags to apply to the query for analytics purposes. + */ + analyticsTags?: Array; + /** + * Whether to include or exclude a query from the processing-time percentile computation. + */ + percentileComputation?: boolean; + /** + * Whether this search should participate in running AB tests. + */ + enableABTest?: boolean; + /** + * Whether this search should use AI Re-Ranking. + */ + enableReRanking?: boolean; +}; diff --git a/clients/algoliasearch-client-javascript/model/indexSettings.ts b/clients/algoliasearch-client-javascript/model/indexSettings.ts new file mode 100644 index 0000000000..0bccb5e7b3 --- /dev/null +++ b/clients/algoliasearch-client-javascript/model/indexSettings.ts @@ -0,0 +1,263 @@ +import { BaseIndexSettings } from './baseIndexSettings'; +import { IndexSettingsAsSearchParams } from './indexSettingsAsSearchParams'; + +export type IndexSettings = { + /** + * Creates replicas, exact copies of an index. + */ + replicas?: Array; + /** + * Set the maximum number of hits accessible via pagination. + */ + paginationLimitedTo?: number; + /** + * A list of words for which you want to turn off typo tolerance. + */ + disableTypoToleranceOnWords?: Array; + /** + * Specify on which attributes to apply transliteration. + */ + attributesToTransliterate?: Array; + /** + * List of attributes on which to do a decomposition of camel case words. + */ + camelCaseAttributes?: Array; + /** + * Specify on which attributes in your index Algolia should apply word segmentation, also known as decompounding. + */ + decompoundedAttributes?: { [key: string]: object }; + /** + * Sets the languages at the index level for language-specific processing such as tokenization and normalization. + */ + indexLanguages?: Array; + /** + * Whether promoted results should match the filters of the current search, except for geographic filters. + */ + filterPromotes?: boolean; + /** + * List of attributes on which you want to disable prefix matching. + */ + disablePrefixOnAttributes?: Array; + /** + * Enables compression of large integer arrays. + */ + allowCompressionOfIntegerArray?: boolean; + /** + * List of numeric attributes that can be used as numerical filters. + */ + numericAttributesForFiltering?: Array; + /** + * Lets you store custom data in your indices. + */ + userData?: { [key: string]: object }; + /** + * The complete list of attributes used for searching. + */ + searchableAttributes?: Array; + /** + * The complete list of attributes that will be used for faceting. + */ + attributesForFaceting?: Array; + /** + * List of attributes that can’t be retrieved at query time. + */ + unretrievableAttributes?: Array; + /** + * This parameter controls which attributes to retrieve and which not to retrieve. + */ + attributesToRetrieve?: Array; + /** + * Restricts a given query to look in only a subset of your searchable attributes. + */ + restrictSearchableAttributes?: Array; + /** + * Controls how Algolia should sort your results. + */ + ranking?: Array; + /** + * Specifies the custom ranking criterion. + */ + customRanking?: Array; + /** + * Controls the relevancy threshold below which less relevant results aren’t included in the results. + */ + relevancyStrictness?: number; + /** + * List of attributes to highlight. + */ + attributesToHighlight?: Array; + /** + * List of attributes to snippet, with an optional maximum number of words to snippet. + */ + attributesToSnippet?: Array; + /** + * The HTML string to insert before the highlighted parts in all highlight and snippet results. + */ + highlightPreTag?: string; + /** + * The HTML string to insert after the highlighted parts in all highlight and snippet results. + */ + highlightPostTag?: string; + /** + * String used as an ellipsis indicator when a snippet is truncated. + */ + snippetEllipsisText?: string; + /** + * Restrict highlighting and snippeting to items that matched the query. + */ + restrictHighlightAndSnippetArrays?: boolean; + /** + * Set the number of hits per page. + */ + hitsPerPage?: number; + /** + * Minimum number of characters a word in the query string must contain to accept matches with 1 typo. + */ + minWordSizefor1Typo?: number; + /** + * Minimum number of characters a word in the query string must contain to accept matches with 2 typos. + */ + minWordSizefor2Typos?: number; + /** + * Controls whether typo tolerance is enabled and how it is applied. + */ + typoTolerance?: IndexSettings.TypoToleranceEnum; + /** + * Whether to allow typos on numbers (“numeric tokens”) in the query string. + */ + allowTyposOnNumericTokens?: boolean; + /** + * List of attributes on which you want to disable typo tolerance. + */ + disableTypoToleranceOnAttributes?: Array; + /** + * Control which separators are indexed. + */ + separatorsToIndex?: string; + /** + * Treats singular, plurals, and other forms of declensions as matching terms. + */ + ignorePlurals?: string; + /** + * Removes stop (common) words from the query before executing it. + */ + removeStopWords?: string; + /** + * List of characters that the engine shouldn’t automatically normalize. + */ + keepDiacriticsOnCharacters?: string; + /** + * Sets the languages to be used by language-specific settings and functionalities such as ignorePlurals, removeStopWords, and CJK word-detection. + */ + queryLanguages?: Array; + /** + * Splits compound words into their composing atoms in the query. + */ + decompoundQuery?: boolean; + /** + * Whether Rules should be globally enabled. + */ + enableRules?: boolean; + /** + * Enable the Personalization feature. + */ + enablePersonalization?: boolean; + /** + * Controls if and how query words are interpreted as prefixes. + */ + queryType?: IndexSettings.QueryTypeEnum; + /** + * Selects a strategy to remove words from the query when it doesn’t match any hits. + */ + removeWordsIfNoResults?: IndexSettings.RemoveWordsIfNoResultsEnum; + /** + * Enables the advanced query syntax. + */ + advancedSyntax?: boolean; + /** + * A list of words that should be considered as optional when found in the query. + */ + optionalWords?: Array; + /** + * List of attributes on which you want to disable the exact ranking criterion. + */ + disableExactOnAttributes?: Array; + /** + * Controls how the exact ranking criterion is computed when the query contains only one word. + */ + exactOnSingleWordQuery?: IndexSettings.ExactOnSingleWordQueryEnum; + /** + * List of alternatives that should be considered an exact match by the exact ranking criterion. + */ + alternativesAsExact?: Array; + /** + * Allows you to specify which advanced syntax features are active when ‘advancedSyntax’ is enabled. + */ + advancedSyntaxFeatures?: Array; + /** + * Enables de-duplication or grouping of results. + */ + distinct?: number; + /** + * Whether to take into account an index’s synonyms for a particular search. + */ + synonyms?: boolean; + /** + * Whether to highlight and snippet the original word that matches the synonym or the synonym itself. + */ + replaceSynonymsInHighlight?: boolean; + /** + * Precision of the proximity ranking criterion. + */ + minProximity?: number; + /** + * Choose which fields to return in the API response. This parameters applies to search and browse queries. + */ + responseFields?: Array; + /** + * Maximum number of facet hits to return during a search for facet values. + */ + maxFacetHits?: number; + /** + * When attribute is ranked above proximity in your ranking formula, proximity is used to select which searchable attribute is matched in the attribute ranking stage. + */ + attributeCriteriaComputedByMinProximity?: boolean; + /** + * Content defining how the search interface should be rendered. Can be set via the settings for a default value and can be overridden via rules. + */ + renderingContent?: object; +}; + +export namespace IndexSettings { + export enum TypoToleranceEnum { + True = 'true', + False = 'false', + Min = 'min', + Strict = 'strict', + } + export enum QueryTypeEnum { + PrefixLast = 'prefixLast', + PrefixAll = 'prefixAll', + PrefixNone = 'prefixNone', + } + export enum RemoveWordsIfNoResultsEnum { + None = 'none', + LastWords = 'lastWords', + FirstWords = 'firstWords', + AllOptional = 'allOptional', + } + export enum ExactOnSingleWordQueryEnum { + Attribute = 'attribute', + None = 'none', + Word = 'word', + } + export enum AlternativesAsExactEnum { + IgnorePlurals = 'ignorePlurals', + SingleWordSynonym = 'singleWordSynonym', + MultiWordsSynonym = 'multiWordsSynonym', + } + export enum AdvancedSyntaxFeaturesEnum { + ExactPhrase = 'exactPhrase', + ExcludeWords = 'excludeWords', + } +} diff --git a/clients/algoliasearch-client-javascript/model/indexSettingsAsSearchParams.ts b/clients/algoliasearch-client-javascript/model/indexSettingsAsSearchParams.ts new file mode 100644 index 0000000000..8f65866f9b --- /dev/null +++ b/clients/algoliasearch-client-javascript/model/indexSettingsAsSearchParams.ts @@ -0,0 +1,212 @@ +export type IndexSettingsAsSearchParams = { + /** + * The complete list of attributes used for searching. + */ + searchableAttributes?: Array; + /** + * The complete list of attributes that will be used for faceting. + */ + attributesForFaceting?: Array; + /** + * List of attributes that can’t be retrieved at query time. + */ + unretrievableAttributes?: Array; + /** + * This parameter controls which attributes to retrieve and which not to retrieve. + */ + attributesToRetrieve?: Array; + /** + * Restricts a given query to look in only a subset of your searchable attributes. + */ + restrictSearchableAttributes?: Array; + /** + * Controls how Algolia should sort your results. + */ + ranking?: Array; + /** + * Specifies the custom ranking criterion. + */ + customRanking?: Array; + /** + * Controls the relevancy threshold below which less relevant results aren’t included in the results. + */ + relevancyStrictness?: number; + /** + * List of attributes to highlight. + */ + attributesToHighlight?: Array; + /** + * List of attributes to snippet, with an optional maximum number of words to snippet. + */ + attributesToSnippet?: Array; + /** + * The HTML string to insert before the highlighted parts in all highlight and snippet results. + */ + highlightPreTag?: string; + /** + * The HTML string to insert after the highlighted parts in all highlight and snippet results. + */ + highlightPostTag?: string; + /** + * String used as an ellipsis indicator when a snippet is truncated. + */ + snippetEllipsisText?: string; + /** + * Restrict highlighting and snippeting to items that matched the query. + */ + restrictHighlightAndSnippetArrays?: boolean; + /** + * Set the number of hits per page. + */ + hitsPerPage?: number; + /** + * Minimum number of characters a word in the query string must contain to accept matches with 1 typo. + */ + minWordSizefor1Typo?: number; + /** + * Minimum number of characters a word in the query string must contain to accept matches with 2 typos. + */ + minWordSizefor2Typos?: number; + /** + * Controls whether typo tolerance is enabled and how it is applied. + */ + typoTolerance?: IndexSettingsAsSearchParams.TypoToleranceEnum; + /** + * Whether to allow typos on numbers (“numeric tokens”) in the query string. + */ + allowTyposOnNumericTokens?: boolean; + /** + * List of attributes on which you want to disable typo tolerance. + */ + disableTypoToleranceOnAttributes?: Array; + /** + * Control which separators are indexed. + */ + separatorsToIndex?: string; + /** + * Treats singular, plurals, and other forms of declensions as matching terms. + */ + ignorePlurals?: string; + /** + * Removes stop (common) words from the query before executing it. + */ + removeStopWords?: string; + /** + * List of characters that the engine shouldn’t automatically normalize. + */ + keepDiacriticsOnCharacters?: string; + /** + * Sets the languages to be used by language-specific settings and functionalities such as ignorePlurals, removeStopWords, and CJK word-detection. + */ + queryLanguages?: Array; + /** + * Splits compound words into their composing atoms in the query. + */ + decompoundQuery?: boolean; + /** + * Whether Rules should be globally enabled. + */ + enableRules?: boolean; + /** + * Enable the Personalization feature. + */ + enablePersonalization?: boolean; + /** + * Controls if and how query words are interpreted as prefixes. + */ + queryType?: IndexSettingsAsSearchParams.QueryTypeEnum; + /** + * Selects a strategy to remove words from the query when it doesn’t match any hits. + */ + removeWordsIfNoResults?: IndexSettingsAsSearchParams.RemoveWordsIfNoResultsEnum; + /** + * Enables the advanced query syntax. + */ + advancedSyntax?: boolean; + /** + * A list of words that should be considered as optional when found in the query. + */ + optionalWords?: Array; + /** + * List of attributes on which you want to disable the exact ranking criterion. + */ + disableExactOnAttributes?: Array; + /** + * Controls how the exact ranking criterion is computed when the query contains only one word. + */ + exactOnSingleWordQuery?: IndexSettingsAsSearchParams.ExactOnSingleWordQueryEnum; + /** + * List of alternatives that should be considered an exact match by the exact ranking criterion. + */ + alternativesAsExact?: Array; + /** + * Allows you to specify which advanced syntax features are active when ‘advancedSyntax’ is enabled. + */ + advancedSyntaxFeatures?: Array; + /** + * Enables de-duplication or grouping of results. + */ + distinct?: number; + /** + * Whether to take into account an index’s synonyms for a particular search. + */ + synonyms?: boolean; + /** + * Whether to highlight and snippet the original word that matches the synonym or the synonym itself. + */ + replaceSynonymsInHighlight?: boolean; + /** + * Precision of the proximity ranking criterion. + */ + minProximity?: number; + /** + * Choose which fields to return in the API response. This parameters applies to search and browse queries. + */ + responseFields?: Array; + /** + * Maximum number of facet hits to return during a search for facet values. + */ + maxFacetHits?: number; + /** + * When attribute is ranked above proximity in your ranking formula, proximity is used to select which searchable attribute is matched in the attribute ranking stage. + */ + attributeCriteriaComputedByMinProximity?: boolean; + /** + * Content defining how the search interface should be rendered. Can be set via the settings for a default value and can be overridden via rules. + */ + renderingContent?: object; +}; + +export namespace IndexSettingsAsSearchParams { + export enum TypoToleranceEnum { + True = 'true', + False = 'false', + Min = 'min', + Strict = 'strict', + } + export enum QueryTypeEnum { + PrefixLast = 'prefixLast', + PrefixAll = 'prefixAll', + PrefixNone = 'prefixNone', + } + export enum RemoveWordsIfNoResultsEnum { + None = 'none', + LastWords = 'lastWords', + FirstWords = 'firstWords', + AllOptional = 'allOptional', + } + export enum ExactOnSingleWordQueryEnum { + Attribute = 'attribute', + None = 'none', + Word = 'word', + } + export enum AlternativesAsExactEnum { + IgnorePlurals = 'ignorePlurals', + SingleWordSynonym = 'singleWordSynonym', + MultiWordsSynonym = 'multiWordsSynonym', + } + export enum AdvancedSyntaxFeaturesEnum { + ExactPhrase = 'exactPhrase', + ExcludeWords = 'excludeWords', + } +} diff --git a/clients/algoliasearch-client-javascript/model/models.ts b/clients/algoliasearch-client-javascript/model/models.ts index f01a2e4f09..7cce6a697d 100644 --- a/clients/algoliasearch-client-javascript/model/models.ts +++ b/clients/algoliasearch-client-javascript/model/models.ts @@ -1,9 +1,13 @@ import type { RequestOptions } from '../utils/types'; +export * from './baseIndexSettings'; +export * from './baseSearchParams'; export * from './batchObject'; export * from './batchResponse'; export * from './errorBase'; export * from './highlightResult'; +export * from './indexSettings'; +export * from './indexSettingsAsSearchParams'; export * from './multipleQueries'; export * from './multipleQueriesObject'; export * from './multipleQueriesResponse'; @@ -13,9 +17,10 @@ export * from './rankingInfoMatchedGeoLocation'; export * from './record'; export * from './saveObjectResponse'; export * from './searchParams'; -export * from './searchParamsString'; +export * from './searchParamsAsString'; export * from './searchResponse'; export * from './searchResponseFacetsStats'; +export * from './setSettingsResponse'; export * from './snippetResult'; export interface Authentication { diff --git a/clients/algoliasearch-client-javascript/model/searchParams.ts b/clients/algoliasearch-client-javascript/model/searchParams.ts index c6b8bfcf7c..4fd944876c 100644 --- a/clients/algoliasearch-client-javascript/model/searchParams.ts +++ b/clients/algoliasearch-client-javascript/model/searchParams.ts @@ -1,3 +1,6 @@ +import { BaseSearchParams } from './baseSearchParams'; +import { IndexSettingsAsSearchParams } from './indexSettingsAsSearchParams'; + export type SearchParams = { /** * The text to search in the index. @@ -7,38 +10,6 @@ export type SearchParams = { * Overrides the query parameter and performs a more generic search that can be used to find \"similar\" results. */ similarQuery?: string; - /** - * The complete list of attributes used for searching. - */ - searchableAttributes?: Array; - /** - * The complete list of attributes that will be used for faceting. - */ - attributesForFaceting?: Array; - /** - * List of attributes that can’t be retrieved at query time. - */ - unretrievableAttributes?: Array; - /** - * This parameter controls which attributes to retrieve and which not to retrieve. - */ - attributesToRetrieve?: Array; - /** - * Restricts a given query to look in only a subset of your searchable attributes. - */ - restrictSearchableAttributes?: Array; - /** - * Controls how Algolia should sort your results. - */ - ranking?: Array; - /** - * Specifies the custom ranking criterion. - */ - customRanking?: Array; - /** - * Controls the relevancy threshold below which less relevant results aren’t included in the results. - */ - relevancyStrictness?: number; /** * Filter the query with numeric, facet and/or tag filters. */ @@ -79,6 +50,122 @@ export type SearchParams = { * Controls how facet values are fetched. */ sortFacetValuesBy?: string; + /** + * Specify the page to retrieve. + */ + page?: number; + /** + * Specify the offset of the first hit to return. + */ + offset?: number; + /** + * Set the number of hits to retrieve (used only with offset). + */ + length?: number; + /** + * Search for entries around a central geolocation, enabling a geo search within a circular area. + */ + aroundLatLng?: string; + /** + * Search for entries around a given location automatically computed from the requester’s IP address. + */ + aroundLatLngViaIP?: boolean; + /** + * Define the maximum radius for a geo search (in meters). + */ + aroundRadius?: number | string | null; + /** + * Precision of geo search (in meters), to add grouping by geo location to the ranking formula. + */ + aroundPrecision?: number; + /** + * Minimum radius (in meters) used for a geo search when aroundRadius is not set. + */ + minimumAroundRadius?: number; + /** + * Search inside a rectangular area (in geo coordinates). + */ + insideBoundingBox?: Array; + /** + * Search inside a polygon (in geo coordinates). + */ + insidePolygon?: Array; + /** + * This parameter changes the default values of certain parameters and settings that work best for a natural language query, such as ignorePlurals, removeStopWords, removeWordsIfNoResults, analyticsTags and ruleContexts. These parameters and settings work well together when the query is formatted in natural language instead of keywords, for example when your user performs a voice search. + */ + naturalLanguages?: Array; + /** + * Enables contextual rules. + */ + ruleContexts?: Array; + /** + * Define the impact of the Personalization feature. + */ + personalizationImpact?: number; + /** + * Associates a certain user token with the current search. + */ + userToken?: string; + /** + * Retrieve detailed ranking information. + */ + getRankingInfo?: boolean; + /** + * Enable the Click Analytics feature. + */ + clickAnalytics?: boolean; + /** + * Whether the current query will be taken into account in the Analytics. + */ + analytics?: boolean; + /** + * List of tags to apply to the query for analytics purposes. + */ + analyticsTags?: Array; + /** + * Whether to include or exclude a query from the processing-time percentile computation. + */ + percentileComputation?: boolean; + /** + * Whether this search should participate in running AB tests. + */ + enableABTest?: boolean; + /** + * Whether this search should use AI Re-Ranking. + */ + enableReRanking?: boolean; + /** + * The complete list of attributes used for searching. + */ + searchableAttributes?: Array; + /** + * The complete list of attributes that will be used for faceting. + */ + attributesForFaceting?: Array; + /** + * List of attributes that can’t be retrieved at query time. + */ + unretrievableAttributes?: Array; + /** + * This parameter controls which attributes to retrieve and which not to retrieve. + */ + attributesToRetrieve?: Array; + /** + * Restricts a given query to look in only a subset of your searchable attributes. + */ + restrictSearchableAttributes?: Array; + /** + * Controls how Algolia should sort your results. + */ + ranking?: Array; + /** + * Specifies the custom ranking criterion. + */ + customRanking?: Array; + /** + * Controls the relevancy threshold below which less relevant results aren’t included in the results. + */ + relevancyStrictness?: number; /** * List of attributes to highlight. */ @@ -103,22 +190,10 @@ export type SearchParams = { * Restrict highlighting and snippeting to items that matched the query. */ restrictHighlightAndSnippetArrays?: boolean; - /** - * Specify the page to retrieve. - */ - page?: number; /** * Set the number of hits per page. */ hitsPerPage?: number; - /** - * Specify the offset of the first hit to return. - */ - offset?: number; - /** - * Set the number of hits to retrieve (used only with offset). - */ - length?: number; /** * Minimum number of characters a word in the query string must contain to accept matches with 1 typo. */ @@ -143,31 +218,6 @@ export type SearchParams = { * Control which separators are indexed. */ separatorsToIndex?: string; - /** - * Search for entries around a central geolocation, enabling a geo search within a circular area. - */ - aroundLatLng?: string; - /** - * Search for entries around a given location automatically computed from the requester’s IP address. - */ - aroundLatLngViaIP?: boolean; - aroundRadius?: number | string; - /** - * Precision of geo search (in meters), to add grouping by geo location to the ranking formula. - */ - aroundPrecision?: number; - /** - * Minimum radius (in meters) used for a geo search when aroundRadius is not set. - */ - minimumAroundRadius?: number; - /** - * Search inside a rectangular area (in geo coordinates). - */ - insideBoundingBox?: Array; - /** - * Search inside a polygon (in geo coordinates). - */ - insidePolygon?: Array; /** * Treats singular, plurals, and other forms of declensions as matching terms. */ @@ -184,10 +234,6 @@ export type SearchParams = { * Sets the languages to be used by language-specific settings and functionalities such as ignorePlurals, removeStopWords, and CJK word-detection. */ queryLanguages?: Array; - /** - * This parameter changes the default values of certain parameters and settings that work best for a natural language query, such as ignorePlurals, removeStopWords, removeWordsIfNoResults, analyticsTags and ruleContexts. These parameters and settings work well together when the query is formatted in natural language instead of keywords, for example when your user performs a voice search. - */ - naturalLanguages?: Array; /** * Splits compound words into their composing atoms in the query. */ @@ -196,22 +242,10 @@ export type SearchParams = { * Whether Rules should be globally enabled. */ enableRules?: boolean; - /** - * Enables contextual rules. - */ - ruleContexts?: Array; /** * Enable the Personalization feature. */ enablePersonalization?: boolean; - /** - * Define the impact of the Personalization feature. - */ - personalizationImpact?: number; - /** - * Associates a certain user token with the current search. - */ - userToken?: string; /** * Controls if and how query words are interpreted as prefixes. */ @@ -248,22 +282,6 @@ export type SearchParams = { * Enables de-duplication or grouping of results. */ distinct?: number; - /** - * Retrieve detailed ranking information. - */ - getRankingInfo?: boolean; - /** - * Enable the Click Analytics feature. - */ - clickAnalytics?: boolean; - /** - * Whether the current query will be taken into account in the Analytics. - */ - analytics?: boolean; - /** - * List of tags to apply to the query for analytics purposes. - */ - analyticsTags?: Array; /** * Whether to take into account an index’s synonyms for a particular search. */ @@ -284,22 +302,10 @@ export type SearchParams = { * Maximum number of facet hits to return during a search for facet values. */ maxFacetHits?: number; - /** - * Whether to include or exclude a query from the processing-time percentile computation. - */ - percentileComputation?: boolean; /** * When attribute is ranked above proximity in your ranking formula, proximity is used to select which searchable attribute is matched in the attribute ranking stage. */ attributeCriteriaComputedByMinProximity?: boolean; - /** - * Whether this search should participate in running AB tests. - */ - enableABTest?: boolean; - /** - * Whether this search should use AI Re-Ranking. - */ - enableReRanking?: boolean; /** * Content defining how the search interface should be rendered. Can be set via the settings for a default value and can be overridden via rules. */ diff --git a/clients/algoliasearch-client-javascript/model/searchParamsAsString.ts b/clients/algoliasearch-client-javascript/model/searchParamsAsString.ts new file mode 100644 index 0000000000..5840104127 --- /dev/null +++ b/clients/algoliasearch-client-javascript/model/searchParamsAsString.ts @@ -0,0 +1,3 @@ +export type SearchParamsAsString = { + params?: string; +}; diff --git a/clients/algoliasearch-client-javascript/model/setSettingsResponse.ts b/clients/algoliasearch-client-javascript/model/setSettingsResponse.ts new file mode 100644 index 0000000000..a1c0d6eaa4 --- /dev/null +++ b/clients/algoliasearch-client-javascript/model/setSettingsResponse.ts @@ -0,0 +1,10 @@ +export type SetSettingsResponse = { + /** + * taskID of the indexing task to wait for. + */ + taskID?: number; + /** + * Date of last update. (ISO-8601 format) + */ + updatedAt?: Date; +}; diff --git a/openapitools.json b/openapitools.json index fa58cee756..2fa27925d9 100644 --- a/openapitools.json +++ b/openapitools.json @@ -1,7 +1,7 @@ { "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", "generator-cli": { - "version": "5.2.1", + "version": "5.3.0", "generators": { "javascript-client": { "generatorName": "typescript-node", diff --git a/specs/common/parameters.yml b/specs/common/parameters.yml index 226ccfb473..d64a60a587 100644 --- a/specs/common/parameters.yml +++ b/specs/common/parameters.yml @@ -1,21 +1,4 @@ -AppId: - name: X-Algolia-Application-Id - in: header - description: Algolia appID - required: true - schema: - type: string - pattern: '^(?:beta|testing)?[A-Z0-9]{10}$' - example: 'DJNVGS47DK' -ApiKey: - name: X-Algolia-API-Key - in: header - description: Algolia API key - required: true - schema: - type: string - pattern: '^[a-f0-9]{32}$' - example: '43b15df305339e827f0ac0bdc5ebcaa7' +# path IndexName: name: indexName in: path @@ -24,3 +7,44 @@ IndexName: schema: type: string example: 'myIndexName' + +# query +ForwardToReplicas: + in: query + name: forwardToReplicas + description: When true, changes are also propagated to replicas of the given indexName. + schema: + type: boolean + +# misc +taskID: + type: integer + description: taskID of the indexing task to wait for. + +objectID: + type: string + description: Unique identifier of the object + +objectIDs: + type: array + items: + type: string + description: List of objectID + +queryID: + type: string + pattern: '^[a-f0-9]{32}$' + example: 43b15df305339e827f0ac0bdc5ebcaa7 + +abTestID: + type: integer + description: If a search encounters an index that is being A/B tested, abTestID reports the ongoing A/B test ID. + +abTestVariantID: + type: integer + description: If a search encounters an index that is being A/B tested, abTestVariantID reports the variant ID of the index used. + +updatedAt: + type: string + format: date-time + description: Date of last update. (ISO-8601 format) diff --git a/specs/search/common/responses/BadRequest.yml b/specs/common/responses/BadRequest.yml similarity index 62% rename from specs/search/common/responses/BadRequest.yml rename to specs/common/responses/BadRequest.yml index e5794d26f1..bd78840b4f 100644 --- a/specs/search/common/responses/BadRequest.yml +++ b/specs/common/responses/BadRequest.yml @@ -2,4 +2,4 @@ description: Bad request or request arguments content: application/json: schema: - $ref: '../../../common/schemas/ErrorBase.yml' + $ref: '../schemas/ErrorBase.yml' diff --git a/specs/search/common/responses/IndexNotFound.yml b/specs/common/responses/IndexNotFound.yml similarity index 57% rename from specs/search/common/responses/IndexNotFound.yml rename to specs/common/responses/IndexNotFound.yml index 1ba8607d12..a13beb85b1 100644 --- a/specs/search/common/responses/IndexNotFound.yml +++ b/specs/common/responses/IndexNotFound.yml @@ -2,4 +2,4 @@ description: Index not found content: application/json: schema: - $ref: '../../../common/schemas/ErrorBase.yml' + $ref: '../schemas/ErrorBase.yml' diff --git a/specs/common/responses/MethodNotAllowed.yml b/specs/common/responses/MethodNotAllowed.yml new file mode 100644 index 0000000000..da0db9b226 --- /dev/null +++ b/specs/common/responses/MethodNotAllowed.yml @@ -0,0 +1,5 @@ +description: Method not allowed with this API key +content: + application/json: + schema: + $ref: '../schemas/ErrorBase.yml' diff --git a/specs/common/responses/common.yml b/specs/common/responses/common.yml deleted file mode 100644 index cc9d2bf26a..0000000000 --- a/specs/common/responses/common.yml +++ /dev/null @@ -1,26 +0,0 @@ -taskID: - type: integer - description: taskID of the indexing task to wait for. - -objectID: - type: string - description: Unique identifier of the object - -objectIDs: - type: array - items: - type: string - description: List of objectID - -queryID: - type: string - pattern: '^[a-f0-9]{32}$' - example: 43b15df305339e827f0ac0bdc5ebcaa7 - -abTestID: - type: integer - description: If a search encounters an index that is being A/B tested, abTestID reports the ongoing A/B test ID. - -abTestVariantID: - type: integer - description: If a search encounters an index that is being A/B tested, abTestVariantID reports the variant ID of the index used. diff --git a/specs/search/common/schemas/IndexSettings.yml b/specs/search/common/schemas/IndexSettings.yml new file mode 100644 index 0000000000..7494a5f6ae --- /dev/null +++ b/specs/search/common/schemas/IndexSettings.yml @@ -0,0 +1,302 @@ +indexSettings: + allOf: + - $ref: '#/baseIndexSettings' + - $ref: '#/indexSettingsAsSearchParams' + +baseIndexSettings: + type: object + additionalProperties: false + properties: + replicas: + type: array + items: + type: string + description: Creates replicas, exact copies of an index. + default: [] + paginationLimitedTo: + type: integer + description: Set the maximum number of hits accessible via pagination. + default: 1000 + disableTypoToleranceOnWords: + type: array + items: + type: string + description: A list of words for which you want to turn off typo tolerance. + default: [] + attributesToTransliterate: + type: array + items: + type: string + description: Specify on which attributes to apply transliteration. + camelCaseAttributes: + type: array + items: + type: string + description: List of attributes on which to do a decomposition of camel case words. + default: [] + decompoundedAttributes: + type: object + additionalProperties: true + description: Specify on which attributes in your index Algolia should apply word segmentation, also known as decompounding. + default: {} + indexLanguages: + type: array + items: + type: string + description: Sets the languages at the index level for language-specific processing such as tokenization and normalization. + default: [] + filterPromotes: + type: boolean + description: Whether promoted results should match the filters of the current search, except for geographic filters. + default: false + disablePrefixOnAttributes: + type: array + items: + type: string + description: List of attributes on which you want to disable prefix matching. + default: [] + allowCompressionOfIntegerArray: + type: boolean + description: Enables compression of large integer arrays. + default: false + numericAttributesForFiltering: + type: array + items: + type: string + description: List of numeric attributes that can be used as numerical filters. + default: [] + userData: + type: object + additionalProperties: true + description: Lets you store custom data in your indices. + default: {} + +indexSettingsAsSearchParams: + type: object + additionalProperties: false + properties: + searchableAttributes: + type: array + items: + type: string + description: The complete list of attributes used for searching. + default: [] + attributesForFaceting: + type: array + items: + type: string + description: The complete list of attributes that will be used for faceting. + default: [] + unretrievableAttributes: + type: array + items: + type: string + description: List of attributes that can’t be retrieved at query time. + default: [] + attributesToRetrieve: + type: array + items: + type: string + description: This parameter controls which attributes to retrieve and which not to retrieve. + default: ['*'] + restrictSearchableAttributes: + type: array + items: + type: string + description: Restricts a given query to look in only a subset of your searchable attributes. + default: [] + ranking: + type: array + items: + type: string + description: Controls how Algolia should sort your results. + default: + - 'typo' + - 'geo' + - 'words' + - 'filters' + - 'proximity' + - 'attribute' + - 'exact' + - 'custom' + customRanking: + type: array + items: + type: string + description: Specifies the custom ranking criterion. + default: [] + relevancyStrictness: + type: integer + description: Controls the relevancy threshold below which less relevant results aren’t included in the results. + default: 100 + attributesToHighlight: + type: array + items: + type: string + description: List of attributes to highlight. + attributesToSnippet: + type: array + items: + type: string + description: List of attributes to snippet, with an optional maximum number of words to snippet. + default: [] + highlightPreTag: + type: string + description: The HTML string to insert before the highlighted parts in all highlight and snippet results. + default: '' + highlightPostTag: + type: string + description: The HTML string to insert after the highlighted parts in all highlight and snippet results. + default: '' + snippetEllipsisText: + type: string + description: String used as an ellipsis indicator when a snippet is truncated. + default: '…' + restrictHighlightAndSnippetArrays: + type: boolean + description: Restrict highlighting and snippeting to items that matched the query. + default: false + hitsPerPage: + type: integer + description: Set the number of hits per page. + default: 20 + minWordSizefor1Typo: + type: integer + description: Minimum number of characters a word in the query string must contain to accept matches with 1 typo. + default: 4 + minWordSizefor2Typos: + type: integer + description: Minimum number of characters a word in the query string must contain to accept matches with 2 typos. + default: 8 + typoTolerance: + type: string + enum: [true, false, 'min', 'strict'] + description: Controls whether typo tolerance is enabled and how it is applied. + default: true + allowTyposOnNumericTokens: + type: boolean + description: Whether to allow typos on numbers (“numeric tokens”) in the query string. + default: true + disableTypoToleranceOnAttributes: + type: array + items: + type: string + description: List of attributes on which you want to disable typo tolerance. + default: [] + separatorsToIndex: + type: string + description: Control which separators are indexed. + default: '' + ignorePlurals: + type: string + description: Treats singular, plurals, and other forms of declensions as matching terms. + default: false + removeStopWords: + type: string + description: Removes stop (common) words from the query before executing it. + default: false + keepDiacriticsOnCharacters: + type: string + description: List of characters that the engine shouldn’t automatically normalize. + default: '' + queryLanguages: + type: array + items: + type: string + description: Sets the languages to be used by language-specific settings and functionalities such as ignorePlurals, removeStopWords, and CJK word-detection. + default: [] + decompoundQuery: + type: boolean + description: Splits compound words into their composing atoms in the query. + default: true + enableRules: + type: boolean + description: Whether Rules should be globally enabled. + default: true + enablePersonalization: + type: boolean + description: Enable the Personalization feature. + default: false + queryType: + type: string + enum: ['prefixLast', 'prefixAll', 'prefixNone'] + description: Controls if and how query words are interpreted as prefixes. + default: 'prefixLast' + removeWordsIfNoResults: + type: string + enum: ['none', 'lastWords', 'firstWords', 'allOptional'] + description: Selects a strategy to remove words from the query when it doesn’t match any hits. + default: 'none' + advancedSyntax: + type: boolean + description: Enables the advanced query syntax. + default: false + optionalWords: + type: array + items: + type: string + description: A list of words that should be considered as optional when found in the query. + default: [] + disableExactOnAttributes: + type: array + items: + type: string + description: List of attributes on which you want to disable the exact ranking criterion. + default: [] + exactOnSingleWordQuery: + type: string + enum: ['attribute', 'none', 'word'] + description: Controls how the exact ranking criterion is computed when the query contains only one word. + default: 'attribute' + alternativesAsExact: + type: array + items: + type: string + enum: ['ignorePlurals', 'singleWordSynonym', 'multiWordsSynonym'] + description: List of alternatives that should be considered an exact match by the exact ranking criterion. + default: ['ignorePlurals', 'singleWordSynonym'] + advancedSyntaxFeatures: + type: array + items: + type: string + enum: ['exactPhrase', 'excludeWords'] + description: Allows you to specify which advanced syntax features are active when ‘advancedSyntax’ is enabled. + default: ['exactPhrase', 'excludeWords'] + distinct: + type: integer + minimum: 0 + maximum: 4 + description: Enables de-duplication or grouping of results. + default: 0 + synonyms: + type: boolean + description: Whether to take into account an index’s synonyms for a particular search. + default: true + replaceSynonymsInHighlight: + type: boolean + description: Whether to highlight and snippet the original word that matches the synonym or the synonym itself. + default: false + minProximity: + type: integer + minimum: 1 + maximum: 7 + description: Precision of the proximity ranking criterion. + default: 1 + responseFields: + type: array + items: + type: string + description: Choose which fields to return in the API response. This parameters applies to search and browse queries. + default: [] + maxFacetHits: + type: integer + description: Maximum number of facet hits to return during a search for facet values. + default: 10 + attributeCriteriaComputedByMinProximity: + type: boolean + description: When attribute is ranked above proximity in your ranking formula, proximity is used to select which searchable attribute is matched in the attribute ranking stage. + default: false + renderingContent: + type: object + description: Content defining how the search interface should be rendered. Can be set via the settings for a default value and can be overridden via rules. + default: {} diff --git a/specs/search/common/schemas/IndexSettingsParams.yml b/specs/search/common/schemas/IndexSettingsParams.yml deleted file mode 100644 index 9f608a844e..0000000000 --- a/specs/search/common/schemas/IndexSettingsParams.yml +++ /dev/null @@ -1,85 +0,0 @@ -allowCompressionOfIntegerArray: - type: boolean - description: Enables compression of large integer arrays. - default: false - -attributeForDistinct: - type: string - description: Name of the de-duplication attribute to be used with the distinct feature. - default: null - -attributesToTransliterate: - type: array - items: - type: string - description: Specify on which attributes to apply transliteration. - -camelCaseAttributes: - type: array - items: - type: string - description: List of attributes on which to do a decomposition of camel case words. - default: [] - -customNormalization: - type: object - additionalProperties: true - description: Override the default normalization handled by the engine. - default: {} - -decompoundedAttributes: - type: object - additionalProperties: true - description: Specify on which attributes in your index Algolia should apply word segmentation, also known as decompounding. - default: {} - -disablePrefixOnAttributes: - type: array - items: - type: string - description: List of attributes on which you want to disable prefix matching. - default: [] - -disableTypoToleranceOnWords: - type: array - items: - type: string - description: A list of words for which you want to turn off typo tolerance. - default: [] - -filterPromotes: - type: boolean - description: Whether promoted results should match the filters of the current search, except for geographic filters. - default: false - -indexLanguages: - type: array - items: - type: string - description: Sets the languages at the index level for language-specific processing such as tokenization and normalization. - default: [] - -numericAttributesForFiltering: - type: array - items: - type: string - description: List of numeric attributes that can be used as numerical filters. - default: null - -paginationLimitedTo: - type: integer - description: Set the maximum number of hits accessible via pagination. - default: 1000 - -userData: - type: object - additionalProperties: true - description: Lets you store custom data in your indices. - default: {} - -replicas: - type: array - items: - type: string - description: Creates replicas, exact copies of an index. - default: [] diff --git a/specs/search/common/schemas/Record.yml b/specs/search/common/schemas/Record.yml index 9b8bada454..80f4d83557 100644 --- a/specs/search/common/schemas/Record.yml +++ b/specs/search/common/schemas/Record.yml @@ -6,7 +6,7 @@ record: - objectID properties: objectID: - $ref: '../../../common/responses/common.yml#/objectID' + $ref: '../../../common/parameters.yml#/objectID' _highlightResult: $ref: '#/highlightResult' _snippetResult: diff --git a/specs/search/common/schemas/SearchParams.yml b/specs/search/common/schemas/SearchParams.yml index 10f642d6a8..4a0af449cf 100644 --- a/specs/search/common/schemas/SearchParams.yml +++ b/specs/search/common/schemas/SearchParams.yml @@ -1,4 +1,9 @@ searchParams: + allOf: + - $ref: '../../common/schemas/SearchParams.yml#/baseSearchParams' + - $ref: '../../common/schemas/IndexSettings.yml#/indexSettingsAsSearchParams' + +baseSearchParams: type: object additionalProperties: false required: @@ -12,60 +17,6 @@ searchParams: type: string description: Overrides the query parameter and performs a more generic search that can be used to find "similar" results. default: '' - searchableAttributes: - type: array - items: - type: string - description: The complete list of attributes used for searching. - default: [] - attributesForFaceting: - type: array - items: - type: string - description: The complete list of attributes that will be used for faceting. - default: [] - unretrievableAttributes: - type: array - items: - type: string - description: List of attributes that can’t be retrieved at query time. - default: [] - attributesToRetrieve: - type: array - items: - type: string - description: This parameter controls which attributes to retrieve and which not to retrieve. - default: ['*'] - restrictSearchableAttributes: - type: array - items: - type: string - description: Restricts a given query to look in only a subset of your searchable attributes. - default: [] - ranking: - type: array - items: - type: string - description: Controls how Algolia should sort your results. - default: - - 'typo' - - 'geo' - - 'words' - - 'filters' - - 'proximity' - - 'attribute' - - 'exact' - - 'custom' - customRanking: - type: array - items: - type: string - description: Specifies the custom ranking criterion. - default: [] - relevancyStrictness: - type: integer - description: Controls the relevancy threshold below which less relevant results aren’t included in the results. - default: 100 filters: type: string description: Filter the query with numeric, facet and/or tag filters. @@ -117,41 +68,10 @@ searchParams: type: string description: Controls how facet values are fetched. default: 'count' - attributesToHighlight: - type: array - items: - type: string - description: List of attributes to highlight. - attributesToSnippet: - type: array - items: - type: string - description: List of attributes to snippet, with an optional maximum number of words to snippet. - default: [] - highlightPreTag: - type: string - description: The HTML string to insert before the highlighted parts in all highlight and snippet results. - default: '' - highlightPostTag: - type: string - description: The HTML string to insert after the highlighted parts in all highlight and snippet results. - default: '' - snippetEllipsisText: - type: string - description: String used as an ellipsis indicator when a snippet is truncated. - default: '…' - restrictHighlightAndSnippetArrays: - type: boolean - description: Restrict highlighting and snippeting to items that matched the query. - default: false page: type: integer description: Specify the page to retrieve. default: 0 - hitsPerPage: - type: integer - description: Set the number of hits per page. - default: 20 offset: type: integer description: Specify the offset of the first hit to return. @@ -160,33 +80,6 @@ searchParams: description: Set the number of hits to retrieve (used only with offset). minimum: 1 maximum: 1000 - minWordSizefor1Typo: - type: integer - description: Minimum number of characters a word in the query string must contain to accept matches with 1 typo. - default: 4 - minWordSizefor2Typos: - type: integer - description: Minimum number of characters a word in the query string must contain to accept matches with 2 typos. - default: 8 - typoTolerance: - type: string - enum: [true, false, 'min', 'strict'] - description: Controls whether typo tolerance is enabled and how it is applied. - default: true - allowTyposOnNumericTokens: - type: boolean - description: Whether to allow typos on numbers (“numeric tokens”) in the query string. - default: true - disableTypoToleranceOnAttributes: - type: array - items: - type: string - description: List of attributes on which you want to disable typo tolerance. - default: [] - separatorsToIndex: - type: string - description: Control which separators are indexed. - default: '' aroundLatLng: type: string description: Search for entries around a central geolocation, enabling a geo search within a circular area. @@ -196,9 +89,9 @@ searchParams: description: Search for entries around a given location automatically computed from the requester’s IP address. default: false aroundRadius: + description: Define the maximum radius for a geo search (in meters). oneOf: - type: integer - description: Define the maximum radius for a geo search (in meters). minimum: 1 - type: string enum: [all] @@ -220,48 +113,18 @@ searchParams: items: type: number description: Search inside a polygon (in geo coordinates). - ignorePlurals: - type: string - description: Treats singular, plurals, and other forms of declensions as matching terms. - default: false - removeStopWords: - type: string - description: Removes stop (common) words from the query before executing it. - default: false - keepDiacriticsOnCharacters: - type: string - description: List of characters that the engine shouldn’t automatically normalize. - default: '' - queryLanguages: - type: array - items: - type: string - description: Sets the languages to be used by language-specific settings and functionalities such as ignorePlurals, removeStopWords, and CJK word-detection. - default: [] naturalLanguages: type: array items: type: string description: This parameter changes the default values of certain parameters and settings that work best for a natural language query, such as ignorePlurals, removeStopWords, removeWordsIfNoResults, analyticsTags and ruleContexts. These parameters and settings work well together when the query is formatted in natural language instead of keywords, for example when your user performs a voice search. default: [] - decompoundQuery: - type: boolean - description: Splits compound words into their composing atoms in the query. - default: true - enableRules: - type: boolean - description: Whether Rules should be globally enabled. - default: true ruleContexts: type: array items: type: string description: Enables contextual rules. default: [] - enablePersonalization: - type: boolean - description: Enable the Personalization feature. - default: false personalizationImpact: type: integer description: Define the impact of the Personalization feature. @@ -269,57 +132,6 @@ searchParams: userToken: type: string description: Associates a certain user token with the current search. - queryType: - type: string - enum: ['prefixLast', 'prefixAll', 'prefixNone'] - description: Controls if and how query words are interpreted as prefixes. - default: 'prefixLast' - removeWordsIfNoResults: - type: string - enum: ['none', 'lastWords', 'firstWords', 'allOptional'] - description: Selects a strategy to remove words from the query when it doesn’t match any hits. - default: 'none' - advancedSyntax: - type: boolean - description: Enables the advanced query syntax. - default: false - optionalWords: - type: array - items: - type: string - description: A list of words that should be considered as optional when found in the query. - default: [] - disableExactOnAttributes: - type: array - items: - type: string - description: List of attributes on which you want to disable the exact ranking criterion. - default: [] - exactOnSingleWordQuery: - type: string - enum: ['attribute', 'none', 'word'] - description: Controls how the exact ranking criterion is computed when the query contains only one word. - default: 'attribute' - alternativesAsExact: - type: array - items: - type: string - enum: ['ignorePlurals', 'singleWordSynonym', 'multiWordsSynonym'] - description: List of alternatives that should be considered an exact match by the exact ranking criterion. - default: ['ignorePlurals', 'singleWordSynonym'] - advancedSyntaxFeatures: - type: array - items: - type: string - enum: ['exactPhrase', 'excludeWords'] - description: Allows you to specify which advanced syntax features are active when ‘advancedSyntax’ is enabled. - default: ['exactPhrase', 'excludeWords'] - distinct: - type: integer - minimum: 0 - maximum: 4 - description: Enables de-duplication or grouping of results. - default: 0 getRankingInfo: type: boolean description: Retrieve detailed ranking information. @@ -338,38 +150,10 @@ searchParams: type: string description: List of tags to apply to the query for analytics purposes. default: [] - synonyms: - type: boolean - description: Whether to take into account an index’s synonyms for a particular search. - default: true - replaceSynonymsInHighlight: - type: boolean - description: Whether to highlight and snippet the original word that matches the synonym or the synonym itself. - default: false - minProximity: - type: integer - minimum: 1 - maximum: 7 - description: Precision of the proximity ranking criterion. - default: 1 - responseFields: - type: array - items: - type: string - description: Choose which fields to return in the API response. This parameters applies to search and browse queries. - default: [] - maxFacetHits: - type: integer - description: Maximum number of facet hits to return during a search for facet values. - default: 10 percentileComputation: type: boolean description: Whether to include or exclude a query from the processing-time percentile computation. default: true - attributeCriteriaComputedByMinProximity: - type: boolean - description: When attribute is ranked above proximity in your ranking formula, proximity is used to select which searchable attribute is matched in the attribute ranking stage. - default: false enableABTest: type: boolean description: Whether this search should participate in running AB tests. @@ -378,12 +162,8 @@ searchParams: type: boolean description: Whether this search should use AI Re-Ranking. default: true - renderingContent: - type: object - description: Content defining how the search interface should be rendered. Can be set via the settings for a default value and can be overridden via rules. - default: {} -searchParamsString: +searchParamsAsString: type: object additionalProperties: false properties: diff --git a/specs/search/common/schemas/SearchResponse.yml b/specs/search/common/schemas/SearchResponse.yml index 996162a094..09b2c2c9e4 100644 --- a/specs/search/common/schemas/SearchResponse.yml +++ b/specs/search/common/schemas/SearchResponse.yml @@ -14,9 +14,9 @@ searchResponse: - params properties: abTestID: - $ref: ../../../common/responses/common.yml#/abTestID + $ref: '../../../common/parameters.yml#/abTestID' abTestVariantID: - $ref: ../../../common/responses/common.yml#/abTestVariantID + $ref: '../../../common/parameters.yml#/abTestVariantID' aroundLatLng: type: string description: The computed geo location. @@ -65,9 +65,9 @@ searchResponse: hits: type: array items: - $ref: Record.yml#/record + $ref: 'Record.yml#/record' hitsPerPage: - $ref: SearchParams.yml#/searchParams/properties/hitsPerPage + $ref: 'IndexSettings.yml#/indexSettingsAsSearchParams/properties/hitsPerPage' index: type: string example: indexName @@ -92,7 +92,7 @@ searchResponse: description: The number of hits selected and sorted by the relevant sort algorithm example: 20 page: - $ref: SearchParams.yml#/searchParams/properties/page + $ref: 'SearchParams.yml#/baseSearchParams/properties/page' params: type: string description: A url-encoded string of all search parameters. @@ -105,7 +105,7 @@ searchResponse: description: Time the server took to process the request, in milliseconds. example: 20 query: - $ref: SearchParams.yml#/searchParams/properties/query + $ref: 'SearchParams.yml#/baseSearchParams/properties/query' queryAfterRemoval: type: string description: A markup text indicating which parts of the original query have been removed in order to retrieve a non-empty result set. @@ -113,4 +113,4 @@ searchResponse: type: string description: Actual host name of the server that processed the request. userData: - $ref: IndexSettingsParams.yml#/userData + $ref: 'IndexSettings.yml#/baseIndexSettings/properties/userData' diff --git a/specs/search/paths/objects/batch.yml b/specs/search/paths/objects/batch.yml index 4eaa3d48d8..4cb2210e27 100644 --- a/specs/search/paths/objects/batch.yml +++ b/specs/search/paths/objects/batch.yml @@ -48,10 +48,12 @@ post: additionalProperties: false properties: taskID: - $ref: '../../../common/responses/common.yml#/taskID' + $ref: '../../../common/parameters.yml#/taskID' objectIDs: - $ref: '../../../common/responses/common.yml#/objectIDs' + $ref: '../../../common/parameters.yml#/objectIDs' '400': - $ref: '../../common/responses/BadRequest.yml' + $ref: '../../../common/responses/BadRequest.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' '404': - $ref: '../../common/responses/IndexNotFound.yml' + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/search/paths/objects/objects.yml b/specs/search/paths/objects/objects.yml index a36130275c..cfe9d8c989 100644 --- a/specs/search/paths/objects/objects.yml +++ b/specs/search/paths/objects/objects.yml @@ -26,12 +26,14 @@ post: createdAt: type: string taskID: - $ref: '../../../common/responses/common.yml#/taskID' + $ref: '../../../common/parameters.yml#/taskID' objectID: - $ref: '../../../common/responses/common.yml#/objectID' + $ref: '../../../common/parameters.yml#/objectID' '400': - $ref: '../../common/responses/BadRequest.yml' + $ref: '../../../common/responses/BadRequest.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' '404': - $ref: '../../common/responses/IndexNotFound.yml' -#delete index + $ref: '../../../common/responses/IndexNotFound.yml' +# delete index # delete: diff --git a/specs/search/paths/search/multipleQueries.yml b/specs/search/paths/search/multipleQueries.yml index 399602cde4..78514ab9a6 100644 --- a/specs/search/paths/search/multipleQueries.yml +++ b/specs/search/paths/search/multipleQueries.yml @@ -24,7 +24,7 @@ post: example: products description: The Algolia index name query: - $ref: ../../common/schemas/SearchParams.yml#/searchParams/properties/query + $ref: '../../common/schemas/SearchParams.yml#/baseSearchParams/properties/query' type: type: string enum: [default, facet] @@ -58,6 +58,8 @@ post: items: $ref: ../../common/schemas/SearchResponse.yml#/searchResponse '400': - $ref: ../../common/responses/BadRequest.yml + $ref: '../../../common/responses/BadRequest.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' '404': - $ref: ../../common/responses/IndexNotFound.yml + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/search/paths/search/search.yml b/specs/search/paths/search/search.yml index 0025493972..16df0b8f11 100644 --- a/specs/search/paths/search/search.yml +++ b/specs/search/paths/search/search.yml @@ -11,17 +11,19 @@ post: application/json: schema: oneOf: - - $ref: ../../common/schemas/SearchParams.yml#/searchParams - - $ref: ../../common/schemas/SearchParams.yml#/searchParamsString + - $ref: '../../common/schemas/SearchParams.yml#/searchParamsAsString' + - $ref: '../../common/schemas/SearchParams.yml#/searchParams' responses: '200': description: OK content: application/json: schema: - title: singleQueryResponse - $ref: ../../common/schemas/SearchResponse.yml#/searchResponse + title: searchResponse + $ref: '../../common/schemas/SearchResponse.yml#/searchResponse' '400': - $ref: ../../common/responses/BadRequest.yml + $ref: '../../../common/responses/BadRequest.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' '404': - $ref: ../../common/responses/IndexNotFound.yml + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/search/paths/settings/settings.yml b/specs/search/paths/settings/settings.yml index 7f2769e14e..3ef8ff7a76 100644 --- a/specs/search/paths/settings/settings.yml +++ b/specs/search/paths/settings/settings.yml @@ -1,2 +1,57 @@ get: + tags: + - search + operationId: getSettings + summary: Retrieve settings of a given indexName. + parameters: + - $ref: '../../../common/parameters.yml#/IndexName' + responses: + '200': + description: OK + content: + application/json: + schema: + title: indexSettings + $ref: '../../common/schemas/IndexSettings.yml#/indexSettings' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' + put: + tags: + - search + operationId: setSettings + summary: Update settings of a given indexName. Only specified settings are overridden; unspecified settings are left unchanged. Specifying null for a setting resets it to its default value. + parameters: + - $ref: '../../../common/parameters.yml#/IndexName' + - $ref: '../../../common/parameters.yml#/ForwardToReplicas' + requestBody: + required: true + content: + application/json: + schema: + title: indexSettings + $ref: '../../common/schemas/IndexSettings.yml#/indexSettings' + responses: + '200': + description: OK + content: + application/json: + schema: + title: setSettingsResponse + type: object + additionalProperties: false + properties: + taskID: + $ref: '../../../common/parameters.yml#/taskID' + updatedAt: + $ref: '../../../common/parameters.yml#/updatedAt' + '400': + $ref: '../../../common/responses/BadRequest.yml' + '403': + $ref: '../../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../../common/responses/IndexNotFound.yml' diff --git a/specs/search/spec.yml b/specs/search/spec.yml index 5ec6abf909..5fa9edbf6a 100644 --- a/specs/search/spec.yml +++ b/specs/search/spec.yml @@ -50,8 +50,8 @@ paths: # ########################## # ### Settings Endpoints ### # ########################## - # /1/indexes/{indexName}/settings: - # $ref: './paths/settings/settings.yml' + /1/indexes/{indexName}/settings: + $ref: './paths/settings/settings.yml' # # ################################ # ### Manage Indices Endpoints ### diff --git a/templates/javascript/api-single.mustache b/templates/javascript/api-single.mustache index 9ebb11b699..52c144e582 100644 --- a/templates/javascript/api-single.mustache +++ b/templates/javascript/api-single.mustache @@ -113,7 +113,7 @@ export class {{classname}} { {{/allParams}} {{#queryParams}} if ({{paramName}} !== undefined) { - queryParameters['{{baseName}}'] = {{paramName}}; + queryParameters['{{baseName}}'] = {{paramName}}.toString(); } {{/queryParams}} From 459e6288f2784f55ce73013fb696d134e5c365c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Thu, 25 Nov 2021 15:00:23 +0100 Subject: [PATCH 2/7] feat(specs): add `recommend` spec and client --- README.md | 16 +- clients/README.md | 7 +- .../{ => client-search}/.gitignore | 0 .../{ => client-search}/api.ts | 2 +- .../model/baseIndexSettings.ts | 0 .../model/baseSearchParams.ts | 0 .../client-search/model/baseSearchResponse.ts | 100 ++++++++ .../model/baseSearchResponseFacetsStats.ts} | 2 +- .../{ => client-search}/model/batchObject.ts | 0 .../model/batchResponse.ts | 0 .../{ => client-search}/model/errorBase.ts | 0 .../model/highlightResult.ts | 0 .../model/indexSettings.ts | 0 .../model/indexSettingsAsSearchParams.ts | 0 .../{ => client-search}/model/models.ts | 4 +- .../model/multipleQueries.ts | 0 .../model/multipleQueriesObject.ts | 0 .../model/multipleQueriesResponse.ts | 0 .../{ => client-search}/model/operation.ts | 0 .../{ => client-search}/model/rankingInfo.ts | 0 .../model/rankingInfoMatchedGeoLocation.ts | 0 .../{ => client-search}/model/record.ts | 0 .../model/saveObjectResponse.ts | 0 .../{ => client-search}/model/searchParams.ts | 0 .../model/searchParamsAsString.ts | 0 .../model/searchResponse.ts | 8 +- .../model/searchResponseAllOf.ts | 5 + .../model/setSettingsResponse.ts | 0 .../model/snippetResult.ts | 0 .../{ => client-search}/package.json | 4 +- .../client-search/{ => src}/apis.ts | 4 +- .../client-search/{ => src}/searchApi.ts | 10 +- .../{ => client-search}/tsconfig.json | 2 +- .../client-search/utils}/Cache.ts | 0 .../client-search/utils}/EchoRequester.ts | 0 .../client-search/utils}/HttpRequester.ts | 0 .../client-search/utils}/MemoryCache.ts | 0 .../client-search/utils}/Requester.ts | 0 .../client-search/utils}/Response.ts | 0 .../client-search/utils}/StatefulHost.ts | 0 .../client-search/utils}/Transporter.ts | 0 .../client-search/utils}/errors.ts | 0 .../client-search/utils}/helpers.ts | 0 .../client-search/utils}/types.ts | 0 .../model/searchParamsString.ts | 3 - .../recommend/.gitignore | 6 + .../recommend/api.ts | 3 + .../recommend/model/baseSearchParams.ts | 134 +++++++++++ .../recommend/model/baseSearchResponse.ts | 100 ++++++++ .../model/baseSearchResponseFacetsStats.ts | 18 ++ .../recommend/model/errorBase.ts | 6 + .../model/getRecommendationsResponse.ts | 5 + .../recommend/model/highlightResult.ts | 26 +++ .../model/indexSettingsAsSearchParams.ts | 212 +++++++++++++++++ .../recommend/model/models.ts | 44 ++++ .../recommend/model/rankingInfo.ts | 45 ++++ .../model/rankingInfoMatchedGeoLocation.ts | 14 ++ .../recommend/model/recommendRecord.ts | 21 ++ .../recommend/model/recommendationRequest.ts | 34 +++ .../model/recommendationsResponse.ts | 104 +++++++++ .../model/recommendationsResponseAllOf.ts | 5 + .../recommend/model/snippetResult.ts | 18 ++ .../recommend/package.json | 24 ++ .../recommend/src/apis.ts | 7 + .../recommend/src/recommendApi.ts | 101 ++++++++ .../recommend/tsconfig.json | 22 ++ .../recommend/utils/Cache.ts | 21 ++ .../recommend/utils/EchoRequester.ts | 12 + .../recommend/utils/HttpRequester.ts | 84 +++++++ .../recommend/utils/MemoryCache.ts | 27 +++ .../recommend/utils/Requester.ts | 4 + .../recommend/utils/Response.ts | 17 ++ .../recommend/utils/StatefulHost.ts | 29 +++ .../recommend/utils/Transporter.ts | 216 ++++++++++++++++++ .../recommend/utils/errors.ts | 38 +++ .../recommend/utils/helpers.ts | 94 ++++++++ .../recommend/utils/types.ts | 65 ++++++ openapitools.json | 25 +- package.json | 27 ++- playground/javascript/app.ts | 53 ----- playground/javascript/package.json | 11 +- playground/javascript/recommend.ts | 36 +++ playground/javascript/search.ts | 29 +++ playground/javascript/tsconfig.json | 2 +- specs/common/parameters.yml | 5 + specs/common/responses/FeatureNotEnabled.yml | 5 + .../schemas/RecommendationsResponse.yml | 35 +++ specs/recommend/paths/getRecommendations.yml | 68 ++++++ specs/recommend/spec.yml | 2 +- .../search/common/schemas/SearchResponse.yml | 15 +- specs/search/paths/objects/batch.yml | 2 + specs/search/paths/objects/objects.yml | 2 + specs/search/paths/search/multipleQueries.yml | 8 +- specs/search/paths/search/search.yml | 2 + specs/search/paths/settings/settings.yml | 4 + templates/javascript/api-all.mustache | 6 +- templates/javascript/api-single.mustache | 10 +- templates/javascript/api.mustache | 4 +- templates/javascript/tsconfig.mustache | 2 +- utils/recommend_spec.yml | 103 --------- utils/recommend_spec_2.yml | 109 --------- yarn.lock | 56 +++-- 102 files changed, 1994 insertions(+), 350 deletions(-) rename clients/algoliasearch-client-javascript/{ => client-search}/.gitignore (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/api.ts (66%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/baseIndexSettings.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/baseSearchParams.ts (100%) create mode 100644 clients/algoliasearch-client-javascript/client-search/model/baseSearchResponse.ts rename clients/algoliasearch-client-javascript/{model/searchResponseFacetsStats.ts => client-search/model/baseSearchResponseFacetsStats.ts} (86%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/batchObject.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/batchResponse.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/errorBase.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/highlightResult.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/indexSettings.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/indexSettingsAsSearchParams.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/models.ts (93%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/multipleQueries.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/multipleQueriesObject.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/multipleQueriesResponse.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/operation.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/rankingInfo.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/rankingInfoMatchedGeoLocation.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/record.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/saveObjectResponse.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/searchParams.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/searchParamsAsString.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/searchResponse.ts (90%) create mode 100644 clients/algoliasearch-client-javascript/client-search/model/searchResponseAllOf.ts rename clients/algoliasearch-client-javascript/{ => client-search}/model/setSettingsResponse.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/model/snippetResult.ts (100%) rename clients/algoliasearch-client-javascript/{ => client-search}/package.json (80%) rename clients/algoliasearch-client-javascript/client-search/{ => src}/apis.ts (79%) rename clients/algoliasearch-client-javascript/client-search/{ => src}/searchApi.ts (97%) rename clients/algoliasearch-client-javascript/{ => client-search}/tsconfig.json (91%) rename clients/{utils/javascript => algoliasearch-client-javascript/client-search/utils}/Cache.ts (100%) rename clients/{utils/javascript => algoliasearch-client-javascript/client-search/utils}/EchoRequester.ts (100%) rename clients/{utils/javascript => algoliasearch-client-javascript/client-search/utils}/HttpRequester.ts (100%) rename clients/{utils/javascript => algoliasearch-client-javascript/client-search/utils}/MemoryCache.ts (100%) rename clients/{utils/javascript => algoliasearch-client-javascript/client-search/utils}/Requester.ts (100%) rename clients/{utils/javascript => algoliasearch-client-javascript/client-search/utils}/Response.ts (100%) rename clients/{utils/javascript => algoliasearch-client-javascript/client-search/utils}/StatefulHost.ts (100%) rename clients/{utils/javascript => algoliasearch-client-javascript/client-search/utils}/Transporter.ts (100%) rename clients/{utils/javascript => algoliasearch-client-javascript/client-search/utils}/errors.ts (100%) rename clients/{utils/javascript => algoliasearch-client-javascript/client-search/utils}/helpers.ts (100%) rename clients/{utils/javascript => algoliasearch-client-javascript/client-search/utils}/types.ts (100%) delete mode 100644 clients/algoliasearch-client-javascript/model/searchParamsString.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/.gitignore create mode 100644 clients/algoliasearch-client-javascript/recommend/api.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/baseSearchParams.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/baseSearchResponse.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/baseSearchResponseFacetsStats.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/errorBase.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/getRecommendationsResponse.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/highlightResult.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/indexSettingsAsSearchParams.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/models.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/rankingInfo.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/rankingInfoMatchedGeoLocation.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/recommendRecord.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/recommendationRequest.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/recommendationsResponse.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/recommendationsResponseAllOf.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/model/snippetResult.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/package.json create mode 100644 clients/algoliasearch-client-javascript/recommend/src/apis.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/src/recommendApi.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/tsconfig.json create mode 100644 clients/algoliasearch-client-javascript/recommend/utils/Cache.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/utils/EchoRequester.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/utils/HttpRequester.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/utils/MemoryCache.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/utils/Requester.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/utils/Response.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/utils/StatefulHost.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/utils/Transporter.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/utils/errors.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/utils/helpers.ts create mode 100644 clients/algoliasearch-client-javascript/recommend/utils/types.ts delete mode 100644 playground/javascript/app.ts create mode 100644 playground/javascript/recommend.ts create mode 100644 playground/javascript/search.ts create mode 100644 specs/common/responses/FeatureNotEnabled.yml create mode 100644 specs/recommend/common/schemas/RecommendationsResponse.yml delete mode 100644 utils/recommend_spec.yml delete mode 100644 utils/recommend_spec_2.yml diff --git a/README.md b/README.md index 4a96094493..8007e509d9 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,26 @@ nvm use && yarn ``` -## Generate clients based on the [`spec.yml` file](./search/specs.yml) +## Generate clients based on the [`specs`](./specs/) + +### All clients + +```bash +yarn generate +``` + +### Search client ```bash yarn generate:search ``` +### Recommend client + +```bash +yarn generate:recommend +``` + ## Build generated clients ```bash diff --git a/clients/README.md b/clients/README.md index 858ad54516..a02ee6f68f 100644 --- a/clients/README.md +++ b/clients/README.md @@ -4,8 +4,11 @@ This folder hosts the generated clients and their utils. ## Generated clients -- [algoliasearch-client-javascript](./algoliasearch-client-javascript/): The Algolia JavaScript client. +### JavaScript + +- [algoliasearch](./algoliasearch-client-javascript/algoliasearch/): The Algolia search client. +- [@algolia/recommend](./algoliasearch-client-javascript/recommend/): The Algolia recommend client. ## Utils -- [JavaScript](./utils/javascript/): The Algolia JavaScript utils. +- [JavaScript](./algoliasearch-client-javascript/utils/): The JavaScript clients utils. diff --git a/clients/algoliasearch-client-javascript/.gitignore b/clients/algoliasearch-client-javascript/client-search/.gitignore similarity index 100% rename from clients/algoliasearch-client-javascript/.gitignore rename to clients/algoliasearch-client-javascript/client-search/.gitignore diff --git a/clients/algoliasearch-client-javascript/api.ts b/clients/algoliasearch-client-javascript/client-search/api.ts similarity index 66% rename from clients/algoliasearch-client-javascript/api.ts rename to clients/algoliasearch-client-javascript/client-search/api.ts index 7a39178e40..59b02c4607 100644 --- a/clients/algoliasearch-client-javascript/api.ts +++ b/clients/algoliasearch-client-javascript/client-search/api.ts @@ -1,3 +1,3 @@ // This is the entrypoint for the package -export * from './client-search/apis'; +export * from './src/apis'; export * from './model/models'; diff --git a/clients/algoliasearch-client-javascript/model/baseIndexSettings.ts b/clients/algoliasearch-client-javascript/client-search/model/baseIndexSettings.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/baseIndexSettings.ts rename to clients/algoliasearch-client-javascript/client-search/model/baseIndexSettings.ts diff --git a/clients/algoliasearch-client-javascript/model/baseSearchParams.ts b/clients/algoliasearch-client-javascript/client-search/model/baseSearchParams.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/baseSearchParams.ts rename to clients/algoliasearch-client-javascript/client-search/model/baseSearchParams.ts diff --git a/clients/algoliasearch-client-javascript/client-search/model/baseSearchResponse.ts b/clients/algoliasearch-client-javascript/client-search/model/baseSearchResponse.ts new file mode 100644 index 0000000000..8decb4bc32 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-search/model/baseSearchResponse.ts @@ -0,0 +1,100 @@ +import { BaseSearchResponseFacetsStats } from './baseSearchResponseFacetsStats'; + +export type BaseSearchResponse = { + /** + * If a search encounters an index that is being A/B tested, abTestID reports the ongoing A/B test ID. + */ + abTestID?: number; + /** + * If a search encounters an index that is being A/B tested, abTestVariantID reports the variant ID of the index used. + */ + abTestVariantID?: number; + /** + * The computed geo location. + */ + aroundLatLng?: string; + /** + * The automatically computed radius. For legacy reasons, this parameter is a string and not an integer. + */ + automaticRadius?: string; + /** + * Whether the facet count is exhaustive or approximate. + */ + exhaustiveFacetsCount?: boolean; + /** + * Indicate if the nbHits count was exhaustive or approximate + */ + exhaustiveNbHits: boolean; + /** + * Indicate if the typo-tolerence search was exhaustive or approximate (only included when typo-tolerance is enabled) + */ + exhaustiveTypo: boolean; + /** + * A mapping of each facet name to the corresponding facet counts. + */ + facets?: { [key: string]: { [key: string]: string } }; + /** + * Statistics for numerical facets. + */ + facets_stats?: { [key: string]: BaseSearchResponseFacetsStats }; + /** + * Set the number of hits per page. + */ + hitsPerPage: number; + /** + * Index name used for the query. + */ + index?: string; + /** + * Index name used for the query. In the case of an A/B test, the targeted index isn’t always the index used by the query. + */ + indexUsed?: string; + /** + * Used to return warnings about the query. + */ + message?: string; + /** + * Number of hits that the search query matched + */ + nbHits: number; + /** + * Number of pages available for the current query + */ + nbPages: number; + /** + * The number of hits selected and sorted by the relevant sort algorithm + */ + nbSortedHits?: number; + /** + * Specify the page to retrieve. + */ + page: number; + /** + * A url-encoded string of all search parameters. + */ + params: string; + /** + * The query string that will be searched, after normalization. + */ + parsedQuery?: string; + /** + * Time the server took to process the request, in milliseconds. + */ + processingTimeMS: number; + /** + * The text to search in the index. + */ + query: string; + /** + * A markup text indicating which parts of the original query have been removed in order to retrieve a non-empty result set. + */ + queryAfterRemoval?: string; + /** + * Actual host name of the server that processed the request. + */ + serverUsed?: string; + /** + * Lets you store custom data in your indices. + */ + userData?: { [key: string]: object }; +}; diff --git a/clients/algoliasearch-client-javascript/model/searchResponseFacetsStats.ts b/clients/algoliasearch-client-javascript/client-search/model/baseSearchResponseFacetsStats.ts similarity index 86% rename from clients/algoliasearch-client-javascript/model/searchResponseFacetsStats.ts rename to clients/algoliasearch-client-javascript/client-search/model/baseSearchResponseFacetsStats.ts index f72bd39467..4c4ceb7bc7 100644 --- a/clients/algoliasearch-client-javascript/model/searchResponseFacetsStats.ts +++ b/clients/algoliasearch-client-javascript/client-search/model/baseSearchResponseFacetsStats.ts @@ -1,4 +1,4 @@ -export type SearchResponseFacetsStats = { +export type BaseSearchResponseFacetsStats = { /** * The minimum value in the result set. */ diff --git a/clients/algoliasearch-client-javascript/model/batchObject.ts b/clients/algoliasearch-client-javascript/client-search/model/batchObject.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/batchObject.ts rename to clients/algoliasearch-client-javascript/client-search/model/batchObject.ts diff --git a/clients/algoliasearch-client-javascript/model/batchResponse.ts b/clients/algoliasearch-client-javascript/client-search/model/batchResponse.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/batchResponse.ts rename to clients/algoliasearch-client-javascript/client-search/model/batchResponse.ts diff --git a/clients/algoliasearch-client-javascript/model/errorBase.ts b/clients/algoliasearch-client-javascript/client-search/model/errorBase.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/errorBase.ts rename to clients/algoliasearch-client-javascript/client-search/model/errorBase.ts diff --git a/clients/algoliasearch-client-javascript/model/highlightResult.ts b/clients/algoliasearch-client-javascript/client-search/model/highlightResult.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/highlightResult.ts rename to clients/algoliasearch-client-javascript/client-search/model/highlightResult.ts diff --git a/clients/algoliasearch-client-javascript/model/indexSettings.ts b/clients/algoliasearch-client-javascript/client-search/model/indexSettings.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/indexSettings.ts rename to clients/algoliasearch-client-javascript/client-search/model/indexSettings.ts diff --git a/clients/algoliasearch-client-javascript/model/indexSettingsAsSearchParams.ts b/clients/algoliasearch-client-javascript/client-search/model/indexSettingsAsSearchParams.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/indexSettingsAsSearchParams.ts rename to clients/algoliasearch-client-javascript/client-search/model/indexSettingsAsSearchParams.ts diff --git a/clients/algoliasearch-client-javascript/model/models.ts b/clients/algoliasearch-client-javascript/client-search/model/models.ts similarity index 93% rename from clients/algoliasearch-client-javascript/model/models.ts rename to clients/algoliasearch-client-javascript/client-search/model/models.ts index 7cce6a697d..3926b480b3 100644 --- a/clients/algoliasearch-client-javascript/model/models.ts +++ b/clients/algoliasearch-client-javascript/client-search/model/models.ts @@ -2,6 +2,8 @@ import type { RequestOptions } from '../utils/types'; export * from './baseIndexSettings'; export * from './baseSearchParams'; +export * from './baseSearchResponse'; +export * from './baseSearchResponseFacetsStats'; export * from './batchObject'; export * from './batchResponse'; export * from './errorBase'; @@ -19,7 +21,7 @@ export * from './saveObjectResponse'; export * from './searchParams'; export * from './searchParamsAsString'; export * from './searchResponse'; -export * from './searchResponseFacetsStats'; +export * from './searchResponseAllOf'; export * from './setSettingsResponse'; export * from './snippetResult'; diff --git a/clients/algoliasearch-client-javascript/model/multipleQueries.ts b/clients/algoliasearch-client-javascript/client-search/model/multipleQueries.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/multipleQueries.ts rename to clients/algoliasearch-client-javascript/client-search/model/multipleQueries.ts diff --git a/clients/algoliasearch-client-javascript/model/multipleQueriesObject.ts b/clients/algoliasearch-client-javascript/client-search/model/multipleQueriesObject.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/multipleQueriesObject.ts rename to clients/algoliasearch-client-javascript/client-search/model/multipleQueriesObject.ts diff --git a/clients/algoliasearch-client-javascript/model/multipleQueriesResponse.ts b/clients/algoliasearch-client-javascript/client-search/model/multipleQueriesResponse.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/multipleQueriesResponse.ts rename to clients/algoliasearch-client-javascript/client-search/model/multipleQueriesResponse.ts diff --git a/clients/algoliasearch-client-javascript/model/operation.ts b/clients/algoliasearch-client-javascript/client-search/model/operation.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/operation.ts rename to clients/algoliasearch-client-javascript/client-search/model/operation.ts diff --git a/clients/algoliasearch-client-javascript/model/rankingInfo.ts b/clients/algoliasearch-client-javascript/client-search/model/rankingInfo.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/rankingInfo.ts rename to clients/algoliasearch-client-javascript/client-search/model/rankingInfo.ts diff --git a/clients/algoliasearch-client-javascript/model/rankingInfoMatchedGeoLocation.ts b/clients/algoliasearch-client-javascript/client-search/model/rankingInfoMatchedGeoLocation.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/rankingInfoMatchedGeoLocation.ts rename to clients/algoliasearch-client-javascript/client-search/model/rankingInfoMatchedGeoLocation.ts diff --git a/clients/algoliasearch-client-javascript/model/record.ts b/clients/algoliasearch-client-javascript/client-search/model/record.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/record.ts rename to clients/algoliasearch-client-javascript/client-search/model/record.ts diff --git a/clients/algoliasearch-client-javascript/model/saveObjectResponse.ts b/clients/algoliasearch-client-javascript/client-search/model/saveObjectResponse.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/saveObjectResponse.ts rename to clients/algoliasearch-client-javascript/client-search/model/saveObjectResponse.ts diff --git a/clients/algoliasearch-client-javascript/model/searchParams.ts b/clients/algoliasearch-client-javascript/client-search/model/searchParams.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/searchParams.ts rename to clients/algoliasearch-client-javascript/client-search/model/searchParams.ts diff --git a/clients/algoliasearch-client-javascript/model/searchParamsAsString.ts b/clients/algoliasearch-client-javascript/client-search/model/searchParamsAsString.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/searchParamsAsString.ts rename to clients/algoliasearch-client-javascript/client-search/model/searchParamsAsString.ts diff --git a/clients/algoliasearch-client-javascript/model/searchResponse.ts b/clients/algoliasearch-client-javascript/client-search/model/searchResponse.ts similarity index 90% rename from clients/algoliasearch-client-javascript/model/searchResponse.ts rename to clients/algoliasearch-client-javascript/client-search/model/searchResponse.ts index 8e848b306a..0e1dceb493 100644 --- a/clients/algoliasearch-client-javascript/model/searchResponse.ts +++ b/clients/algoliasearch-client-javascript/client-search/model/searchResponse.ts @@ -1,5 +1,7 @@ +import { BaseSearchResponse } from './baseSearchResponse'; +import { BaseSearchResponseFacetsStats } from './baseSearchResponseFacetsStats'; import { Record } from './record'; -import { SearchResponseFacetsStats } from './searchResponseFacetsStats'; +import { SearchResponseAllOf } from './searchResponseAllOf'; export type SearchResponse = { /** @@ -37,8 +39,7 @@ export type SearchResponse = { /** * Statistics for numerical facets. */ - facets_stats?: { [key: string]: SearchResponseFacetsStats }; - hits: Array; + facets_stats?: { [key: string]: BaseSearchResponseFacetsStats }; /** * Set the number of hits per page. */ @@ -99,4 +100,5 @@ export type SearchResponse = { * Lets you store custom data in your indices. */ userData?: { [key: string]: object }; + hits: Array; }; diff --git a/clients/algoliasearch-client-javascript/client-search/model/searchResponseAllOf.ts b/clients/algoliasearch-client-javascript/client-search/model/searchResponseAllOf.ts new file mode 100644 index 0000000000..a6ed511451 --- /dev/null +++ b/clients/algoliasearch-client-javascript/client-search/model/searchResponseAllOf.ts @@ -0,0 +1,5 @@ +import { Record } from './record'; + +export type SearchResponseAllOf = { + hits?: Array; +}; diff --git a/clients/algoliasearch-client-javascript/model/setSettingsResponse.ts b/clients/algoliasearch-client-javascript/client-search/model/setSettingsResponse.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/setSettingsResponse.ts rename to clients/algoliasearch-client-javascript/client-search/model/setSettingsResponse.ts diff --git a/clients/algoliasearch-client-javascript/model/snippetResult.ts b/clients/algoliasearch-client-javascript/client-search/model/snippetResult.ts similarity index 100% rename from clients/algoliasearch-client-javascript/model/snippetResult.ts rename to clients/algoliasearch-client-javascript/client-search/model/snippetResult.ts diff --git a/clients/algoliasearch-client-javascript/package.json b/clients/algoliasearch-client-javascript/client-search/package.json similarity index 80% rename from clients/algoliasearch-client-javascript/package.json rename to clients/algoliasearch-client-javascript/client-search/package.json index 3b848f601d..17b92d16aa 100644 --- a/clients/algoliasearch-client-javascript/package.json +++ b/clients/algoliasearch-client-javascript/client-search/package.json @@ -1,7 +1,7 @@ { - "name": "algoliasearch-client-javascript", + "name": "@algolia/client-search", "version": "5.0.0", - "description": "JavaScript client for algoliasearch-client-javascript", + "description": "JavaScript client for @algolia/client-search", "repository": "algolia/algoliasearch-client-javascript", "author": "Algolia", "private": true, diff --git a/clients/algoliasearch-client-javascript/client-search/apis.ts b/clients/algoliasearch-client-javascript/client-search/src/apis.ts similarity index 79% rename from clients/algoliasearch-client-javascript/client-search/apis.ts rename to clients/algoliasearch-client-javascript/client-search/src/apis.ts index c69231a7b7..28afda58ea 100644 --- a/clients/algoliasearch-client-javascript/client-search/apis.ts +++ b/clients/algoliasearch-client-javascript/client-search/src/apis.ts @@ -1,9 +1,7 @@ export * from './searchApi'; import { SearchApi } from './searchApi'; - -export class searchClient extends SearchApi {} - export * from '../utils/errors'; export { EchoRequester } from '../utils/EchoRequester'; +export class SearchApiClient extends SearchApi {} export const APIS = [SearchApi]; diff --git a/clients/algoliasearch-client-javascript/client-search/searchApi.ts b/clients/algoliasearch-client-javascript/client-search/src/searchApi.ts similarity index 97% rename from clients/algoliasearch-client-javascript/client-search/searchApi.ts rename to clients/algoliasearch-client-javascript/client-search/src/searchApi.ts index 53fd9dec84..187a9d7fde 100644 --- a/clients/algoliasearch-client-javascript/client-search/searchApi.ts +++ b/clients/algoliasearch-client-javascript/client-search/src/searchApi.ts @@ -16,7 +16,7 @@ import { SearchResponse } from '../model/searchResponse'; import { SetSettingsResponse } from '../model/setSettingsResponse'; import { ApiKeyAuth } from '../model/models'; -export enum SearchApiApiKeys { +export enum SearchApiKeys { apiKey, appId, } @@ -30,8 +30,8 @@ export class SearchApi { }; constructor(appId: string, apiKey: string, requester?: Requester) { - this.setApiKey(SearchApiApiKeys.appId, appId); - this.setApiKey(SearchApiApiKeys.apiKey, apiKey); + this.setApiKey(SearchApiKeys.appId, appId); + this.setApiKey(SearchApiKeys.apiKey, apiKey); this.transporter = new Transporter({ hosts: ( [ @@ -58,8 +58,8 @@ export class SearchApi { }); } - public setApiKey(key: SearchApiApiKeys, value: string) { - this.authentications[SearchApiApiKeys[key]].apiKey = value; + public setApiKey(key: SearchApiKeys, value: string) { + this.authentications[SearchApiKeys[key]].apiKey = value; } private async sendRequest( diff --git a/clients/algoliasearch-client-javascript/tsconfig.json b/clients/algoliasearch-client-javascript/client-search/tsconfig.json similarity index 91% rename from clients/algoliasearch-client-javascript/tsconfig.json rename to clients/algoliasearch-client-javascript/client-search/tsconfig.json index f10927b181..2f72c93ccb 100644 --- a/clients/algoliasearch-client-javascript/tsconfig.json +++ b/clients/algoliasearch-client-javascript/client-search/tsconfig.json @@ -17,6 +17,6 @@ "typeRoots": ["node_modules/@types"], "types": ["node"] }, - "include": ["client-search", "model", "api.ts"], + "include": ["src", "model", "api.ts"], "exclude": ["dist", "node_modules"] } diff --git a/clients/utils/javascript/Cache.ts b/clients/algoliasearch-client-javascript/client-search/utils/Cache.ts similarity index 100% rename from clients/utils/javascript/Cache.ts rename to clients/algoliasearch-client-javascript/client-search/utils/Cache.ts diff --git a/clients/utils/javascript/EchoRequester.ts b/clients/algoliasearch-client-javascript/client-search/utils/EchoRequester.ts similarity index 100% rename from clients/utils/javascript/EchoRequester.ts rename to clients/algoliasearch-client-javascript/client-search/utils/EchoRequester.ts diff --git a/clients/utils/javascript/HttpRequester.ts b/clients/algoliasearch-client-javascript/client-search/utils/HttpRequester.ts similarity index 100% rename from clients/utils/javascript/HttpRequester.ts rename to clients/algoliasearch-client-javascript/client-search/utils/HttpRequester.ts diff --git a/clients/utils/javascript/MemoryCache.ts b/clients/algoliasearch-client-javascript/client-search/utils/MemoryCache.ts similarity index 100% rename from clients/utils/javascript/MemoryCache.ts rename to clients/algoliasearch-client-javascript/client-search/utils/MemoryCache.ts diff --git a/clients/utils/javascript/Requester.ts b/clients/algoliasearch-client-javascript/client-search/utils/Requester.ts similarity index 100% rename from clients/utils/javascript/Requester.ts rename to clients/algoliasearch-client-javascript/client-search/utils/Requester.ts diff --git a/clients/utils/javascript/Response.ts b/clients/algoliasearch-client-javascript/client-search/utils/Response.ts similarity index 100% rename from clients/utils/javascript/Response.ts rename to clients/algoliasearch-client-javascript/client-search/utils/Response.ts diff --git a/clients/utils/javascript/StatefulHost.ts b/clients/algoliasearch-client-javascript/client-search/utils/StatefulHost.ts similarity index 100% rename from clients/utils/javascript/StatefulHost.ts rename to clients/algoliasearch-client-javascript/client-search/utils/StatefulHost.ts diff --git a/clients/utils/javascript/Transporter.ts b/clients/algoliasearch-client-javascript/client-search/utils/Transporter.ts similarity index 100% rename from clients/utils/javascript/Transporter.ts rename to clients/algoliasearch-client-javascript/client-search/utils/Transporter.ts diff --git a/clients/utils/javascript/errors.ts b/clients/algoliasearch-client-javascript/client-search/utils/errors.ts similarity index 100% rename from clients/utils/javascript/errors.ts rename to clients/algoliasearch-client-javascript/client-search/utils/errors.ts diff --git a/clients/utils/javascript/helpers.ts b/clients/algoliasearch-client-javascript/client-search/utils/helpers.ts similarity index 100% rename from clients/utils/javascript/helpers.ts rename to clients/algoliasearch-client-javascript/client-search/utils/helpers.ts diff --git a/clients/utils/javascript/types.ts b/clients/algoliasearch-client-javascript/client-search/utils/types.ts similarity index 100% rename from clients/utils/javascript/types.ts rename to clients/algoliasearch-client-javascript/client-search/utils/types.ts diff --git a/clients/algoliasearch-client-javascript/model/searchParamsString.ts b/clients/algoliasearch-client-javascript/model/searchParamsString.ts deleted file mode 100644 index e0858af48a..0000000000 --- a/clients/algoliasearch-client-javascript/model/searchParamsString.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type SearchParamsString = { - params?: string; -}; diff --git a/clients/algoliasearch-client-javascript/recommend/.gitignore b/clients/algoliasearch-client-javascript/recommend/.gitignore new file mode 100644 index 0000000000..b3a5f6266d --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/.gitignore @@ -0,0 +1,6 @@ +node_modules +typings +dist +build +.env +.vscode \ No newline at end of file diff --git a/clients/algoliasearch-client-javascript/recommend/api.ts b/clients/algoliasearch-client-javascript/recommend/api.ts new file mode 100644 index 0000000000..59b02c4607 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/api.ts @@ -0,0 +1,3 @@ +// This is the entrypoint for the package +export * from './src/apis'; +export * from './model/models'; diff --git a/clients/algoliasearch-client-javascript/recommend/model/baseSearchParams.ts b/clients/algoliasearch-client-javascript/recommend/model/baseSearchParams.ts new file mode 100644 index 0000000000..4bedbadf18 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/baseSearchParams.ts @@ -0,0 +1,134 @@ +export type BaseSearchParams = { + /** + * The text to search in the index. + */ + query: string; + /** + * Overrides the query parameter and performs a more generic search that can be used to find \"similar\" results. + */ + similarQuery?: string; + /** + * Filter the query with numeric, facet and/or tag filters. + */ + filters?: string; + /** + * Filter hits by facet value. + */ + facetFilters?: Array; + /** + * Create filters for ranking purposes, where records that match the filter are ranked higher, or lower in the case of a negative optional filter. + */ + optionalFilters?: Array; + /** + * Filter on numeric attributes. + */ + numericFilters?: Array; + /** + * Filter hits by tags. + */ + tagFilters?: Array; + /** + * Determines how to calculate the total score for filtering. + */ + sumOrFiltersScores?: boolean; + /** + * Retrieve facets and their facet values. + */ + facets?: Array; + /** + * Maximum number of facet values to return for each facet during a regular search. + */ + maxValuesPerFacet?: number; + /** + * Force faceting to be applied after de-duplication (via the Distinct setting). + */ + facetingAfterDistinct?: boolean; + /** + * Controls how facet values are fetched. + */ + sortFacetValuesBy?: string; + /** + * Specify the page to retrieve. + */ + page?: number; + /** + * Specify the offset of the first hit to return. + */ + offset?: number; + /** + * Set the number of hits to retrieve (used only with offset). + */ + length?: number; + /** + * Search for entries around a central geolocation, enabling a geo search within a circular area. + */ + aroundLatLng?: string; + /** + * Search for entries around a given location automatically computed from the requester’s IP address. + */ + aroundLatLngViaIP?: boolean; + /** + * Define the maximum radius for a geo search (in meters). + */ + aroundRadius?: number | string | null; + /** + * Precision of geo search (in meters), to add grouping by geo location to the ranking formula. + */ + aroundPrecision?: number; + /** + * Minimum radius (in meters) used for a geo search when aroundRadius is not set. + */ + minimumAroundRadius?: number; + /** + * Search inside a rectangular area (in geo coordinates). + */ + insideBoundingBox?: Array; + /** + * Search inside a polygon (in geo coordinates). + */ + insidePolygon?: Array; + /** + * This parameter changes the default values of certain parameters and settings that work best for a natural language query, such as ignorePlurals, removeStopWords, removeWordsIfNoResults, analyticsTags and ruleContexts. These parameters and settings work well together when the query is formatted in natural language instead of keywords, for example when your user performs a voice search. + */ + naturalLanguages?: Array; + /** + * Enables contextual rules. + */ + ruleContexts?: Array; + /** + * Define the impact of the Personalization feature. + */ + personalizationImpact?: number; + /** + * Associates a certain user token with the current search. + */ + userToken?: string; + /** + * Retrieve detailed ranking information. + */ + getRankingInfo?: boolean; + /** + * Enable the Click Analytics feature. + */ + clickAnalytics?: boolean; + /** + * Whether the current query will be taken into account in the Analytics. + */ + analytics?: boolean; + /** + * List of tags to apply to the query for analytics purposes. + */ + analyticsTags?: Array; + /** + * Whether to include or exclude a query from the processing-time percentile computation. + */ + percentileComputation?: boolean; + /** + * Whether this search should participate in running AB tests. + */ + enableABTest?: boolean; + /** + * Whether this search should use AI Re-Ranking. + */ + enableReRanking?: boolean; +}; diff --git a/clients/algoliasearch-client-javascript/recommend/model/baseSearchResponse.ts b/clients/algoliasearch-client-javascript/recommend/model/baseSearchResponse.ts new file mode 100644 index 0000000000..8decb4bc32 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/baseSearchResponse.ts @@ -0,0 +1,100 @@ +import { BaseSearchResponseFacetsStats } from './baseSearchResponseFacetsStats'; + +export type BaseSearchResponse = { + /** + * If a search encounters an index that is being A/B tested, abTestID reports the ongoing A/B test ID. + */ + abTestID?: number; + /** + * If a search encounters an index that is being A/B tested, abTestVariantID reports the variant ID of the index used. + */ + abTestVariantID?: number; + /** + * The computed geo location. + */ + aroundLatLng?: string; + /** + * The automatically computed radius. For legacy reasons, this parameter is a string and not an integer. + */ + automaticRadius?: string; + /** + * Whether the facet count is exhaustive or approximate. + */ + exhaustiveFacetsCount?: boolean; + /** + * Indicate if the nbHits count was exhaustive or approximate + */ + exhaustiveNbHits: boolean; + /** + * Indicate if the typo-tolerence search was exhaustive or approximate (only included when typo-tolerance is enabled) + */ + exhaustiveTypo: boolean; + /** + * A mapping of each facet name to the corresponding facet counts. + */ + facets?: { [key: string]: { [key: string]: string } }; + /** + * Statistics for numerical facets. + */ + facets_stats?: { [key: string]: BaseSearchResponseFacetsStats }; + /** + * Set the number of hits per page. + */ + hitsPerPage: number; + /** + * Index name used for the query. + */ + index?: string; + /** + * Index name used for the query. In the case of an A/B test, the targeted index isn’t always the index used by the query. + */ + indexUsed?: string; + /** + * Used to return warnings about the query. + */ + message?: string; + /** + * Number of hits that the search query matched + */ + nbHits: number; + /** + * Number of pages available for the current query + */ + nbPages: number; + /** + * The number of hits selected and sorted by the relevant sort algorithm + */ + nbSortedHits?: number; + /** + * Specify the page to retrieve. + */ + page: number; + /** + * A url-encoded string of all search parameters. + */ + params: string; + /** + * The query string that will be searched, after normalization. + */ + parsedQuery?: string; + /** + * Time the server took to process the request, in milliseconds. + */ + processingTimeMS: number; + /** + * The text to search in the index. + */ + query: string; + /** + * A markup text indicating which parts of the original query have been removed in order to retrieve a non-empty result set. + */ + queryAfterRemoval?: string; + /** + * Actual host name of the server that processed the request. + */ + serverUsed?: string; + /** + * Lets you store custom data in your indices. + */ + userData?: { [key: string]: object }; +}; diff --git a/clients/algoliasearch-client-javascript/recommend/model/baseSearchResponseFacetsStats.ts b/clients/algoliasearch-client-javascript/recommend/model/baseSearchResponseFacetsStats.ts new file mode 100644 index 0000000000..4c4ceb7bc7 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/baseSearchResponseFacetsStats.ts @@ -0,0 +1,18 @@ +export type BaseSearchResponseFacetsStats = { + /** + * The minimum value in the result set. + */ + min?: number; + /** + * The maximum value in the result set. + */ + max?: number; + /** + * The average facet value in the result set. + */ + avg?: number; + /** + * The sum of all values in the result set. + */ + sum?: number; +}; diff --git a/clients/algoliasearch-client-javascript/recommend/model/errorBase.ts b/clients/algoliasearch-client-javascript/recommend/model/errorBase.ts new file mode 100644 index 0000000000..d5b7c95506 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/errorBase.ts @@ -0,0 +1,6 @@ +/** + * Error + */ +export type ErrorBase = { + message?: string; +}; diff --git a/clients/algoliasearch-client-javascript/recommend/model/getRecommendationsResponse.ts b/clients/algoliasearch-client-javascript/recommend/model/getRecommendationsResponse.ts new file mode 100644 index 0000000000..b77b3e0646 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/getRecommendationsResponse.ts @@ -0,0 +1,5 @@ +import { RecommendationsResponse } from './recommendationsResponse'; + +export type GetRecommendationsResponse = { + results?: Array; +}; diff --git a/clients/algoliasearch-client-javascript/recommend/model/highlightResult.ts b/clients/algoliasearch-client-javascript/recommend/model/highlightResult.ts new file mode 100644 index 0000000000..7955038cba --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/highlightResult.ts @@ -0,0 +1,26 @@ +export type HighlightResult = { + /** + * Markup text with occurrences highlighted. + */ + value?: string; + /** + * Indicates how well the attribute matched the search query. + */ + matchLevel?: HighlightResult.MatchLevelEnum; + /** + * List of words from the query that matched the object. + */ + matchedWords?: Array; + /** + * Whether the entire attribute value is highlighted. + */ + fullyHighlighted?: boolean; +}; + +export namespace HighlightResult { + export enum MatchLevelEnum { + None = 'none', + Partial = 'partial', + Full = 'full', + } +} diff --git a/clients/algoliasearch-client-javascript/recommend/model/indexSettingsAsSearchParams.ts b/clients/algoliasearch-client-javascript/recommend/model/indexSettingsAsSearchParams.ts new file mode 100644 index 0000000000..8f65866f9b --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/indexSettingsAsSearchParams.ts @@ -0,0 +1,212 @@ +export type IndexSettingsAsSearchParams = { + /** + * The complete list of attributes used for searching. + */ + searchableAttributes?: Array; + /** + * The complete list of attributes that will be used for faceting. + */ + attributesForFaceting?: Array; + /** + * List of attributes that can’t be retrieved at query time. + */ + unretrievableAttributes?: Array; + /** + * This parameter controls which attributes to retrieve and which not to retrieve. + */ + attributesToRetrieve?: Array; + /** + * Restricts a given query to look in only a subset of your searchable attributes. + */ + restrictSearchableAttributes?: Array; + /** + * Controls how Algolia should sort your results. + */ + ranking?: Array; + /** + * Specifies the custom ranking criterion. + */ + customRanking?: Array; + /** + * Controls the relevancy threshold below which less relevant results aren’t included in the results. + */ + relevancyStrictness?: number; + /** + * List of attributes to highlight. + */ + attributesToHighlight?: Array; + /** + * List of attributes to snippet, with an optional maximum number of words to snippet. + */ + attributesToSnippet?: Array; + /** + * The HTML string to insert before the highlighted parts in all highlight and snippet results. + */ + highlightPreTag?: string; + /** + * The HTML string to insert after the highlighted parts in all highlight and snippet results. + */ + highlightPostTag?: string; + /** + * String used as an ellipsis indicator when a snippet is truncated. + */ + snippetEllipsisText?: string; + /** + * Restrict highlighting and snippeting to items that matched the query. + */ + restrictHighlightAndSnippetArrays?: boolean; + /** + * Set the number of hits per page. + */ + hitsPerPage?: number; + /** + * Minimum number of characters a word in the query string must contain to accept matches with 1 typo. + */ + minWordSizefor1Typo?: number; + /** + * Minimum number of characters a word in the query string must contain to accept matches with 2 typos. + */ + minWordSizefor2Typos?: number; + /** + * Controls whether typo tolerance is enabled and how it is applied. + */ + typoTolerance?: IndexSettingsAsSearchParams.TypoToleranceEnum; + /** + * Whether to allow typos on numbers (“numeric tokens”) in the query string. + */ + allowTyposOnNumericTokens?: boolean; + /** + * List of attributes on which you want to disable typo tolerance. + */ + disableTypoToleranceOnAttributes?: Array; + /** + * Control which separators are indexed. + */ + separatorsToIndex?: string; + /** + * Treats singular, plurals, and other forms of declensions as matching terms. + */ + ignorePlurals?: string; + /** + * Removes stop (common) words from the query before executing it. + */ + removeStopWords?: string; + /** + * List of characters that the engine shouldn’t automatically normalize. + */ + keepDiacriticsOnCharacters?: string; + /** + * Sets the languages to be used by language-specific settings and functionalities such as ignorePlurals, removeStopWords, and CJK word-detection. + */ + queryLanguages?: Array; + /** + * Splits compound words into their composing atoms in the query. + */ + decompoundQuery?: boolean; + /** + * Whether Rules should be globally enabled. + */ + enableRules?: boolean; + /** + * Enable the Personalization feature. + */ + enablePersonalization?: boolean; + /** + * Controls if and how query words are interpreted as prefixes. + */ + queryType?: IndexSettingsAsSearchParams.QueryTypeEnum; + /** + * Selects a strategy to remove words from the query when it doesn’t match any hits. + */ + removeWordsIfNoResults?: IndexSettingsAsSearchParams.RemoveWordsIfNoResultsEnum; + /** + * Enables the advanced query syntax. + */ + advancedSyntax?: boolean; + /** + * A list of words that should be considered as optional when found in the query. + */ + optionalWords?: Array; + /** + * List of attributes on which you want to disable the exact ranking criterion. + */ + disableExactOnAttributes?: Array; + /** + * Controls how the exact ranking criterion is computed when the query contains only one word. + */ + exactOnSingleWordQuery?: IndexSettingsAsSearchParams.ExactOnSingleWordQueryEnum; + /** + * List of alternatives that should be considered an exact match by the exact ranking criterion. + */ + alternativesAsExact?: Array; + /** + * Allows you to specify which advanced syntax features are active when ‘advancedSyntax’ is enabled. + */ + advancedSyntaxFeatures?: Array; + /** + * Enables de-duplication or grouping of results. + */ + distinct?: number; + /** + * Whether to take into account an index’s synonyms for a particular search. + */ + synonyms?: boolean; + /** + * Whether to highlight and snippet the original word that matches the synonym or the synonym itself. + */ + replaceSynonymsInHighlight?: boolean; + /** + * Precision of the proximity ranking criterion. + */ + minProximity?: number; + /** + * Choose which fields to return in the API response. This parameters applies to search and browse queries. + */ + responseFields?: Array; + /** + * Maximum number of facet hits to return during a search for facet values. + */ + maxFacetHits?: number; + /** + * When attribute is ranked above proximity in your ranking formula, proximity is used to select which searchable attribute is matched in the attribute ranking stage. + */ + attributeCriteriaComputedByMinProximity?: boolean; + /** + * Content defining how the search interface should be rendered. Can be set via the settings for a default value and can be overridden via rules. + */ + renderingContent?: object; +}; + +export namespace IndexSettingsAsSearchParams { + export enum TypoToleranceEnum { + True = 'true', + False = 'false', + Min = 'min', + Strict = 'strict', + } + export enum QueryTypeEnum { + PrefixLast = 'prefixLast', + PrefixAll = 'prefixAll', + PrefixNone = 'prefixNone', + } + export enum RemoveWordsIfNoResultsEnum { + None = 'none', + LastWords = 'lastWords', + FirstWords = 'firstWords', + AllOptional = 'allOptional', + } + export enum ExactOnSingleWordQueryEnum { + Attribute = 'attribute', + None = 'none', + Word = 'word', + } + export enum AlternativesAsExactEnum { + IgnorePlurals = 'ignorePlurals', + SingleWordSynonym = 'singleWordSynonym', + MultiWordsSynonym = 'multiWordsSynonym', + } + export enum AdvancedSyntaxFeaturesEnum { + ExactPhrase = 'exactPhrase', + ExcludeWords = 'excludeWords', + } +} diff --git a/clients/algoliasearch-client-javascript/recommend/model/models.ts b/clients/algoliasearch-client-javascript/recommend/model/models.ts new file mode 100644 index 0000000000..3610262bf6 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/models.ts @@ -0,0 +1,44 @@ +import type { RequestOptions } from '../utils/types'; + +export * from './baseSearchParams'; +export * from './baseSearchResponse'; +export * from './baseSearchResponseFacetsStats'; +export * from './errorBase'; +export * from './getRecommendationsResponse'; +export * from './highlightResult'; +export * from './indexSettingsAsSearchParams'; +export * from './rankingInfo'; +export * from './rankingInfoMatchedGeoLocation'; +export * from './recommendRecord'; +export * from './recommendationRequest'; +export * from './recommendationsResponse'; +export * from './recommendationsResponseAllOf'; +export * from './snippetResult'; + +export interface Authentication { + /** + * Apply authentication settings to header and query params. + */ + applyToRequest(requestOptions: RequestOptions): Promise | void; +} + +export class ApiKeyAuth implements Authentication { + public apiKey: string = ''; + + constructor(private location: string, private paramName: string) {} + + applyToRequest(requestOptions: RequestOptions): void { + if (this.location == 'query') { + requestOptions.queryParameters[this.paramName] = this.apiKey; + } else if (this.location == 'header' && requestOptions && requestOptions.headers) { + requestOptions.headers[this.paramName] = this.apiKey; + } else if (this.location == 'cookie' && requestOptions && requestOptions.headers) { + if (requestOptions.headers['Cookie']) { + requestOptions.headers['Cookie'] += + '; ' + this.paramName + '=' + encodeURIComponent(this.apiKey); + } else { + requestOptions.headers['Cookie'] = this.paramName + '=' + encodeURIComponent(this.apiKey); + } + } + } +} diff --git a/clients/algoliasearch-client-javascript/recommend/model/rankingInfo.ts b/clients/algoliasearch-client-javascript/recommend/model/rankingInfo.ts new file mode 100644 index 0000000000..0b163f3302 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/rankingInfo.ts @@ -0,0 +1,45 @@ +import { RankingInfoMatchedGeoLocation } from './rankingInfoMatchedGeoLocation'; + +export type RankingInfo = { + /** + * This field is reserved for advanced usage. + */ + filters?: number; + /** + * Position of the most important matched attribute in the attributes to index list. + */ + firstMatchedWord?: number; + /** + * Distance between the geo location in the search query and the best matching geo location in the record, divided by the geo precision (in meters). + */ + geoDistance?: number; + /** + * Precision used when computing the geo distance, in meters. + */ + geoPrecision?: number; + matchedGeoLocation?: { [key: string]: RankingInfoMatchedGeoLocation }; + /** + * Number of exactly matched words. + */ + nbExactWords?: number; + /** + * Number of typos encountered when matching the record. + */ + nbTypos?: number; + /** + * Present and set to true if a Rule promoted the hit. + */ + promoted?: boolean; + /** + * When the query contains more than one word, the sum of the distances between matched words (in meters). + */ + proximityDistance?: number; + /** + * Custom ranking for the object, expressed as a single integer value. + */ + userScore?: number; + /** + * Number of matched words, including prefixes and typos. + */ + word?: number; +}; diff --git a/clients/algoliasearch-client-javascript/recommend/model/rankingInfoMatchedGeoLocation.ts b/clients/algoliasearch-client-javascript/recommend/model/rankingInfoMatchedGeoLocation.ts new file mode 100644 index 0000000000..bc9ce84718 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/rankingInfoMatchedGeoLocation.ts @@ -0,0 +1,14 @@ +export type RankingInfoMatchedGeoLocation = { + /** + * Latitude of the matched location. + */ + lat?: number; + /** + * Longitude of the matched location. + */ + lng?: number; + /** + * Distance between the matched location and the search location (in meters). + */ + distance?: number; +}; diff --git a/clients/algoliasearch-client-javascript/recommend/model/recommendRecord.ts b/clients/algoliasearch-client-javascript/recommend/model/recommendRecord.ts new file mode 100644 index 0000000000..451e961563 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/recommendRecord.ts @@ -0,0 +1,21 @@ +import { HighlightResult } from './highlightResult'; +import { RankingInfo } from './rankingInfo'; +import { SnippetResult } from './snippetResult'; + +/** + * A Recommend record + */ +export type RecommendRecord = { + /** + * Unique identifier of the object + */ + objectID: string; + _highlightResult?: HighlightResult; + _snippetResult?: SnippetResult; + _rankingInfo?: RankingInfo; + _distinctSeqID?: number; + /** + * The recommendation score + */ + _score: number; +}; diff --git a/clients/algoliasearch-client-javascript/recommend/model/recommendationRequest.ts b/clients/algoliasearch-client-javascript/recommend/model/recommendationRequest.ts new file mode 100644 index 0000000000..eb9b7ab6b2 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/recommendationRequest.ts @@ -0,0 +1,34 @@ +import { BaseSearchParams } from './baseSearchParams'; +import { IndexSettingsAsSearchParams } from './indexSettingsAsSearchParams'; + +export type RecommendationRequest = { + /** + * The Algolia index name + */ + indexName: string; + /** + * Unique identifier of the object + */ + objectID: string; + /** + * The recommendation model to use. + */ + model: RecommendationRequest.ModelEnum; + /** + * The threshold to use when filtering recommendations by their score. + */ + threshold: number; + /** + * The max number of recommendations to retrieve. If it’s set to 0, all the recommendations of the objectID may be returned. + */ + maxRecommendations?: number; + _queryParameters?: (BaseSearchParams & IndexSettingsAsSearchParams) | null; + fallbackParameters?: (BaseSearchParams & IndexSettingsAsSearchParams) | null; +}; + +export namespace RecommendationRequest { + export enum ModelEnum { + RelatedProducts = 'related-products', + BoughtTogether = 'bought-together', + } +} diff --git a/clients/algoliasearch-client-javascript/recommend/model/recommendationsResponse.ts b/clients/algoliasearch-client-javascript/recommend/model/recommendationsResponse.ts new file mode 100644 index 0000000000..e60147e03a --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/recommendationsResponse.ts @@ -0,0 +1,104 @@ +import { BaseSearchResponse } from './baseSearchResponse'; +import { BaseSearchResponseFacetsStats } from './baseSearchResponseFacetsStats'; +import { RecommendRecord } from './recommendRecord'; +import { RecommendationsResponseAllOf } from './recommendationsResponseAllOf'; + +export type RecommendationsResponse = { + /** + * If a search encounters an index that is being A/B tested, abTestID reports the ongoing A/B test ID. + */ + abTestID?: number; + /** + * If a search encounters an index that is being A/B tested, abTestVariantID reports the variant ID of the index used. + */ + abTestVariantID?: number; + /** + * The computed geo location. + */ + aroundLatLng?: string; + /** + * The automatically computed radius. For legacy reasons, this parameter is a string and not an integer. + */ + automaticRadius?: string; + /** + * Whether the facet count is exhaustive or approximate. + */ + exhaustiveFacetsCount?: boolean; + /** + * Indicate if the nbHits count was exhaustive or approximate + */ + exhaustiveNbHits: boolean; + /** + * Indicate if the typo-tolerence search was exhaustive or approximate (only included when typo-tolerance is enabled) + */ + exhaustiveTypo: boolean; + /** + * A mapping of each facet name to the corresponding facet counts. + */ + facets?: { [key: string]: { [key: string]: string } }; + /** + * Statistics for numerical facets. + */ + facets_stats?: { [key: string]: BaseSearchResponseFacetsStats }; + /** + * Set the number of hits per page. + */ + hitsPerPage: number; + /** + * Index name used for the query. + */ + index?: string; + /** + * Index name used for the query. In the case of an A/B test, the targeted index isn’t always the index used by the query. + */ + indexUsed?: string; + /** + * Used to return warnings about the query. + */ + message?: string; + /** + * Number of hits that the search query matched + */ + nbHits: number; + /** + * Number of pages available for the current query + */ + nbPages: number; + /** + * The number of hits selected and sorted by the relevant sort algorithm + */ + nbSortedHits?: number; + /** + * Specify the page to retrieve. + */ + page: number; + /** + * A url-encoded string of all search parameters. + */ + params: string; + /** + * The query string that will be searched, after normalization. + */ + parsedQuery?: string; + /** + * Time the server took to process the request, in milliseconds. + */ + processingTimeMS: number; + /** + * The text to search in the index. + */ + query: string; + /** + * A markup text indicating which parts of the original query have been removed in order to retrieve a non-empty result set. + */ + queryAfterRemoval?: string; + /** + * Actual host name of the server that processed the request. + */ + serverUsed?: string; + /** + * Lets you store custom data in your indices. + */ + userData?: { [key: string]: object }; + hits: Array; +}; diff --git a/clients/algoliasearch-client-javascript/recommend/model/recommendationsResponseAllOf.ts b/clients/algoliasearch-client-javascript/recommend/model/recommendationsResponseAllOf.ts new file mode 100644 index 0000000000..119a5eb5eb --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/recommendationsResponseAllOf.ts @@ -0,0 +1,5 @@ +import { RecommendRecord } from './recommendRecord'; + +export type RecommendationsResponseAllOf = { + hits?: Array; +}; diff --git a/clients/algoliasearch-client-javascript/recommend/model/snippetResult.ts b/clients/algoliasearch-client-javascript/recommend/model/snippetResult.ts new file mode 100644 index 0000000000..d4fd65bce0 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/model/snippetResult.ts @@ -0,0 +1,18 @@ +export type SnippetResult = { + /** + * Markup text with occurrences highlighted. + */ + value?: string; + /** + * Indicates how well the attribute matched the search query. + */ + matchLevel?: SnippetResult.MatchLevelEnum; +}; + +export namespace SnippetResult { + export enum MatchLevelEnum { + None = 'none', + Partial = 'partial', + Full = 'full', + } +} diff --git a/clients/algoliasearch-client-javascript/recommend/package.json b/clients/algoliasearch-client-javascript/recommend/package.json new file mode 100644 index 0000000000..f4039809b3 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/package.json @@ -0,0 +1,24 @@ +{ + "name": "@algolia/recommend", + "version": "5.0.0", + "description": "JavaScript client for @algolia/recommend", + "repository": "algolia/algoliasearch-client-javascript", + "author": "Algolia", + "private": true, + "license": "MIT", + "main": "dist/api.js", + "types": "dist/api.d.ts", + "scripts": { + "clean": "rm -Rf node_modules/ *.js", + "build": "tsc", + "test": "yarn build && node dist/client.js" + }, + "engines": { + "node": "^16.0.0", + "yarn": "^3.0.0" + }, + "devDependencies": { + "@types/node": "^16.11.6", + "typescript": "4.5.2" + } +} diff --git a/clients/algoliasearch-client-javascript/recommend/src/apis.ts b/clients/algoliasearch-client-javascript/recommend/src/apis.ts new file mode 100644 index 0000000000..a9a0c043ca --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/src/apis.ts @@ -0,0 +1,7 @@ +export * from './recommendApi'; +import { RecommendApi } from './recommendApi'; +export * from '../utils/errors'; +export { EchoRequester } from '../utils/EchoRequester'; + +export class RecommendApiClient extends RecommendApi {} +export const APIS = [RecommendApi]; diff --git a/clients/algoliasearch-client-javascript/recommend/src/recommendApi.ts b/clients/algoliasearch-client-javascript/recommend/src/recommendApi.ts new file mode 100644 index 0000000000..a475c50d6b --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/src/recommendApi.ts @@ -0,0 +1,101 @@ +import { shuffle } from '../utils/helpers'; +import { Transporter } from '../utils/Transporter'; +import { Headers, Host, Request, RequestOptions } from '../utils/types'; +import { Requester } from '../utils/Requester'; + +import { ErrorBase } from '../model/errorBase'; +import { GetRecommendationsResponse } from '../model/getRecommendationsResponse'; +import { RecommendationRequest } from '../model/recommendationRequest'; +import { ApiKeyAuth } from '../model/models'; + +export enum RecommendApiKeys { + apiKey, + appId, +} + +export class RecommendApi { + private transporter: Transporter; + + protected authentications = { + apiKey: new ApiKeyAuth('header', 'X-Algolia-API-Key'), + appId: new ApiKeyAuth('header', 'X-Algolia-Application-Id'), + }; + + constructor(appId: string, apiKey: string, requester?: Requester) { + this.setApiKey(RecommendApiKeys.appId, appId); + this.setApiKey(RecommendApiKeys.apiKey, apiKey); + this.transporter = new Transporter({ + hosts: ( + [ + { url: `${appId}-dsn.algolia.net`, accept: 'read', protocol: 'https' }, + { url: `${appId}.algolia.net`, accept: 'write', protocol: 'https' }, + ] as Host[] + ).concat( + shuffle([ + { url: `${appId}-1.algolianet.com`, accept: 'readWrite', protocol: 'https' }, + { url: `${appId}-2.algolianet.com`, accept: 'readWrite', protocol: 'https' }, + { url: `${appId}-3.algolianet.com`, accept: 'readWrite', protocol: 'https' }, + ]) + ), + baseHeaders: { + 'content-type': 'application/x-www-form-urlencoded', + }, + userAgent: 'Algolia for Javascript', + timeouts: { + connect: 2, + read: 5, + write: 30, + }, + requester, + }); + } + + public setApiKey(key: RecommendApiKeys, value: string) { + this.authentications[RecommendApiKeys[key]].apiKey = value; + } + + private async sendRequest( + request: Request, + requestOptions: RequestOptions + ): Promise { + if (this.authentications.apiKey.apiKey) { + this.authentications.apiKey.applyToRequest(requestOptions); + } + if (this.authentications.appId.apiKey) { + this.authentications.appId.applyToRequest(requestOptions); + } + return this.transporter.request(request, requestOptions); + } + + /** + * + * @summary Returns recommendations for a specific model and objectID + * @param recommendationRequest + */ + public async getRecommendations( + recommendationRequest: Array + ): Promise { + const path = '/1/indexes/*/recommendations'; + let headers: Headers = { Accept: 'application/json' }; + let queryParameters: Record = {}; + + if (recommendationRequest === null || recommendationRequest === undefined) { + throw new Error( + 'Required parameter recommendationRequest was null or undefined when calling getRecommendations.' + ); + } + + const request: Request = { + method: 'POST', + path, + data: recommendationRequest, + }; + + const requestOptions: RequestOptions = { + headers, + queryParameters, + }; + + return this.sendRequest(request, requestOptions); + } +} diff --git a/clients/algoliasearch-client-javascript/recommend/tsconfig.json b/clients/algoliasearch-client-javascript/recommend/tsconfig.json new file mode 100644 index 0000000000..2f72c93ccb --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "noImplicitAny": false, + "suppressImplicitAnyIndexErrors": true, + "target": "ES6", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "strict": true, + "moduleResolution": "node", + "removeComments": true, + "sourceMap": true, + "noLib": false, + "declaration": true, + "lib": ["dom", "es6", "es5", "dom.iterable", "scripthost"], + "outDir": "dist", + "typeRoots": ["node_modules/@types"], + "types": ["node"] + }, + "include": ["src", "model", "api.ts"], + "exclude": ["dist", "node_modules"] +} diff --git a/clients/algoliasearch-client-javascript/recommend/utils/Cache.ts b/clients/algoliasearch-client-javascript/recommend/utils/Cache.ts new file mode 100644 index 0000000000..faaa9333f8 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/utils/Cache.ts @@ -0,0 +1,21 @@ +export interface Cache { + /** + * Gets the value of the given `key`. + */ + get: (key: object | string, defaultValue: () => Promise) => Promise; + + /** + * Sets the given value with the given `key`. + */ + set: (key: object | string, value: TValue) => Promise; + + /** + * Deletes the given `key`. + */ + delete: (key: object | string) => Promise; + + /** + * Clears the cache. + */ + clear: () => Promise; +} diff --git a/clients/algoliasearch-client-javascript/recommend/utils/EchoRequester.ts b/clients/algoliasearch-client-javascript/recommend/utils/EchoRequester.ts new file mode 100644 index 0000000000..12c6cd1b25 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/utils/EchoRequester.ts @@ -0,0 +1,12 @@ +import { EndRequest, Response } from './types'; +import { Requester } from './Requester'; + +export class EchoRequester extends Requester { + async send(request: EndRequest): Promise { + return { + content: JSON.stringify(request), + isTimedOut: false, + status: 200, + }; + } +} diff --git a/clients/algoliasearch-client-javascript/recommend/utils/HttpRequester.ts b/clients/algoliasearch-client-javascript/recommend/utils/HttpRequester.ts new file mode 100644 index 0000000000..7105360a44 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/utils/HttpRequester.ts @@ -0,0 +1,84 @@ +import { EndRequest, Response } from './types'; +import * as http from 'http'; +import * as https from 'https'; +import { Requester } from './Requester'; + +export class HttpRequester extends Requester { + private httpAgent: http.Agent; + private httpsAgent: https.Agent; + + constructor() { + super(); + this.httpAgent = new http.Agent({ keepAlive: true }); + this.httpsAgent = new https.Agent({ keepAlive: true }); + } + + async send(request: EndRequest): Promise { + return new Promise((resolve) => { + const url = new URL(request.url); + + const path = url.search === null ? url.pathname : `${url.pathname}?${url.search}`; + + const options: https.RequestOptions = { + agent: url.protocol === 'https:' ? this.httpsAgent : this.httpAgent, + hostname: url.hostname, + path, + method: request.method, + headers: request.headers, + ...(url.port !== undefined ? { port: url.port || '' } : {}), + }; + + const req = (url.protocol === 'https:' ? https : http).request(options, (response) => { + let contentBuffers: Buffer[] = []; + + response.on('data', (chunk) => { + contentBuffers = contentBuffers.concat(chunk); + }); + + response.on('end', () => { + clearTimeout(connectTimeout); + clearTimeout(responseTimeout as NodeJS.Timeout); + + resolve({ + status: response.statusCode || 0, + content: Buffer.concat(contentBuffers).toString(), + isTimedOut: false, + }); + }); + }); + + const createTimeout = (timeout: number, content: string): NodeJS.Timeout => { + return setTimeout(() => { + req.destroy(); + + resolve({ + status: 0, + content, + isTimedOut: true, + }); + }, timeout * 1000); + }; + + const connectTimeout = createTimeout(request.connectTimeout, 'Connection timeout'); + + let responseTimeout: NodeJS.Timeout | undefined; + + req.on('error', (error) => { + clearTimeout(connectTimeout); + clearTimeout(responseTimeout!); + resolve({ status: 0, content: error.message, isTimedOut: false }); + }); + + req.once('response', () => { + clearTimeout(connectTimeout); + responseTimeout = createTimeout(request.responseTimeout, 'Socket timeout'); + }); + + if (request.data !== undefined) { + req.write(request.data); + } + + req.end(); + }); + } +} diff --git a/clients/algoliasearch-client-javascript/recommend/utils/MemoryCache.ts b/clients/algoliasearch-client-javascript/recommend/utils/MemoryCache.ts new file mode 100644 index 0000000000..d492164e34 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/utils/MemoryCache.ts @@ -0,0 +1,27 @@ +import type { Cache } from './Cache'; + +export class MemoryCache implements Cache { + private cache: Record = {}; + + async get(key: object | string, defaultValue: () => Promise): Promise { + const keyAsString = JSON.stringify(key); + + if (keyAsString in this.cache) { + return Promise.resolve(this.cache[keyAsString]); + } + return await defaultValue(); + } + + async set(key: object | string, value: TValue): Promise { + this.cache[JSON.stringify(key)] = value; + return value; + } + + async delete(key: object | string): Promise { + delete this.cache[JSON.stringify(key)]; + } + + async clear(): Promise { + this.cache = {}; + } +} diff --git a/clients/algoliasearch-client-javascript/recommend/utils/Requester.ts b/clients/algoliasearch-client-javascript/recommend/utils/Requester.ts new file mode 100644 index 0000000000..6735a27a34 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/utils/Requester.ts @@ -0,0 +1,4 @@ +import { EndRequest, Response } from './types'; +export abstract class Requester { + abstract send(request: EndRequest): Promise; +} diff --git a/clients/algoliasearch-client-javascript/recommend/utils/Response.ts b/clients/algoliasearch-client-javascript/recommend/utils/Response.ts new file mode 100644 index 0000000000..cc53c30f5e --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/utils/Response.ts @@ -0,0 +1,17 @@ +import { Response } from './types'; + +export function isNetworkError({ isTimedOut, status }: Omit): boolean { + return !isTimedOut && ~~status === 0; +} + +export function isRetryable({ isTimedOut, status }: Omit): boolean { + return ( + isTimedOut || + isNetworkError({ isTimedOut, status }) || + (~~(status / 100) !== 2 && ~~(status / 100) !== 4) + ); +} + +export function isSuccess({ status }: Pick): boolean { + return ~~(status / 100) === 2; +} diff --git a/clients/algoliasearch-client-javascript/recommend/utils/StatefulHost.ts b/clients/algoliasearch-client-javascript/recommend/utils/StatefulHost.ts new file mode 100644 index 0000000000..d9cd8929df --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/utils/StatefulHost.ts @@ -0,0 +1,29 @@ +import type { Host } from './types'; + +const EXPIRATION_DELAY = 2 * 60 * 1000; + +export class StatefulHost implements Host { + url: string; + accept: 'read' | 'write' | 'readWrite'; + protocol: 'http' | 'https'; + + private lastUpdate: number; + private status: 'up' | 'down' | 'timedout'; + + constructor(host: Host, status: StatefulHost['status'] = 'up') { + this.url = host.url; + this.accept = host.accept; + this.protocol = host.protocol; + + this.status = status; + this.lastUpdate = Date.now(); + } + + isUp(): boolean { + return this.status === 'up' || Date.now() - this.lastUpdate > EXPIRATION_DELAY; + } + + isTimedout(): boolean { + return this.status === 'timedout' && Date.now() - this.lastUpdate <= EXPIRATION_DELAY; + } +} diff --git a/clients/algoliasearch-client-javascript/recommend/utils/Transporter.ts b/clients/algoliasearch-client-javascript/recommend/utils/Transporter.ts new file mode 100644 index 0000000000..4248c636a3 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/utils/Transporter.ts @@ -0,0 +1,216 @@ +import type { + Host, + Request, + RequestOptions, + StackFrame, + Timeouts, + Response, + EndRequest, +} from './types'; +import { MemoryCache } from './MemoryCache'; +import type { Cache } from './Cache'; +import { StatefulHost } from './StatefulHost'; +import { + deserializeFailure, + deserializeSuccess, + serializeData, + serializeHeaders, + serializeUrl, +} from './helpers'; +import { Headers } from './types'; +import { RetryError } from './errors'; +import * as responseUtils from './Response'; +import { Requester } from './Requester'; +import { HttpRequester } from './HttpRequester'; + +export class Transporter { + private hosts: Host[]; + private baseHeaders: Headers; + private hostsCache: Cache; + private userAgent: string; + private timeouts: Timeouts; + private requester: Requester; + + constructor({ + hosts, + baseHeaders, + userAgent, + timeouts, + requester = new HttpRequester(), + }: { + hosts: Host[]; + baseHeaders: Headers; + userAgent: string; + timeouts: Timeouts; + requester?: Requester; + }) { + this.hosts = hosts; + this.hostsCache = new MemoryCache(); + this.baseHeaders = baseHeaders; + this.userAgent = userAgent; + this.timeouts = timeouts; + this.requester = requester; + } + + async createRetryableOptions(compatibleHosts: Host[]): Promise<{ + hosts: Host[]; + getTimeout: (retryCount: number, timeout: number) => number; + }> { + const statefulHosts = await Promise.all( + compatibleHosts.map((statelessHost) => { + return this.hostsCache.get(statelessHost, async () => { + return new StatefulHost(statelessHost); + }); + }) + ); + const hostsUp = statefulHosts.filter((host) => host.isUp()); + const hostsTimeouted = statefulHosts.filter((host) => host.isTimedout()); + + /** + * Note, we put the hosts that previously timeouted on the end of the list. + */ + const hostsAvailable = [...hostsUp, ...hostsTimeouted]; + + const hosts = hostsAvailable.length > 0 ? hostsAvailable : compatibleHosts; + + return { + hosts, + getTimeout(timeoutsCount: number, baseTimeout: number): number { + /** + * Imagine that you have 4 hosts, if timeouts will increase + * on the following way: 1 (timeouted) > 4 (timeouted) > 5 (200) + * + * Note that, the very next request, we start from the previous timeout + * + * 5 (timeouted) > 6 (timeouted) > 7 ... + * + * This strategy may need to be reviewed, but is the strategy on the our + * current v3 version. + */ + const timeoutMultiplier = + hostsTimeouted.length === 0 && timeoutsCount === 0 + ? 1 + : hostsTimeouted.length + 3 + timeoutsCount; + + return timeoutMultiplier * baseTimeout; + }, + }; + } + + async request(request: Request, requestOptions: RequestOptions): Promise { + const stackTrace: StackFrame[] = []; + + const isRead = request.method === 'GET'; + + /** + * First we prepare the payload that do not depend from hosts. + */ + const data = serializeData(request, requestOptions); + const headers = serializeHeaders(this.baseHeaders, requestOptions); + const method = request.method; + + // On `GET`, the data is proxied to query parameters. + const dataQueryParameters: Record = isRead + ? { + ...request.data, + ...requestOptions.data, + } + : {}; + + const queryParameters = { + 'x-algolia-agent': this.userAgent, + ...dataQueryParameters, + ...requestOptions.queryParameters, + }; + + let timeoutsCount = 0; + + const retry = async ( + hosts: Host[], + getTimeout: (timeoutsCount: number, timeout: number) => number + ): Promise => { + /** + * We iterate on each host, until there is no host left. + */ + const host = hosts.pop(); + if (host === undefined) { + throw new RetryError(stackTrace); + } + + let responseTimeout = requestOptions.timeout; + if (responseTimeout === undefined) { + responseTimeout = isRead ? this.timeouts.read : this.timeouts.write; + } + + const payload: EndRequest = { + data, + headers, + method, + url: serializeUrl(host, request.path, queryParameters), + connectTimeout: getTimeout(timeoutsCount, this.timeouts.connect), + responseTimeout: getTimeout(timeoutsCount, responseTimeout), + }; + + /** + * The stackFrame is pushed to the stackTrace so we + * can have information about onRetry and onFailure + * decisions. + */ + const pushToStackTrace = (response: Response): StackFrame => { + const stackFrame: StackFrame = { + request: payload, + response, + host, + triesLeft: hosts.length, + }; + + stackTrace.push(stackFrame); + + return stackFrame; + }; + + const response = await this.requester.send(payload); + + if (responseUtils.isRetryable(response)) { + pushToStackTrace(response); + + // If response is a timeout, we increase the number of timeouts so we can increase the timeout later. + if (response.isTimedOut) { + timeoutsCount++; + } + + /** + * We also store the state of the host in failure cases. If the host, is + * down it will remain down for the next 2 minutes. In a timeout situation, + * this host will be added end of the list of hosts on the next request. + */ + await this.hostsCache.set( + host, + new StatefulHost(host, response.isTimedOut ? 'timedout' : 'down') + ); + return retry(hosts, getTimeout); + } + if (responseUtils.isSuccess(response)) { + return deserializeSuccess(response); + } + + pushToStackTrace(response); + throw deserializeFailure(response, stackTrace); + }; + + /** + * Finally, for each retryable host perform request until we got a non + * retryable response. Some notes here: + * + * 1. The reverse here is applied so we can apply a `pop` later on => more performant. + * 2. We also get from the retryable options a timeout multiplier that is tailored + * for the current context. + */ + const compatibleHosts = this.hosts.filter( + (host) => + host.accept == 'readWrite' || (isRead ? host.accept == 'read' : host.accept == 'write') + ); + const options = await this.createRetryableOptions(compatibleHosts); + return retry([...options.hosts].reverse(), options.getTimeout); + } +} diff --git a/clients/algoliasearch-client-javascript/recommend/utils/errors.ts b/clients/algoliasearch-client-javascript/recommend/utils/errors.ts new file mode 100644 index 0000000000..df4f3008d9 --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/utils/errors.ts @@ -0,0 +1,38 @@ +import { Response, StackFrame } from './types'; + +class ErrorWithStackTrace extends Error { + stackTrace: StackFrame[]; + + constructor(message: string, stackTrace: StackFrame[]) { + super(message); + //the array and object should be frozen to reflect the stackTrace at the time of the error + this.stackTrace = stackTrace; + } +} + +export class RetryError extends ErrorWithStackTrace { + constructor(stackTrace: StackFrame[]) { + super( + 'Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.', + stackTrace + ); + } +} + +export class ApiError extends ErrorWithStackTrace { + status: number; + + constructor(message: string, status: number, stackTrace: StackFrame[]) { + super(message, stackTrace); + this.status = status; + } +} + +export class DeserializationError extends Error { + response: Response; + + constructor(message: string, response: Response) { + super(message); + this.response = response; + } +} diff --git a/clients/algoliasearch-client-javascript/recommend/utils/helpers.ts b/clients/algoliasearch-client-javascript/recommend/utils/helpers.ts new file mode 100644 index 0000000000..2271326b7e --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/utils/helpers.ts @@ -0,0 +1,94 @@ +import { ApiError, DeserializationError } from './errors'; +import { Headers, Host, Request, RequestOptions, Response, StackFrame } from './types'; + +export function shuffle(array: TData[]): TData[] { + for (let c = array.length - 1; c > 0; c--) { + const b = Math.floor(Math.random() * (c + 1)); + const a = array[c]; + array[c] = array[b]; + array[b] = a; + } + return array; +} + +export function serializeUrl( + host: Host, + path: string, + queryParameters: Readonly> +): string { + const queryParametersAsString = serializeQueryParameters(queryParameters); + let url = `${host.protocol}://${host.url}/${path.charAt(0) === '/' ? path.substr(1) : path}`; + + if (queryParametersAsString.length) { + url += `?${queryParametersAsString}`; + } + + return url; +} + +export function serializeQueryParameters(parameters: Readonly>): string { + const isObjectOrArray = (value: any): boolean => + Object.prototype.toString.call(value) === '[object Object]' || + Object.prototype.toString.call(value) === '[object Array]'; + + return Object.keys(parameters) + .map( + (key) => + `${key}=${ + isObjectOrArray(parameters[key]) ? JSON.stringify(parameters[key]) : parameters[key] + }` + ) + .join('&'); +} + +export function serializeData( + request: Request, + requestOptions: RequestOptions +): string | undefined { + if ( + request.method === 'GET' || + (request.data === undefined && requestOptions.data === undefined) + ) { + return undefined; + } + + const data = Array.isArray(request.data) + ? request.data + : { ...request.data, ...requestOptions.data }; + + return JSON.stringify(data); +} + +export function serializeHeaders(baseHeaders: Headers, requestOptions: RequestOptions): Headers { + const headers: Headers = { + ...baseHeaders, + ...requestOptions.headers, + }; + const serializedHeaders: Headers = {}; + + Object.keys(headers).forEach((header) => { + const value = headers[header]; + serializedHeaders[header.toLowerCase()] = value; + }); + + return serializedHeaders; +} + +export function deserializeSuccess(response: Response): TObject { + try { + return JSON.parse(response.content); + } catch (e) { + throw new DeserializationError((e as Error).message, response); + } +} + +export function deserializeFailure({ content, status }: Response, stackFrame: StackFrame[]): Error { + let message = content; + try { + message = JSON.parse(content).message; + } catch (e) { + // .. + } + + return new ApiError(message, status, stackFrame); +} diff --git a/clients/algoliasearch-client-javascript/recommend/utils/types.ts b/clients/algoliasearch-client-javascript/recommend/utils/types.ts new file mode 100644 index 0000000000..1b6ce1e6ca --- /dev/null +++ b/clients/algoliasearch-client-javascript/recommend/utils/types.ts @@ -0,0 +1,65 @@ +export type Method = 'GET' | 'PATCH' | 'POST' | 'PUT' | 'DELETE'; + +export type Request = { + method: Method; + path: string; + data?: Record; +}; + +export type RequestOptions = { + /** + * Custom timeout for the request. Note that, in normal situacions + * the given timeout will be applied. But the transporter layer may + * increase this timeout if there is need for it. + */ + timeout?: number; + + /** + * Custom headers for the request. This headers are + * going to be merged the transporter headers. + */ + headers?: Record; + + /** + * Custom query parameters for the request. This query parameters are + * going to be merged the transporter query parameters. + */ + queryParameters: Record; + data?: Record; +}; + +export type EndRequest = { + method: Method; + url: string; + connectTimeout: number; + responseTimeout: number; + headers: Headers; + data?: string; +}; + +export type Response = { + content: string; + isTimedOut: boolean; + status: number; +}; + +export type Headers = Record; + +export type Host = { + url: string; + accept: 'read' | 'write' | 'readWrite'; + protocol: 'http' | 'https'; +}; + +export type StackFrame = { + request: EndRequest; + response: Response; + host: Host; + triesLeft: number; +}; + +export type Timeouts = { + readonly connect: number; + readonly read: number; + readonly write: number; +}; diff --git a/openapitools.json b/openapitools.json index 2fa27925d9..af88ab629a 100644 --- a/openapitools.json +++ b/openapitools.json @@ -3,12 +3,12 @@ "generator-cli": { "version": "5.3.0", "generators": { - "javascript-client": { + "javascript-client-search": { "generatorName": "typescript-node", "templateDir": "#{cwd}/templates/javascript/", "config": "#{cwd}/openapitools.json", - "apiPackage": "client-search", - "output": "#{cwd}/clients/algoliasearch-client-javascript", + "apiPackage": "src", + "output": "#{cwd}/clients/algoliasearch-client-javascript/client-search", "glob": "specs/search/spec.yml", "gitHost": "algolia", "gitUserId": "algolia", @@ -16,7 +16,24 @@ "additionalProperties": { "modelPropertyNaming": "original", "supportsES6": true, - "npmName": "algoliasearch-client-javascript", + "npmName": "@algolia/client-search", + "npmVersion": "5.0.0" + } + }, + "javascript-recommend": { + "generatorName": "typescript-node", + "templateDir": "#{cwd}/templates/javascript/", + "config": "#{cwd}/openapitools.json", + "apiPackage": "src", + "output": "#{cwd}/clients/algoliasearch-client-javascript/recommend", + "glob": "specs/recommend/spec.yml", + "gitHost": "algolia", + "gitUserId": "algolia", + "gitRepoId": "algoliasearch-client-javascript", + "additionalProperties": { + "modelPropertyNaming": "original", + "supportsES6": true, + "npmName": "@algolia/recommend", "npmVersion": "5.0.0" } } diff --git a/package.json b/package.json index a844a49e83..51005b186a 100644 --- a/package.json +++ b/package.json @@ -2,24 +2,31 @@ "name": "@algolia/api-client-automation", "version": "0.0.0", "workspaces": [ - "clients/algoliasearch-client-javascript/", + "clients/algoliasearch-client-javascript/*", "playground/javascript/" ], "scripts": { - "build:spec": "yarn swagger-cli bundle specs/search/spec.yml --outfile dist/openapi.yml --type yaml", - "build:spec:json": "yarn swagger-cli bundle specs/search/spec.yml --outfile dist/openapi.json --type json", + "build:spec:recommend:json": "yarn swagger-cli bundle specs/recommend/spec.yml --outfile dist/openapi.json --type json", + "build:spec:search:json": "yarn swagger-cli bundle specs/search/spec.yml --outfile dist/openapi.json --type json", + "build:spec:recommend": "yarn swagger-cli bundle specs/recommend/spec.yml --outfile dist/recommend.yml --type yaml", + "build:spec:search": "yarn swagger-cli bundle specs/search/spec.yml --outfile dist/search.yml --type yaml", + "build:spec:json": "yarn build:spec:search:json", + "build:spec": "yarn build:spec:search && yarn build:spec:recommend", "clean": "rm -rf **/dist **/build **/node_modules", - "client:build-js": "cd clients/algoliasearch-client-javascript/ && yarn install && yarn build && cd ../../", + "client:build-js": "yarn workspace @algolia/recommend build && yarn workspace @algolia/client-search build", "client:build": "yarn client:build-js", - "lint:js": "yarn prettier --write clients/algoliasearch-client-javascript clients/utils/javascript", + "lint:js": "yarn prettier --write clients/algoliasearch-client-javascript", "lint:specs": "yarn prettier --write specs", "lint": "yarn lint:specs && yarn lint:js", - "generate:js": "PACKAGE_VERSION='4.11.0' yarn openapi-generator-cli generate --generator-key javascript-client && yarn install && yarn utils:import-js", - "generate:js:search": "PACKAGE_VERSION='4.11.0' yarn openapi-generator-cli generate -i specs/search/spec.yml --generator-key javascript-client && yarn install && yarn utils:import-js", + "generate:js:recommend": "yarn openapi-generator-cli generate --generator-key javascript-recommend && CLIENT=recommend yarn utils:import-js", + "generate:js:search": "yarn openapi-generator-cli generate --generator-key javascript-client-search && CLIENT=client-search yarn utils:import-js", + "generate:js": "yarn generate:js:search && yarn generate:js:recommend && yarn install", + "generate:recommend": "yarn generate:js:recommend", + "generate:search": "yarn generate:js:search", "generate": "yarn generate:js && yarn lint", - "generate:search": "yarn generate:js:search && yarn lint", - "playground:js": "yarn workspace algoliasearch-client-javascript-playground start", - "utils:import-js": "mkdir -p -- clients/algoliasearch-client-javascript/utils && cp -R clients/utils/javascript/ clients/algoliasearch-client-javascript/utils" + "playground:js:search": "yarn workspace javascript-playground start:search", + "playground:js:recommend": "yarn workspace javascript-playground start:recommend", + "utils:import-js": "mkdir -p -- clients/algoliasearch-client-javascript/${CLIENT}/utils && cp -R clients/algoliasearch-client-javascript/utils/ clients/algoliasearch-client-javascript/${CLIENT}/utils" }, "devDependencies": { "@openapitools/openapi-generator-cli": "^2.4.13", diff --git a/playground/javascript/app.ts b/playground/javascript/app.ts deleted file mode 100644 index fcc2d59d8c..0000000000 --- a/playground/javascript/app.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { searchClient, ApiError } from 'algoliasearch-client-javascript'; -import dotenv from 'dotenv'; - -dotenv.config({ path: '../.env' }); - -const appId = process.env.ALGOLIA_APPLICATION_ID || '**** APP_ID *****'; -const apiKey = process.env.ALGOLIA_SEARCH_KEY || '**** SEARCH_API_KEY *****'; - -const searchIndex = process.env.SEARCH_INDEX || 'test_index'; -const searchQuery = process.env.SEARCH_QUERY || 'test_query'; - -// Init client with appId and apiKey -const client = new searchClient(appId, apiKey); - -async function testMultiQueries() { - try { - const res = await client.multipleQueries({ - requests: [ - { - indexName: searchIndex, - query: searchQuery, - }, - ], - }); - - console.log(`[OK]`, res); - } catch (e) { - if (e instanceof ApiError) { - return console.log(`[${e.status}] ${e.message}`, e.stackTrace); - } - - console.log('[ERROR]', e); - } -} - -async function testSearch() { - try { - const res = await client.search(searchIndex, { - query: searchQuery, - }); - - console.log(`[OK]`, res); - } catch (e) { - if (e instanceof ApiError) { - return console.log(`[${e.status}] ${e.message}`, e.stackTrace); - } - - console.log('[ERROR]', JSON.stringify(e, null, 4)); - } -} - -// testMultiQueries(); -testSearch(); diff --git a/playground/javascript/package.json b/playground/javascript/package.json index 5af9654adf..5eee07a707 100644 --- a/playground/javascript/package.json +++ b/playground/javascript/package.json @@ -1,13 +1,16 @@ { - "name": "algoliasearch-client-javascript-playground", + "name": "javascript-playground", "version": "0.0.0", "scripts": { "build": "tsc", - "start": "yarn install && yarn build && yarn test", - "test": "node dist/app.js" + "start:search": "yarn install && yarn build && yarn test:search", + "start:recommend": "yarn install && yarn build && yarn test:recommend", + "test:search": "node dist/search.js", + "test:recommend": "node dist/recommend.js" }, "devDependencies": { - "algoliasearch-client-javascript": "5.0.0", + "@algolia/client-search": "5.0.0", + "@algolia/recommend": "5.0.0", "dotenv": "10.0.0", "prettier": "2.4.1", "typescript": "4.5.2" diff --git a/playground/javascript/recommend.ts b/playground/javascript/recommend.ts new file mode 100644 index 0000000000..66bf7b3f3e --- /dev/null +++ b/playground/javascript/recommend.ts @@ -0,0 +1,36 @@ +import { RecommendApiClient, ApiError, RecommendationRequest } from '@algolia/recommend'; +import dotenv from 'dotenv'; + +dotenv.config({ path: '../.env' }); + +const appId = process.env.ALGOLIA_APPLICATION_ID || '**** APP_ID *****'; +const apiKey = process.env.ALGOLIA_SEARCH_KEY || '**** SEARCH_API_KEY *****'; + +const searchIndex = process.env.SEARCH_INDEX || 'test_index'; +const searchQuery = process.env.SEARCH_QUERY || 'test_query'; + +// Init client with appId and apiKey +const client = new RecommendApiClient(appId, apiKey); + +async function testRecommend() { + try { + const res = await client.getRecommendations([ + { + indexName: searchIndex, + model: RecommendationRequest.ModelEnum['BoughtTogether'], + objectID: searchQuery, + threshold: 0, + }, + ]); + + console.log(`[OK]`, res); + } catch (e) { + if (e instanceof ApiError) { + return console.log(`[${e.status}] ${e.message}`, e.stackTrace); + } + + console.log('[ERROR]', e); + } +} + +testRecommend(); diff --git a/playground/javascript/search.ts b/playground/javascript/search.ts new file mode 100644 index 0000000000..1e6bd774bf --- /dev/null +++ b/playground/javascript/search.ts @@ -0,0 +1,29 @@ +import { SearchApiClient, ApiError } from '@algolia/client-search'; +import dotenv from 'dotenv'; + +dotenv.config({ path: '../.env' }); + +const appId = process.env.ALGOLIA_APPLICATION_ID || '**** APP_ID *****'; +const apiKey = process.env.ALGOLIA_SEARCH_KEY || '**** SEARCH_API_KEY *****'; + +const searchIndex = process.env.SEARCH_INDEX || 'test_index'; +const searchQuery = process.env.SEARCH_QUERY || 'test_query'; + +// Init client with appId and apiKey +const client = new SearchApiClient(appId, apiKey); + +async function testSearch() { + try { + const res = await client.search(searchIndex, {}); + + console.log(`[OK]`, res); + } catch (e) { + if (e instanceof ApiError) { + return console.log(`[${e.status}] ${e.message}`, e.stackTrace); + } + + console.log('[ERROR]', e); + } +} + +testSearch(); diff --git a/playground/javascript/tsconfig.json b/playground/javascript/tsconfig.json index 2c3762b922..5e79b3b7eb 100644 --- a/playground/javascript/tsconfig.json +++ b/playground/javascript/tsconfig.json @@ -16,5 +16,5 @@ "outDir": "dist", "typeRoots": ["node_modules/@types"] }, - "include": ["app.ts"] + "include": ["search.ts", "recommend.ts"] } diff --git a/specs/common/parameters.yml b/specs/common/parameters.yml index d64a60a587..f104e4495f 100644 --- a/specs/common/parameters.yml +++ b/specs/common/parameters.yml @@ -48,3 +48,8 @@ updatedAt: type: string format: date-time description: Date of last update. (ISO-8601 format) + +indexName: + type: string + example: products + description: The Algolia index name diff --git a/specs/common/responses/FeatureNotEnabled.yml b/specs/common/responses/FeatureNotEnabled.yml new file mode 100644 index 0000000000..2fad7a24f5 --- /dev/null +++ b/specs/common/responses/FeatureNotEnabled.yml @@ -0,0 +1,5 @@ +description: This feature is not enabled on your Algolia account +content: + application/json: + schema: + $ref: '../schemas/ErrorBase.yml' diff --git a/specs/recommend/common/schemas/RecommendationsResponse.yml b/specs/recommend/common/schemas/RecommendationsResponse.yml new file mode 100644 index 0000000000..84067a9c71 --- /dev/null +++ b/specs/recommend/common/schemas/RecommendationsResponse.yml @@ -0,0 +1,35 @@ +recommendationsResponse: + allOf: + - $ref: '../../../search/common/schemas/SearchResponse.yml#/baseSearchResponse' + - type: object + additionalProperties: false + properties: + hits: + type: array + items: + $ref: '#/recommendRecord' + +recommendRecord: + type: object + description: A Recommend record + additionalProperties: true + required: + - objectID + - _score + properties: + objectID: + $ref: '../../../common/parameters.yml#/objectID' + _highlightResult: + $ref: '../../../search/common/schemas/Record.yml#/highlightResult' + _snippetResult: + $ref: '../../../search/common/schemas/Record.yml#/snippetResult' + _rankingInfo: + $ref: '../../../search/common/schemas/Record.yml#/rankingInfo' + _distinctSeqID: + $ref: '../../../search/common/schemas/Record.yml#/record/properties/_distinctSeqID' + _score: + type: number + format: double + minimum: 0 + maximum: 100 + description: The recommendation score diff --git a/specs/recommend/paths/getRecommendations.yml b/specs/recommend/paths/getRecommendations.yml index 6adb517bf4..4fbe9cfde4 100644 --- a/specs/recommend/paths/getRecommendations.yml +++ b/specs/recommend/paths/getRecommendations.yml @@ -1 +1,69 @@ post: + tags: + - recommend + operationId: getRecommendations + summary: Returns recommendations for a specific model and objectID + requestBody: + required: true + content: + application/json: + schema: + title: getRecommendations + type: array + items: + title: recommendationRequest + type: object + additionalProperties: false + properties: + indexName: + $ref: '../../common/parameters.yml#/indexName' + objectID: + $ref: '../../common/parameters.yml#/objectID' + model: + description: The recommendation model to use. + type: string + enum: ['related-products', 'bought-together'] + threshold: + type: integer + minimum: 0 + maximum: 100 + description: The threshold to use when filtering recommendations by their score. + maxRecommendations: + type: integer + default: 0 + description: The max number of recommendations to retrieve. If it’s set to 0, all the recommendations of the objectID may be returned. + queryParameters: + allOf: + - $ref: '../../search/common/schemas/SearchParams.yml#/baseSearchParams' + - $ref: '../../search/common/schemas/IndexSettings.yml#/indexSettingsAsSearchParams' + fallbackParameters: + allOf: + - $ref: '../../search/common/schemas/SearchParams.yml#/baseSearchParams' + - $ref: '../../search/common/schemas/IndexSettings.yml#/indexSettingsAsSearchParams' + required: + - model + - indexName + - objectID + - threshold + responses: + '200': + description: OK + content: + application/json: + schema: + title: getRecommendationsResponse + type: object + additionalProperties: false + properties: + results: + type: array + items: + $ref: '../common/schemas/RecommendationsResponse.yml#/recommendationsResponse' + '400': + $ref: '../../common/responses/BadRequest.yml' + '402': + $ref: '../../common/responses/FeatureNotEnabled.yml' + '403': + $ref: '../../common/responses/MethodNotAllowed.yml' + '404': + $ref: '../../common/responses/IndexNotFound.yml' diff --git a/specs/recommend/spec.yml b/specs/recommend/spec.yml index 706b441952..2bd22fc63f 100644 --- a/specs/recommend/spec.yml +++ b/specs/recommend/spec.yml @@ -2,7 +2,7 @@ openapi: 3.0.2 info: title: Recommend API description: API powering the Recommend feature of Algolia. - version: 0.0.1 + version: 0.1.0 components: securitySchemes: appId: diff --git a/specs/search/common/schemas/SearchResponse.yml b/specs/search/common/schemas/SearchResponse.yml index 09b2c2c9e4..3509c133c6 100644 --- a/specs/search/common/schemas/SearchResponse.yml +++ b/specs/search/common/schemas/SearchResponse.yml @@ -1,4 +1,15 @@ searchResponse: + allOf: + - $ref: '#/baseSearchResponse' + - type: object + additionalProperties: false + properties: + hits: + type: array + items: + $ref: 'Record.yml#/record' + +baseSearchResponse: type: object additionalProperties: false required: @@ -62,10 +73,6 @@ searchResponse: sum: type: integer description: The sum of all values in the result set. - hits: - type: array - items: - $ref: 'Record.yml#/record' hitsPerPage: $ref: 'IndexSettings.yml#/indexSettingsAsSearchParams/properties/hitsPerPage' index: diff --git a/specs/search/paths/objects/batch.yml b/specs/search/paths/objects/batch.yml index 4cb2210e27..734c0193ab 100644 --- a/specs/search/paths/objects/batch.yml +++ b/specs/search/paths/objects/batch.yml @@ -53,6 +53,8 @@ post: $ref: '../../../common/parameters.yml#/objectIDs' '400': $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' '403': $ref: '../../../common/responses/MethodNotAllowed.yml' '404': diff --git a/specs/search/paths/objects/objects.yml b/specs/search/paths/objects/objects.yml index cfe9d8c989..6ad2fce1c4 100644 --- a/specs/search/paths/objects/objects.yml +++ b/specs/search/paths/objects/objects.yml @@ -31,6 +31,8 @@ post: $ref: '../../../common/parameters.yml#/objectID' '400': $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' '403': $ref: '../../../common/responses/MethodNotAllowed.yml' '404': diff --git a/specs/search/paths/search/multipleQueries.yml b/specs/search/paths/search/multipleQueries.yml index 78514ab9a6..3bac27758c 100644 --- a/specs/search/paths/search/multipleQueries.yml +++ b/specs/search/paths/search/multipleQueries.yml @@ -20,9 +20,7 @@ post: additionalProperties: false properties: indexName: - type: string - example: products - description: The Algolia index name + $ref: '../../../common/parameters.yml#/indexName' query: $ref: '../../common/schemas/SearchParams.yml#/baseSearchParams/properties/query' type: @@ -56,9 +54,11 @@ post: results: type: array items: - $ref: ../../common/schemas/SearchResponse.yml#/searchResponse + $ref: '../../common/schemas/SearchResponse.yml#/searchResponse' '400': $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' '403': $ref: '../../../common/responses/MethodNotAllowed.yml' '404': diff --git a/specs/search/paths/search/search.yml b/specs/search/paths/search/search.yml index 16df0b8f11..f33ef2a8af 100644 --- a/specs/search/paths/search/search.yml +++ b/specs/search/paths/search/search.yml @@ -23,6 +23,8 @@ post: $ref: '../../common/schemas/SearchResponse.yml#/searchResponse' '400': $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' '403': $ref: '../../../common/responses/MethodNotAllowed.yml' '404': diff --git a/specs/search/paths/settings/settings.yml b/specs/search/paths/settings/settings.yml index 3ef8ff7a76..6859e46262 100644 --- a/specs/search/paths/settings/settings.yml +++ b/specs/search/paths/settings/settings.yml @@ -15,6 +15,8 @@ get: $ref: '../../common/schemas/IndexSettings.yml#/indexSettings' '400': $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' '403': $ref: '../../../common/responses/MethodNotAllowed.yml' '404': @@ -51,6 +53,8 @@ put: $ref: '../../../common/parameters.yml#/updatedAt' '400': $ref: '../../../common/responses/BadRequest.yml' + '402': + $ref: '../../../common/responses/FeatureNotEnabled.yml' '403': $ref: '../../../common/responses/MethodNotAllowed.yml' '404': diff --git a/templates/javascript/api-all.mustache b/templates/javascript/api-all.mustache index 17bcd356c6..f93bb896bf 100644 --- a/templates/javascript/api-all.mustache +++ b/templates/javascript/api-all.mustache @@ -8,11 +8,11 @@ import { {{ classname }} } from './{{ classFilename }}'; export * from './{{ classFilename }}Interface' {{/withInterfaces}} {{/apis}} - -export class searchClient extends SearchApi{} - export * from '../utils/errors'; export { EchoRequester } from '../utils/EchoRequester'; +{{#apis}} +export class {{ classname }}Client extends {{ classname }}{} +{{/apis}} export const APIS = [{{#apis}}{{#operations}}{{ classname }}{{/operations}}{{^-last}}, {{/-last}}{{/apis}}]; {{/apiInfo}} diff --git a/templates/javascript/api-single.mustache b/templates/javascript/api-single.mustache index 52c144e582..e1ecc2b0dd 100644 --- a/templates/javascript/api-single.mustache +++ b/templates/javascript/api-single.mustache @@ -16,7 +16,7 @@ import { ApiKeyAuth } from '../model/models'; * {{&description}} */ {{/description}} -export enum {{classname}}ApiKeys { +export enum {{classname}}Keys { {{#authMethods}} {{#isApiKey}} {{name}}, @@ -38,8 +38,8 @@ export class {{classname}} { } constructor(appId: string, apiKey: string, requester?: Requester) { - this.setApiKey(SearchApiApiKeys.appId, appId); - this.setApiKey(SearchApiApiKeys.apiKey, apiKey); + this.setApiKey({{classname}}Keys.appId, appId); + this.setApiKey({{classname}}Keys.apiKey, apiKey); this.transporter = new Transporter({ hosts: ( [ @@ -66,8 +66,8 @@ export class {{classname}} { }); } - public setApiKey(key: {{classname}}ApiKeys, value: string) { - this.authentications[{{classname}}ApiKeys[key]].apiKey = value; + public setApiKey(key: {{classname}}Keys, value: string) { + this.authentications[{{classname}}Keys[key]].apiKey = value; } {{#hasAuthMethods}} {{#authMethods}} diff --git a/templates/javascript/api.mustache b/templates/javascript/api.mustache index b6399735d4..0ba53426e1 100644 --- a/templates/javascript/api.mustache +++ b/templates/javascript/api.mustache @@ -1,3 +1,3 @@ // This is the entrypoint for the package -export * from './client-search/apis'; -export * from './model/models'; \ No newline at end of file +export * from './{{apiPackage}}/apis'; +export * from './model/models'; diff --git a/templates/javascript/tsconfig.mustache b/templates/javascript/tsconfig.mustache index f10927b181..1b77056931 100644 --- a/templates/javascript/tsconfig.mustache +++ b/templates/javascript/tsconfig.mustache @@ -17,6 +17,6 @@ "typeRoots": ["node_modules/@types"], "types": ["node"] }, - "include": ["client-search", "model", "api.ts"], + "include": ["{{apiPackage}}", "model", "api.ts"], "exclude": ["dist", "node_modules"] } diff --git a/utils/recommend_spec.yml b/utils/recommend_spec.yml deleted file mode 100644 index 03bb91ee97..0000000000 --- a/utils/recommend_spec.yml +++ /dev/null @@ -1,103 +0,0 @@ -openapi: 3.0.0 -info: - title: Recommend API - description: API powering the Recommend feature of Algolia. - version: 0.1.0 -servers: - - url: https://{appid}-1.algolianet.com - - url: https://{appid}-2.algolianet.com - - url: https://{appid}-3.algolianet.com - - url: https://{appid}-dsn.algolianet.com -paths: - /1/indexes/*/recommendations: - post: - operationId: getRecommendations - summary: Get recommendations for the given requests. - parameters: - - in: header - name: X-Algolia-Application-Id - description: Algolia appID - schema: - type: string - - in: header - name: X-Algolia-API-Key - description: Algolia API key - schema: - type: string - requestBody: - required: true - content: - application/json: - schema: - type: array - items: - type: object - properties: - indexName: - type: string - example: products - model: - type: string - enum: [related-products, bought-together] - objectID: - type: string - threshold: - type: number - default: 0 - minimum: 0 - maximum: 1 - maxRecommendations: - type: number - default: 0 - example: 5 - minimum: 0 - maximum: 1000 - queryParameters: - type: object - additionalProperties: true - description: A key-value mapping of additional search parameters - example: - filters: 'in_stock:true' - fallbackParameters: - type: object - additionalProperties: true - description: A key-value mapping of additional search parameters - example: - filters: 'brand:apple' - required: - - indexName - - model - - objectID - responses: - '200': - description: OK - content: - application/json: - schema: - type: object - properties: - results: - type: array - items: - type: object - properties: - hits: - type: array - items: - type: object - additionalProperties: {} - properties: - objectID: - type: string - example: objectID1 - _score: - type: number - minimum: 0 - maximum: 1 - example: 0.41 - nbHits: - type: integer - queryID: - type: string - pattern: '[a-f0-9]{32}' - example: 43b15df305339e827f0ac0bdc5ebcaa7 diff --git a/utils/recommend_spec_2.yml b/utils/recommend_spec_2.yml deleted file mode 100644 index 96c373f410..0000000000 --- a/utils/recommend_spec_2.yml +++ /dev/null @@ -1,109 +0,0 @@ -openapi: 3.0.0 -info: - title: Recommend API - description: API powering the Recommend feature of Algolia. - version: 0.1.0 -servers: - - url: https://{appid}-1.algolianet.com - - url: https://{appid}-2.algolianet.com - - url: https://{appid}-3.algolianet.com - - url: https://{appid}-dsn.algolianet.com -paths: - /1/indexes/*/recommendations: - post: - operationId: getRecommendations - summary: Get recommendations for the given requests. - parameters: - - in: header - name: X-Algolia-Application-Id - description: Algolia appID - schema: - type: string - - in: header - name: X-Algolia-API-Key - description: Algolia API key - schema: - type: string - requestBody: - required: true - content: - application/json: - schema: - type: array - items: - type: object - properties: - indexName: - type: string - example: products - model: - type: string - enum: [related-products, bought-together] - objectID: - type: string - threshold: - type: number - default: 0 - minimum: 0 - maximum: 1 - maxRecommendations: - type: number - default: 0 - example: 5 - minimum: 0 - maximum: 1000 - minRecommendations: - type: number - default: 0 - example: 3 - minimum: 0 - maximum: 1000 - queryParameters: - type: object - additionalProperties: true - description: A key-value mapping of additional search parameters - example: - filters: 'in_stock:true' - fallbackParameters: - type: object - additionalProperties: true - description: A key-value mapping of additional search parameters - example: - filters: 'brand:apple' - required: - - indexName - - model - - objectID - responses: - '200': - description: OK - content: - application/json: - schema: - type: object - properties: - results: - type: array - items: - type: object - properties: - hits: - type: array - items: - type: object - additionalProperties: {} - properties: - objectID: - type: string - example: objectID1 - _score: - type: number - minimum: 0 - maximum: 1 - example: 0.41 - nbHits: - type: integer - queryID: - type: string - pattern: '[a-f0-9]{32}' - example: 43b15df305339e827f0ac0bdc5ebcaa7 diff --git a/yarn.lock b/yarn.lock index ae32476aed..ba739a59b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15,6 +15,24 @@ __metadata: languageName: unknown linkType: soft +"@algolia/client-search@5.0.0, @algolia/client-search@workspace:clients/algoliasearch-client-javascript/client-search": + version: 0.0.0-use.local + resolution: "@algolia/client-search@workspace:clients/algoliasearch-client-javascript/client-search" + dependencies: + "@types/node": ^16.11.6 + typescript: 4.5.2 + languageName: unknown + linkType: soft + +"@algolia/recommend@5.0.0, @algolia/recommend@workspace:clients/algoliasearch-client-javascript/recommend": + version: 0.0.0-use.local + resolution: "@algolia/recommend@workspace:clients/algoliasearch-client-javascript/recommend" + dependencies: + "@types/node": ^16.11.6 + typescript: 4.5.2 + languageName: unknown + linkType: soft + "@apidevtools/json-schema-ref-parser@npm:^9.0.6": version: 9.0.9 resolution: "@apidevtools/json-schema-ref-parser@npm:9.0.9" @@ -178,32 +196,12 @@ __metadata: linkType: hard "@types/node@npm:^16.11.6": - version: 16.11.9 - resolution: "@types/node@npm:16.11.9" - checksum: baec2e6471ee58fd1e9874e6f47ab95a918a0f46b42424392e4c13e3e07f078f8b72b6b48073b0b14f710ed66c5f1b2e497df43f28151000f11f5f299382cfe2 + version: 16.11.10 + resolution: "@types/node@npm:16.11.10" + checksum: 9c79419c5c3d92d5825bffa30f3668533f598d8b63a73ea7fc24e47f162bdbed92b0f8e4f4261cc3314b39cee050e303366d2aa154abc95c63a572a110b8c160 languageName: node linkType: hard -"algoliasearch-client-javascript-playground@workspace:playground/javascript": - version: 0.0.0-use.local - resolution: "algoliasearch-client-javascript-playground@workspace:playground/javascript" - dependencies: - algoliasearch-client-javascript: 5.0.0 - dotenv: 10.0.0 - prettier: 2.4.1 - typescript: 4.5.2 - languageName: unknown - linkType: soft - -"algoliasearch-client-javascript@5.0.0, algoliasearch-client-javascript@workspace:clients/algoliasearch-client-javascript": - version: 0.0.0-use.local - resolution: "algoliasearch-client-javascript@workspace:clients/algoliasearch-client-javascript" - dependencies: - "@types/node": ^16.11.6 - typescript: 4.5.2 - languageName: unknown - linkType: soft - "ansi-escapes@npm:^4.2.1": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" @@ -716,6 +714,18 @@ __metadata: languageName: node linkType: hard +"javascript-playground@workspace:playground/javascript": + version: 0.0.0-use.local + resolution: "javascript-playground@workspace:playground/javascript" + dependencies: + "@algolia/client-search": 5.0.0 + "@algolia/recommend": 5.0.0 + dotenv: 10.0.0 + prettier: 2.4.1 + typescript: 4.5.2 + languageName: unknown + linkType: soft + "js-yaml@npm:^3.14.0": version: 3.14.1 resolution: "js-yaml@npm:3.14.1" From 07aeafeba3a9b7ff55cff9954aa2c00ac0df4681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Mon, 29 Nov 2021 12:34:44 +0100 Subject: [PATCH 3/7] chore(tooling): setup GitHub actions, add CODEOWNERS and PR template --- .github/CODEOWNERS.md | 3 ++ .github/PULL_REQUEST_TEMPLATE.md | 11 +++++++ .github/workflows/client_javascript.yml | 43 +++++++++++++++++++++++++ .github/workflows/specs.yml | 37 +++++++++++++++++++++ package.json | 17 ++++++---- 5 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 .github/CODEOWNERS.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/workflows/client_javascript.yml create mode 100644 .github/workflows/specs.yml diff --git a/.github/CODEOWNERS.md b/.github/CODEOWNERS.md new file mode 100644 index 0000000000..e447251d3d --- /dev/null +++ b/.github/CODEOWNERS.md @@ -0,0 +1,3 @@ +# Default owners + +- @algolia/data-ingestion diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..9ad10c0f55 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,11 @@ +## 🧭 What and Why + +🎟 JIRA Ticket: + +### Changes included: + +- List changes + +## 🧪 Test + +- `yarn dev` diff --git a/.github/workflows/client_javascript.yml b/.github/workflows/client_javascript.yml new file mode 100644 index 0000000000..7df6a57c45 --- /dev/null +++ b/.github/workflows/client_javascript.yml @@ -0,0 +1,43 @@ +name: client_javascript + +on: [push] + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + node: ['16'] + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-java@v2 + with: + distribution: 'zulu' + java-version: '11' + + - uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + cache: 'yarn' + cache-dependency-path: 'yarn.lock' + + - name: Install Dependencies + run: yarn install + + - name: Generate search client + run: yarn generate:js:search + + - name: Build search client + run: yarn client:build-js:search + + - name: Generate recommend client + run: yarn generate:js:recommend + + - name: Build recommend client + run: yarn client:build-js:recommend + + - name: Lint + run: yarn lint:js --check diff --git a/.github/workflows/specs.yml b/.github/workflows/specs.yml new file mode 100644 index 0000000000..a03bccc585 --- /dev/null +++ b/.github/workflows/specs.yml @@ -0,0 +1,37 @@ +name: specs + +on: [push] + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + node: ['16'] + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-java@v2 + with: + distribution: 'zulu' + java-version: '11' + + - uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + cache: 'yarn' + cache-dependency-path: 'yarn.lock' + + - name: Install Dependencies + run: yarn install + + - name: Build + run: yarn build:spec + + - name: Validate + run: yarn validate + + - name: Lint + run: yarn lint:specs --check diff --git a/package.json b/package.json index 51005b186a..537bb498ef 100644 --- a/package.json +++ b/package.json @@ -6,14 +6,16 @@ "playground/javascript/" ], "scripts": { - "build:spec:recommend:json": "yarn swagger-cli bundle specs/recommend/spec.yml --outfile dist/openapi.json --type json", - "build:spec:search:json": "yarn swagger-cli bundle specs/search/spec.yml --outfile dist/openapi.json --type json", - "build:spec:recommend": "yarn swagger-cli bundle specs/recommend/spec.yml --outfile dist/recommend.yml --type yaml", - "build:spec:search": "yarn swagger-cli bundle specs/search/spec.yml --outfile dist/search.yml --type yaml", - "build:spec:json": "yarn build:spec:search:json", + "build:spec:recommend:json": "yarn swagger-cli bundle specs/recommend/spec.yml --outfile specs/dist/recommend.json --type json", + "build:spec:search:json": "yarn swagger-cli bundle specs/search/spec.yml --outfile specs/dist/search.json --type json", + "build:spec:recommend": "yarn swagger-cli bundle specs/recommend/spec.yml --outfile specs/dist/recommend.yml --type yaml", + "build:spec:search": "yarn swagger-cli bundle specs/search/spec.yml --outfile specs/dist/search.yml --type yaml", + "build:spec:json": "yarn build:spec:search:json && yarn build:spec:recommend:json", "build:spec": "yarn build:spec:search && yarn build:spec:recommend", "clean": "rm -rf **/dist **/build **/node_modules", - "client:build-js": "yarn workspace @algolia/recommend build && yarn workspace @algolia/client-search build", + "client:build-js:search": "yarn workspace @algolia/client-search build", + "client:build-js:recommend": "yarn workspace @algolia/client-search build", + "client:build-js": "yarn client:build-js:search && yarn client:build-js:recommend", "client:build": "yarn client:build-js", "lint:js": "yarn prettier --write clients/algoliasearch-client-javascript", "lint:specs": "yarn prettier --write specs", @@ -26,7 +28,8 @@ "generate": "yarn generate:js && yarn lint", "playground:js:search": "yarn workspace javascript-playground start:search", "playground:js:recommend": "yarn workspace javascript-playground start:recommend", - "utils:import-js": "mkdir -p -- clients/algoliasearch-client-javascript/${CLIENT}/utils && cp -R clients/algoliasearch-client-javascript/utils/ clients/algoliasearch-client-javascript/${CLIENT}/utils" + "utils:import-js": "mkdir -p -- clients/algoliasearch-client-javascript/${CLIENT}/utils && cp -R clients/algoliasearch-client-javascript/utils/ clients/algoliasearch-client-javascript/${CLIENT}/utils", + "validate": "yarn swagger-cli validate specs/dist/search.yml && yarn swagger-cli validate specs/dist/recommend.yml" }, "devDependencies": { "@openapitools/openapi-generator-cli": "^2.4.13", From a59eac020b04044ada21aec829e744bd2b5b3adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Mon, 29 Nov 2021 12:52:57 +0100 Subject: [PATCH 4/7] fix: lint commands --- .github/workflows/client_javascript.yml | 2 +- .github/workflows/specs.yml | 2 +- package.json | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/client_javascript.yml b/.github/workflows/client_javascript.yml index 7df6a57c45..66af18109d 100644 --- a/.github/workflows/client_javascript.yml +++ b/.github/workflows/client_javascript.yml @@ -40,4 +40,4 @@ jobs: run: yarn client:build-js:recommend - name: Lint - run: yarn lint:js --check + run: yarn prettier --check clients/algoliasearch-client-javascript diff --git a/.github/workflows/specs.yml b/.github/workflows/specs.yml index a03bccc585..db010c9393 100644 --- a/.github/workflows/specs.yml +++ b/.github/workflows/specs.yml @@ -34,4 +34,4 @@ jobs: run: yarn validate - name: Lint - run: yarn lint:specs --check + run: yarn prettier --check specs diff --git a/package.json b/package.json index 537bb498ef..9c09bcb381 100644 --- a/package.json +++ b/package.json @@ -17,15 +17,15 @@ "client:build-js:recommend": "yarn workspace @algolia/client-search build", "client:build-js": "yarn client:build-js:search && yarn client:build-js:recommend", "client:build": "yarn client:build-js", - "lint:js": "yarn prettier --write clients/algoliasearch-client-javascript", + "lint:js": "yarn prettier --write clients/algoliasearch-client-javascript/${CLIENT}", "lint:specs": "yarn prettier --write specs", "lint": "yarn lint:specs && yarn lint:js", - "generate:js:recommend": "yarn openapi-generator-cli generate --generator-key javascript-recommend && CLIENT=recommend yarn utils:import-js", - "generate:js:search": "yarn openapi-generator-cli generate --generator-key javascript-client-search && CLIENT=client-search yarn utils:import-js", - "generate:js": "yarn generate:js:search && yarn generate:js:recommend && yarn install", + "generate:js:recommend": "yarn openapi-generator-cli generate --generator-key javascript-recommend && CLIENT=recommend yarn utils:import-js && CLIENT=recommend yarn lint:js", + "generate:js:search": "yarn openapi-generator-cli generate --generator-key javascript-client-search && CLIENT=client-search yarn utils:import-js && CLIENT=client-search yarn lint:js", + "generate:js": "yarn generate:js:search && yarn generate:js:recommend", "generate:recommend": "yarn generate:js:recommend", "generate:search": "yarn generate:js:search", - "generate": "yarn generate:js && yarn lint", + "generate": "yarn generate:js && yarn lint:specs", "playground:js:search": "yarn workspace javascript-playground start:search", "playground:js:recommend": "yarn workspace javascript-playground start:recommend", "utils:import-js": "mkdir -p -- clients/algoliasearch-client-javascript/${CLIENT}/utils && cp -R clients/algoliasearch-client-javascript/utils/ clients/algoliasearch-client-javascript/${CLIENT}/utils", From 1345338c1fd156bf0abf6251581fecedc8b57cf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Mon, 29 Nov 2021 14:31:07 +0100 Subject: [PATCH 5/7] fix: PR template, run `client_javascript` on `specs` success --- .github/PULL_REQUEST_TEMPLATE.md | 2 -- .github/workflows/client_javascript.yml | 7 ++++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9ad10c0f55..2be07162e9 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,5 +7,3 @@ - List changes ## 🧪 Test - -- `yarn dev` diff --git a/.github/workflows/client_javascript.yml b/.github/workflows/client_javascript.yml index 66af18109d..0a242e3e04 100644 --- a/.github/workflows/client_javascript.yml +++ b/.github/workflows/client_javascript.yml @@ -1,9 +1,14 @@ name: client_javascript -on: [push] +on: + workflow_run: + workflows: ['specs'] + types: + - completed jobs: build: + if: ${{ github.event.workflow_run.conclusion == 'success' }} runs-on: ${{ matrix.os }} strategy: fail-fast: false From 508eb479cad97ec96a77b3263c7779939e8dd96f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Mon, 29 Nov 2021 14:40:16 +0100 Subject: [PATCH 6/7] fix: remove `strategy`, handle `failure` on `client_javascript` --- .github/workflows/client_javascript.yml | 16 +++++++++------- .github/workflows/specs.yml | 9 ++------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.github/workflows/client_javascript.yml b/.github/workflows/client_javascript.yml index 0a242e3e04..75b4c70e77 100644 --- a/.github/workflows/client_javascript.yml +++ b/.github/workflows/client_javascript.yml @@ -9,12 +9,7 @@ on: jobs: build: if: ${{ github.event.workflow_run.conclusion == 'success' }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest] - node: ['16'] + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -25,7 +20,7 @@ jobs: - uses: actions/setup-node@v2 with: - node-version: ${{ matrix.node }} + node-version: 16 cache: 'yarn' cache-dependency-path: 'yarn.lock' @@ -46,3 +41,10 @@ jobs: - name: Lint run: yarn prettier --check clients/algoliasearch-client-javascript + + build-failure: + if: ${{ github.event.workflow_run.conclusion == 'failure' }} + runs-on: ubuntu-latest + steps: + - name: Error on `specs` workflow + run: exit 1 diff --git a/.github/workflows/specs.yml b/.github/workflows/specs.yml index db010c9393..afdca73a5c 100644 --- a/.github/workflows/specs.yml +++ b/.github/workflows/specs.yml @@ -4,12 +4,7 @@ on: [push] jobs: build: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest] - node: ['16'] + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -20,7 +15,7 @@ jobs: - uses: actions/setup-node@v2 with: - node-version: ${{ matrix.node }} + node-version: 16 cache: 'yarn' cache-dependency-path: 'yarn.lock' From 9d2b0591fc43f79862aa5c1c938eb2e326e6be2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Mon, 29 Nov 2021 15:34:08 +0100 Subject: [PATCH 7/7] fix: use node version from `.nvmrc` --- .github/workflows/client_javascript.yml | 2 +- .github/workflows/specs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/client_javascript.yml b/.github/workflows/client_javascript.yml index 75b4c70e77..4a1dffd13c 100644 --- a/.github/workflows/client_javascript.yml +++ b/.github/workflows/client_javascript.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/setup-node@v2 with: - node-version: 16 + node-version-file: '.nvmrc' cache: 'yarn' cache-dependency-path: 'yarn.lock' diff --git a/.github/workflows/specs.yml b/.github/workflows/specs.yml index afdca73a5c..88840a75ec 100644 --- a/.github/workflows/specs.yml +++ b/.github/workflows/specs.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/setup-node@v2 with: - node-version: 16 + node-version-file: '.nvmrc' cache: 'yarn' cache-dependency-path: 'yarn.lock'