From 2fcafc0fbdae9b7c0fd75ccd4c30d9b1d6d90229 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Tue, 4 Feb 2025 09:34:49 +0200 Subject: [PATCH 01/18] Improve settings --- src/batch.ts | 2 +- src/enqueued-task.ts | 2 +- src/errors/meilisearch-api-error.ts | 2 +- src/http-requests.ts | 2 +- src/index.ts | 2 +- src/indexes.ts | 633 +++++++++----------------- src/meilisearch.ts | 4 +- src/task.ts | 4 +- src/token.ts | 5 +- src/types/index.ts | 2 + src/types/settings.ts | 127 ++++++ src/types/shared.ts | 7 + src/{ => types}/types.ts | 242 ++-------- tests/dictionary.test.ts | 8 +- tests/displayed_attributes.test.ts | 2 +- tests/distinct_attribute.test.ts | 2 +- tests/documents.test.ts | 2 +- tests/dump.test.ts | 2 +- tests/embedders.test.ts | 32 +- tests/facet_search_settings.test.ts | 2 +- tests/faceting.test.ts | 2 +- tests/filterable_attributes.test.ts | 24 +- tests/get_search.test.ts | 2 +- tests/index.test.ts | 2 +- tests/keys.test.ts | 2 +- tests/localized_attributes.test.ts | 13 +- tests/non_separator_tokens.test.ts | 16 +- tests/pagination.test.ts | 2 +- tests/prefix_search_settings.test.ts | 2 +- tests/proximity_precision.test.ts | 16 +- tests/ranking_rules.test.ts | 18 +- tests/raw_document.test.ts | 2 +- tests/search.test.ts | 4 +- tests/search_cutoff_ms.test.ts | 2 +- tests/searchable_attributes.test.ts | 18 +- tests/separator_tokens.test.ts | 16 +- tests/settings.test.ts | 10 +- tests/snapshots.test.ts | 2 +- tests/sortable_attributes.test.ts | 2 +- tests/stop_words.test.ts | 10 +- tests/synonyms.test.ts | 10 +- tests/task.test.ts | 2 +- tests/typed_search.test.ts | 2 +- tests/typo_tolerance.test.ts | 2 +- tests/utils/meilisearch-test-utils.ts | 2 +- 45 files changed, 486 insertions(+), 781 deletions(-) create mode 100644 src/types/index.ts create mode 100644 src/types/settings.ts create mode 100644 src/types/shared.ts rename src/{ => types}/types.ts (86%) diff --git a/src/batch.ts b/src/batch.ts index 67fbc5695..ffa763f37 100644 --- a/src/batch.ts +++ b/src/batch.ts @@ -4,7 +4,7 @@ import type { BatchesQuery, BatchesResults, BatchesResultsObject, -} from "./types.js"; +} from "./types/index.js"; import { HttpRequests, toQueryParams } from "./http-requests.js"; class Batch { diff --git a/src/enqueued-task.ts b/src/enqueued-task.ts index 9665cadbd..dce0512d5 100644 --- a/src/enqueued-task.ts +++ b/src/enqueued-task.ts @@ -1,4 +1,4 @@ -import type { EnqueuedTaskObject } from "./types.js"; +import type { EnqueuedTaskObject } from "./types/index.js"; class EnqueuedTask { taskUid: EnqueuedTaskObject["taskUid"]; diff --git a/src/errors/meilisearch-api-error.ts b/src/errors/meilisearch-api-error.ts index 6d74e764e..aeb1dd0cb 100644 --- a/src/errors/meilisearch-api-error.ts +++ b/src/errors/meilisearch-api-error.ts @@ -1,4 +1,4 @@ -import type { MeiliSearchErrorResponse } from "../types.js"; +import type { MeiliSearchErrorResponse } from "../types/index.js"; import { MeiliSearchError } from "./meilisearch-error.js"; export class MeiliSearchApiError extends MeiliSearchError { diff --git a/src/http-requests.ts b/src/http-requests.ts index 19e466323..b91e64ab9 100644 --- a/src/http-requests.ts +++ b/src/http-requests.ts @@ -1,4 +1,4 @@ -import type { Config, EnqueuedTaskObject } from "./types.js"; +import type { Config, EnqueuedTaskObject } from "./types/index.js"; import { PACKAGE_VERSION } from "./package-version.js"; import { diff --git a/src/index.ts b/src/index.ts index e559e1906..0783e1311 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -export * from "./types.js"; +export * from "./types/index.js"; export * from "./errors/index.js"; export * from "./indexes.js"; export * from "./enqueued-task.js"; diff --git a/src/indexes.ts b/src/indexes.ts index 5ad1b9ccb..d84831aa8 100644 --- a/src/indexes.ts +++ b/src/indexes.ts @@ -24,20 +24,9 @@ import type { DocumentQuery, DocumentOptions, Settings, - Synonyms, - StopWords, - RankingRules, - DistinctAttribute, - FilterableAttributes, - SortableAttributes, - SearchableAttributes, - DisplayedAttributes, - TypoTolerance, WaitOptions, TasksQuery, TasksResults, - PaginationSettings, - Faceting, ResourceResults, RawDocumentAdditionOptions, ContentType, @@ -45,17 +34,11 @@ import type { DocumentsDeletionQuery, SearchForFacetValuesParams, SearchForFacetValuesResponse, - SeparatorTokens, - NonSeparatorTokens, - Dictionary, - ProximityPrecision, - Embedders, - SearchCutoffMs, SearchSimilarDocumentsParams, - LocalizedAttributes, UpdateDocumentsByFunctionOptions, - PrefixSearch, -} from "./types.js"; + IndividualSettings, + UpdatableSettings, +} from "./types/index.js"; import { removeUndefinedFromObject } from "./utils.js"; import { HttpRequests } from "./http-requests.js"; import { Task, TaskClient } from "./task.js"; @@ -655,23 +638,14 @@ class Index = Record> { /// SETTINGS /// - /** - * Retrieve all settings - * - * @returns Promise containing Settings object - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-settings} */ async getSettings(): Promise { const url = `indexes/${this.uid}/settings`; return await this.httpRequest.get(url); } - /** - * Update all settings Any parameters not provided will be left unchanged. - * - * @param settings - Object containing parameters with their updated values - * @returns Promise containing an EnqueuedTask - */ - async updateSettings(settings: Settings): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-settings} */ + async updateSettings(settings: UpdatableSettings): Promise { const url = `indexes/${this.uid}/settings`; const task = await this.httpRequest.patch(url, settings); @@ -680,11 +654,7 @@ class Index = Record> { return task; } - /** - * Reset settings. - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-settings} */ async resetSettings(): Promise { const url = `indexes/${this.uid}/settings`; const task = await this.httpRequest.delete(url); @@ -698,24 +668,17 @@ class Index = Record> { /// PAGINATION SETTINGS /// - /** - * Get the pagination settings. - * - * @returns Promise containing object of pagination settings - */ - async getPagination(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-pagination-settings} */ + async getPagination(): Promise { const url = `indexes/${this.uid}/settings/pagination`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["pagination"] + >(url); } - /** - * Update the pagination settings. - * - * @param pagination - Pagination object - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-pagination-settings} */ async updatePagination( - pagination: PaginationSettings, + pagination: IndividualSettings["pagination"], ): Promise { const url = `indexes/${this.uid}/settings/pagination`; const task = await this.httpRequest.patch(url, pagination); @@ -723,11 +686,7 @@ class Index = Record> { return new EnqueuedTask(task); } - /** - * Reset the pagination settings. - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-pagination-settings} */ async resetPagination(): Promise { const url = `indexes/${this.uid}/settings/pagination`; const task = await this.httpRequest.delete(url); @@ -739,34 +698,25 @@ class Index = Record> { /// SYNONYMS /// - /** - * Get the list of all synonyms - * - * @returns Promise containing object of synonym mappings - */ - async getSynonyms(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-synonyms} */ + async getSynonyms(): Promise { const url = `indexes/${this.uid}/settings/synonyms`; - return await this.httpRequest.get(url); + return await this.httpRequest.get( + url, + ); } - /** - * Update the list of synonyms. Overwrite the old list. - * - * @param synonyms - Mapping of synonyms with their associated words - * @returns Promise containing an EnqueuedTask - */ - async updateSynonyms(synonyms: Synonyms): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-synonyms} */ + async updateSynonyms( + synonyms: IndividualSettings["synonyms"], + ): Promise { const url = `indexes/${this.uid}/settings/synonyms`; const task = await this.httpRequest.put(url, synonyms); return new EnqueuedTask(task); } - /** - * Reset the synonym list to be empty again - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-synonyms} */ async resetSynonyms(): Promise { const url = `indexes/${this.uid}/settings/synonyms`; const task = await this.httpRequest.delete(url); @@ -780,34 +730,25 @@ class Index = Record> { /// STOP WORDS /// - /** - * Get the list of all stop-words - * - * @returns Promise containing array of stop-words - */ - async getStopWords(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-stop-words} */ + async getStopWords(): Promise { const url = `indexes/${this.uid}/settings/stop-words`; - return await this.httpRequest.get(url); + return await this.httpRequest.get( + url, + ); } - /** - * Update the list of stop-words. Overwrite the old list. - * - * @param stopWords - Array of strings that contains the stop-words. - * @returns Promise containing an EnqueuedTask - */ - async updateStopWords(stopWords: StopWords): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-stop-words} */ + async updateStopWords( + stopWords: IndividualSettings["stopWords"], + ): Promise { const url = `indexes/${this.uid}/settings/stop-words`; const task = await this.httpRequest.put(url, stopWords); return new EnqueuedTask(task); } - /** - * Reset the stop-words list to be empty again - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-stop-words} */ async resetStopWords(): Promise { const url = `indexes/${this.uid}/settings/stop-words`; const task = await this.httpRequest.delete(url); @@ -821,35 +762,27 @@ class Index = Record> { /// RANKING RULES /// - /** - * Get the list of all ranking-rules - * - * @returns Promise containing array of ranking-rules - */ - async getRankingRules(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-ranking-rules} */ + async getRankingRules(): Promise< + IndividualSettings["rankingRules"] + > { const url = `indexes/${this.uid}/settings/ranking-rules`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["rankingRules"] + >(url); } - /** - * Update the list of ranking-rules. Overwrite the old list. - * - * @param rankingRules - Array that contain ranking rules sorted by order of - * importance. - * @returns Promise containing an EnqueuedTask - */ - async updateRankingRules(rankingRules: RankingRules): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-ranking-rules} */ + async updateRankingRules( + rankingRules: IndividualSettings["rankingRules"], + ): Promise { const url = `indexes/${this.uid}/settings/ranking-rules`; const task = await this.httpRequest.put(url, rankingRules); return new EnqueuedTask(task); } - /** - * Reset the ranking rules list to its default value - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-ranking-rules} */ async resetRankingRules(): Promise { const url = `indexes/${this.uid}/settings/ranking-rules`; const task = await this.httpRequest.delete(url); @@ -863,24 +796,19 @@ class Index = Record> { /// DISTINCT ATTRIBUTE /// - /** - * Get the distinct-attribute - * - * @returns Promise containing the distinct-attribute of the index - */ - async getDistinctAttribute(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-distinct-attribute} */ + async getDistinctAttribute(): Promise< + IndividualSettings["distinctAttribute"] + > { const url = `indexes/${this.uid}/settings/distinct-attribute`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["distinctAttribute"] + >(url); } - /** - * Update the distinct-attribute. - * - * @param distinctAttribute - Field name of the distinct-attribute - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-distinct-attribute} */ async updateDistinctAttribute( - distinctAttribute: DistinctAttribute, + distinctAttribute: IndividualSettings["distinctAttribute"], ): Promise { const url = `indexes/${this.uid}/settings/distinct-attribute`; const task = await this.httpRequest.put(url, distinctAttribute); @@ -888,11 +816,7 @@ class Index = Record> { return new EnqueuedTask(task); } - /** - * Reset the distinct-attribute. - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-distinct-attribute} */ async resetDistinctAttribute(): Promise { const url = `indexes/${this.uid}/settings/distinct-attribute`; const task = await this.httpRequest.delete(url); @@ -906,25 +830,19 @@ class Index = Record> { /// FILTERABLE ATTRIBUTES /// - /** - * Get the filterable-attributes - * - * @returns Promise containing an array of filterable-attributes - */ - async getFilterableAttributes(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-filterable-attributes} */ + async getFilterableAttributes(): Promise< + IndividualSettings["filterableAttributes"] + > { const url = `indexes/${this.uid}/settings/filterable-attributes`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["filterableAttributes"] + >(url); } - /** - * Update the filterable-attributes. - * - * @param filterableAttributes - Array of strings containing the attributes - * that can be used as filters at query time - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-filterable-attributes} */ async updateFilterableAttributes( - filterableAttributes: FilterableAttributes, + filterableAttributes: IndividualSettings["filterableAttributes"], ): Promise { const url = `indexes/${this.uid}/settings/filterable-attributes`; const task = await this.httpRequest.put(url, filterableAttributes); @@ -932,11 +850,7 @@ class Index = Record> { return new EnqueuedTask(task); } - /** - * Reset the filterable-attributes. - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-filterable-attributes} */ async resetFilterableAttributes(): Promise { const url = `indexes/${this.uid}/settings/filterable-attributes`; const task = await this.httpRequest.delete(url); @@ -950,25 +864,19 @@ class Index = Record> { /// SORTABLE ATTRIBUTES /// - /** - * Get the sortable-attributes - * - * @returns Promise containing array of sortable-attributes - */ - async getSortableAttributes(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-sortable-attributes} */ + async getSortableAttributes(): Promise< + IndividualSettings["sortableAttributes"] + > { const url = `indexes/${this.uid}/settings/sortable-attributes`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["sortableAttributes"] + >(url); } - /** - * Update the sortable-attributes. - * - * @param sortableAttributes - Array of strings containing the attributes that - * can be used to sort search results at query time - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-sortable-attributes} */ async updateSortableAttributes( - sortableAttributes: SortableAttributes, + sortableAttributes: IndividualSettings["sortableAttributes"], ): Promise { const url = `indexes/${this.uid}/settings/sortable-attributes`; const task = await this.httpRequest.put(url, sortableAttributes); @@ -976,11 +884,7 @@ class Index = Record> { return new EnqueuedTask(task); } - /** - * Reset the sortable-attributes. - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-sortable-attributes} */ async resetSortableAttributes(): Promise { const url = `indexes/${this.uid}/settings/sortable-attributes`; const task = await this.httpRequest.delete(url); @@ -994,25 +898,19 @@ class Index = Record> { /// SEARCHABLE ATTRIBUTE /// - /** - * Get the searchable-attributes - * - * @returns Promise containing array of searchable-attributes - */ - async getSearchableAttributes(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-searchable-attributes} */ + async getSearchableAttributes(): Promise< + IndividualSettings["searchableAttributes"] + > { const url = `indexes/${this.uid}/settings/searchable-attributes`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["searchableAttributes"] + >(url); } - /** - * Update the searchable-attributes. - * - * @param searchableAttributes - Array of strings that contains searchable - * attributes sorted by order of importance(most to least important) - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-searchable-attributes} */ async updateSearchableAttributes( - searchableAttributes: SearchableAttributes, + searchableAttributes: IndividualSettings["searchableAttributes"], ): Promise { const url = `indexes/${this.uid}/settings/searchable-attributes`; const task = await this.httpRequest.put(url, searchableAttributes); @@ -1020,11 +918,7 @@ class Index = Record> { return new EnqueuedTask(task); } - /** - * Reset the searchable-attributes. - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-searchable-attributes} */ async resetSearchableAttributes(): Promise { const url = `indexes/${this.uid}/settings/searchable-attributes`; const task = await this.httpRequest.delete(url); @@ -1038,25 +932,19 @@ class Index = Record> { /// DISPLAYED ATTRIBUTE /// - /** - * Get the displayed-attributes - * - * @returns Promise containing array of displayed-attributes - */ - async getDisplayedAttributes(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-displayed-attributes} */ + async getDisplayedAttributes(): Promise< + IndividualSettings["displayedAttributes"] + > { const url = `indexes/${this.uid}/settings/displayed-attributes`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["displayedAttributes"] + >(url); } - /** - * Update the displayed-attributes. - * - * @param displayedAttributes - Array of strings that contains attributes of - * an index to display - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-displayed-attributes} */ async updateDisplayedAttributes( - displayedAttributes: DisplayedAttributes, + displayedAttributes: IndividualSettings["displayedAttributes"], ): Promise { const url = `indexes/${this.uid}/settings/displayed-attributes`; const task = await this.httpRequest.put(url, displayedAttributes); @@ -1064,11 +952,7 @@ class Index = Record> { return new EnqueuedTask(task); } - /** - * Reset the displayed-attributes. - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-displayed-attributes} */ async resetDisplayedAttributes(): Promise { const url = `indexes/${this.uid}/settings/displayed-attributes`; const task = await this.httpRequest.delete(url); @@ -1082,25 +966,19 @@ class Index = Record> { /// TYPO TOLERANCE /// - /** - * Get the typo tolerance settings. - * - * @returns Promise containing the typo tolerance settings. - */ - async getTypoTolerance(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-typo-tolerance-settings} */ + async getTypoTolerance(): Promise< + IndividualSettings["typoTolerance"] + > { const url = `indexes/${this.uid}/settings/typo-tolerance`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["typoTolerance"] + >(url); } - /** - * Update the typo tolerance settings. - * - * @param typoTolerance - Object containing the custom typo tolerance - * settings. - * @returns Promise containing object of the enqueued update - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-typo-tolerance-settings} */ async updateTypoTolerance( - typoTolerance: TypoTolerance, + typoTolerance: IndividualSettings["typoTolerance"], ): Promise { const url = `indexes/${this.uid}/settings/typo-tolerance`; const task = await this.httpRequest.patch(url, typoTolerance); @@ -1110,11 +988,7 @@ class Index = Record> { return task; } - /** - * Reset the typo tolerance settings. - * - * @returns Promise containing object of the enqueued update - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-typo-tolerance-settings} */ async resetTypoTolerance(): Promise { const url = `indexes/${this.uid}/settings/typo-tolerance`; const task = await this.httpRequest.delete(url); @@ -1128,34 +1002,25 @@ class Index = Record> { /// FACETING /// - /** - * Get the faceting settings. - * - * @returns Promise containing object of faceting index settings - */ - async getFaceting(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-faceting-settings} */ + async getFaceting(): Promise { const url = `indexes/${this.uid}/settings/faceting`; - return await this.httpRequest.get(url); + return await this.httpRequest.get( + url, + ); } - /** - * Update the faceting settings. - * - * @param faceting - Faceting index settings object - * @returns Promise containing an EnqueuedTask - */ - async updateFaceting(faceting: Faceting): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-faceting-settings} */ + async updateFaceting( + faceting: IndividualSettings["faceting"], + ): Promise { const url = `indexes/${this.uid}/settings/faceting`; const task = await this.httpRequest.patch(url, faceting); return new EnqueuedTask(task); } - /** - * Reset the faceting settings. - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-faceting-settings} */ async resetFaceting(): Promise { const url = `indexes/${this.uid}/settings/faceting`; const task = await this.httpRequest.delete(url); @@ -1167,24 +1032,19 @@ class Index = Record> { /// SEPARATOR TOKENS /// - /** - * Get the list of all separator tokens. - * - * @returns Promise containing array of separator tokens - */ - async getSeparatorTokens(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-separator-tokens} */ + async getSeparatorTokens(): Promise< + IndividualSettings["separatorTokens"] + > { const url = `indexes/${this.uid}/settings/separator-tokens`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["separatorTokens"] + >(url); } - /** - * Update the list of separator tokens. Overwrite the old list. - * - * @param separatorTokens - Array that contains separator tokens. - * @returns Promise containing an EnqueuedTask or null - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-separator-tokens} */ async updateSeparatorTokens( - separatorTokens: SeparatorTokens, + separatorTokens: IndividualSettings["separatorTokens"], ): Promise { const url = `indexes/${this.uid}/settings/separator-tokens`; const task = await this.httpRequest.put(url, separatorTokens); @@ -1192,11 +1052,7 @@ class Index = Record> { return new EnqueuedTask(task); } - /** - * Reset the separator tokens list to its default value - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-separator-tokens} */ async resetSeparatorTokens(): Promise { const url = `indexes/${this.uid}/settings/separator-tokens`; const task = await this.httpRequest.delete(url); @@ -1210,24 +1066,19 @@ class Index = Record> { /// NON-SEPARATOR TOKENS /// - /** - * Get the list of all non-separator tokens. - * - * @returns Promise containing array of non-separator tokens - */ - async getNonSeparatorTokens(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-non-separator-tokens} */ + async getNonSeparatorTokens(): Promise< + IndividualSettings["nonSeparatorTokens"] + > { const url = `indexes/${this.uid}/settings/non-separator-tokens`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["nonSeparatorTokens"] + >(url); } - /** - * Update the list of non-separator tokens. Overwrite the old list. - * - * @param nonSeparatorTokens - Array that contains non-separator tokens. - * @returns Promise containing an EnqueuedTask or null - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-non-separator-tokens} */ async updateNonSeparatorTokens( - nonSeparatorTokens: NonSeparatorTokens, + nonSeparatorTokens: IndividualSettings["nonSeparatorTokens"], ): Promise { const url = `indexes/${this.uid}/settings/non-separator-tokens`; const task = await this.httpRequest.put(url, nonSeparatorTokens); @@ -1235,11 +1086,7 @@ class Index = Record> { return new EnqueuedTask(task); } - /** - * Reset the non-separator tokens list to its default value - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-non-separator-tokens} */ async resetNonSeparatorTokens(): Promise { const url = `indexes/${this.uid}/settings/non-separator-tokens`; const task = await this.httpRequest.delete(url); @@ -1253,34 +1100,25 @@ class Index = Record> { /// DICTIONARY /// - /** - * Get the dictionary settings of a Meilisearch index. - * - * @returns Promise containing the dictionary settings - */ - async getDictionary(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-dictionary} */ + async getDictionary(): Promise { const url = `indexes/${this.uid}/settings/dictionary`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["dictionary"] + >(url); } - /** - * Update the dictionary settings. Overwrite the old settings. - * - * @param dictionary - Array that contains the new dictionary settings. - * @returns Promise containing an EnqueuedTask or null - */ - async updateDictionary(dictionary: Dictionary): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-dictionary} */ + async updateDictionary( + dictionary: IndividualSettings["dictionary"], + ): Promise { const url = `indexes/${this.uid}/settings/dictionary`; const task = await this.httpRequest.put(url, dictionary); return new EnqueuedTask(task); } - /** - * Reset the dictionary settings to its default value - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-dictionary} */ async resetDictionary(): Promise { const url = `indexes/${this.uid}/settings/dictionary`; const task = await this.httpRequest.delete(url); @@ -1294,25 +1132,19 @@ class Index = Record> { /// PROXIMITY PRECISION /// - /** - * Get the proximity precision settings of a Meilisearch index. - * - * @returns Promise containing the proximity precision settings - */ - async getProximityPrecision(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-proximity-precision-settings} */ + async getProximityPrecision(): Promise< + IndividualSettings["proximityPrecision"] + > { const url = `indexes/${this.uid}/settings/proximity-precision`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["proximityPrecision"] + >(url); } - /** - * Update the proximity precision settings. Overwrite the old settings. - * - * @param proximityPrecision - String that contains the new proximity - * precision settings. - * @returns Promise containing an EnqueuedTask or null - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-proximity-precision-settings} */ async updateProximityPrecision( - proximityPrecision: ProximityPrecision, + proximityPrecision: IndividualSettings["proximityPrecision"], ): Promise { const url = `indexes/${this.uid}/settings/proximity-precision`; const task = await this.httpRequest.put(url, proximityPrecision); @@ -1320,11 +1152,7 @@ class Index = Record> { return new EnqueuedTask(task); } - /** - * Reset the proximity precision settings to its default value - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-proximity-precision-settings} */ async resetProximityPrecision(): Promise { const url = `indexes/${this.uid}/settings/proximity-precision`; const task = await this.httpRequest.delete(url); @@ -1338,34 +1166,25 @@ class Index = Record> { /// EMBEDDERS /// - /** - * Get the embedders settings of a Meilisearch index. - * - * @returns Promise containing the embedders settings - */ - async getEmbedders(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-embedder-settings} */ + async getEmbedders(): Promise { const url = `indexes/${this.uid}/settings/embedders`; - return await this.httpRequest.get(url); + return await this.httpRequest.get( + url, + ); } - /** - * Update the embedders settings. Overwrite the old settings. - * - * @param embedders - Object that contains the new embedders settings. - * @returns Promise containing an EnqueuedTask or null - */ - async updateEmbedders(embedders: Embedders): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-embedder-settings} */ + async updateEmbedders( + embedders: IndividualSettings["embedders"], + ): Promise { const url = `indexes/${this.uid}/settings/embedders`; const task = await this.httpRequest.patch(url, embedders); return new EnqueuedTask(task); } - /** - * Reset the embedders settings to its default value - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-embedder-settings} */ async resetEmbedders(): Promise { const url = `indexes/${this.uid}/settings/embedders`; const task = await this.httpRequest.delete(url); @@ -1379,24 +1198,19 @@ class Index = Record> { /// SEARCHCUTOFFMS SETTINGS /// - /** - * Get the SearchCutoffMs settings. - * - * @returns Promise containing object of SearchCutoffMs settings - */ - async getSearchCutoffMs(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-search-cutoff} */ + async getSearchCutoffMs(): Promise< + IndividualSettings["searchCutoffMs"] + > { const url = `indexes/${this.uid}/settings/search-cutoff-ms`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["searchCutoffMs"] + >(url); } - /** - * Update the SearchCutoffMs settings. - * - * @param searchCutoffMs - Object containing SearchCutoffMsSettings - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-search-cutoff} */ async updateSearchCutoffMs( - searchCutoffMs: SearchCutoffMs, + searchCutoffMs: IndividualSettings["searchCutoffMs"], ): Promise { const url = `indexes/${this.uid}/settings/search-cutoff-ms`; const task = await this.httpRequest.put(url, searchCutoffMs); @@ -1404,11 +1218,7 @@ class Index = Record> { return new EnqueuedTask(task); } - /** - * Reset the SearchCutoffMs settings. - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-search-cutoff} */ async resetSearchCutoffMs(): Promise { const url = `indexes/${this.uid}/settings/search-cutoff-ms`; const task = await this.httpRequest.delete(url); @@ -1420,24 +1230,19 @@ class Index = Record> { /// LOCALIZED ATTRIBUTES SETTINGS /// - /** - * Get the localized attributes settings. - * - * @returns Promise containing object of localized attributes settings - */ - async getLocalizedAttributes(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-localized-attributes-settings} */ + async getLocalizedAttributes(): Promise< + IndividualSettings["localizedAttributes"] + > { const url = `indexes/${this.uid}/settings/localized-attributes`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["localizedAttributes"] + >(url); } - /** - * Update the localized attributes settings. - * - * @param localizedAttributes - Localized attributes object - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-localized-attribute-settings} */ async updateLocalizedAttributes( - localizedAttributes: LocalizedAttributes, + localizedAttributes: IndividualSettings["localizedAttributes"], ): Promise { const url = `indexes/${this.uid}/settings/localized-attributes`; const task = await this.httpRequest.put(url, localizedAttributes); @@ -1445,11 +1250,7 @@ class Index = Record> { return new EnqueuedTask(task); } - /** - * Reset the localized attributes settings. - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-localized-attributes-settings} */ async resetLocalizedAttributes(): Promise { const url = `indexes/${this.uid}/settings/localized-attributes`; const task = await this.httpRequest.delete(url); @@ -1461,33 +1262,24 @@ class Index = Record> { /// FACET SEARCH SETTINGS /// - /** - * Get the facet search settings. - * - * @returns Promise containing object of facet search settings - */ - async getFacetSearch(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-facet-search-settings} */ + async getFacetSearch(): Promise { const url = `indexes/${this.uid}/settings/facet-search`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["facetSearch"] + >(url); } - /** - * Update the facet search settings. - * - * @param facetSearch - Boolean value - * @returns Promise containing an EnqueuedTask - */ - async updateFacetSearch(facetSearch: boolean): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-facet-search-settings} */ + async updateFacetSearch( + facetSearch: IndividualSettings["facetSearch"], + ): Promise { const url = `indexes/${this.uid}/settings/facet-search`; const task = await this.httpRequest.put(url, facetSearch); return new EnqueuedTask(task); } - /** - * Reset the facet search settings. - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-facet-search-settings} */ async resetFacetSearch(): Promise { const url = `indexes/${this.uid}/settings/facet-search`; const task = await this.httpRequest.delete(url); @@ -1498,33 +1290,26 @@ class Index = Record> { /// PREFIX SEARCH SETTINGS /// - /** - * Get the prefix search settings. - * - * @returns Promise containing object of prefix search settings - */ - async getPrefixSearch(): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-prefix-search-settings} */ + async getPrefixSearch(): Promise< + IndividualSettings["prefixSearch"] + > { const url = `indexes/${this.uid}/settings/prefix-search`; - return await this.httpRequest.get(url); + return await this.httpRequest.get< + IndividualSettings["prefixSearch"] + >(url); } - /** - * Update the prefix search settings. - * - * @param prefixSearch - PrefixSearch value - * @returns Promise containing an EnqueuedTask - */ - async updatePrefixSearch(prefixSearch: PrefixSearch): Promise { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-prefix-search-settings} */ + async updatePrefixSearch( + prefixSearch: IndividualSettings["prefixSearch"], + ): Promise { const url = `indexes/${this.uid}/settings/prefix-search`; const task = await this.httpRequest.put(url, prefixSearch); return new EnqueuedTask(task); } - /** - * Reset the prefix search settings. - * - * @returns Promise containing an EnqueuedTask - */ + /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-prefix-search-settings} */ async resetPrefixSearch(): Promise { const url = `indexes/${this.uid}/settings/prefix-search`; const task = await this.httpRequest.delete(url); diff --git a/src/meilisearch.ts b/src/meilisearch.ts index b6899df9e..4ae4ebd4f 100644 --- a/src/meilisearch.ts +++ b/src/meilisearch.ts @@ -32,8 +32,8 @@ import type { BatchesResults, BatchesQuery, MultiSearchResponseOrSearchResponse, -} from "./types.js"; -import { ErrorStatusCode } from "./types.js"; +} from "./types/index.js"; +import { ErrorStatusCode } from "./types/index.js"; import { HttpRequests } from "./http-requests.js"; import { TaskClient, type Task } from "./task.js"; import { EnqueuedTask } from "./enqueued-task.js"; diff --git a/src/task.ts b/src/task.ts index 1c668f4a7..aece8b9c2 100644 --- a/src/task.ts +++ b/src/task.ts @@ -8,8 +8,8 @@ import type { CancelTasksQuery, TasksResultsObject, DeleteTasksQuery, -} from "./types.js"; -import { TaskStatus } from "./types.js"; +} from "./types/index.js"; +import { TaskStatus } from "./types/index.js"; import { HttpRequests, toQueryParams } from "./http-requests.js"; import { sleep } from "./utils.js"; import { EnqueuedTask } from "./enqueued-task.js"; diff --git a/src/token.ts b/src/token.ts index a0d1ef652..2c5e2ee9f 100644 --- a/src/token.ts +++ b/src/token.ts @@ -1,5 +1,8 @@ import type { webcrypto } from "node:crypto"; -import type { TenantTokenGeneratorOptions, TokenSearchRules } from "./types.js"; +import type { + TenantTokenGeneratorOptions, + TokenSearchRules, +} from "./types/index.js"; function getOptionsWithDefaults(options: TenantTokenGeneratorOptions) { const { diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 000000000..169e26986 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,2 @@ +export * from "./settings.js"; +export * from "./types.js"; diff --git a/src/types/settings.ts b/src/types/settings.ts new file mode 100644 index 000000000..2d47eed0c --- /dev/null +++ b/src/types/settings.ts @@ -0,0 +1,127 @@ +import type { NonNullableDeepRecordValues } from "./shared.js"; + +/** {@link https://www.meilisearch.com/docs/reference/api/settings#proximity-precision} */ +export type ProximityPrecision = "byWord" | "byAttribute"; + +/** @see `minWordSizeForTypos` at {@link https://www.meilisearch.com/docs/reference/api/settings#typo-tolerance} */ +export type MinWordSizeForTypos = { + oneTypo?: number | null; + twoTypos?: number | null; +}; + +/** {@link https://www.meilisearch.com/docs/reference/api/settings#typo-tolerance} */ +export type TypoTolerance = { + enabled?: boolean | null; + minWordSizeForTypos?: MinWordSizeForTypos | null; + disableOnWords?: string[] | null; + disableOnAttributes?: string[] | null; +}; + +/** @see `sortFacetValuesBy` at {@link https://www.meilisearch.com/docs/reference/api/settings#faceting} */ +export type FacetOrder = "alpha" | "count"; + +/** {@link https://www.meilisearch.com/docs/reference/api/settings#faceting} */ +export type Faceting = { + maxValuesPerFacet?: number | null; + sortFacetValuesBy?: Record | null; +}; + +/** {@link https://www.meilisearch.com/docs/reference/api/settings#pagination} */ +export type PaginationSettings = { maxTotalHits?: number | null }; + +/** @see `distribution` at {@link https://www.meilisearch.com/docs/reference/api/settings#embedders-experimental} */ +export type Distribution = { + mean: number; + sigma: number; +}; + +/** @see `source` at {@link https://www.meilisearch.com/docs/reference/api/settings#embedders-experimental} */ +export type EmbedderSource = + | "openAi" + | "huggingFace" + | "ollama" + | "userProvided" + | "rest"; + +/** {@link https://www.meilisearch.com/docs/reference/api/settings#embedders-experimental} */ +export type EmbeddingSettings = { + source?: EmbedderSource | null; + model?: string | null; + revision?: string | null; + apiKey?: string | null; + dimensions?: number | null; + binaryQuantized?: boolean | null; + documentTemplate?: string | null; + documentTemplateMaxBytes?: number | null; + url?: string | null; + request?: unknown; + response?: unknown; + headers?: Record | null; + distribution?: Distribution | null; +}; + +/** {@link https://www.meilisearch.com/docs/reference/api/settings#localized-attributes} */ +export type LocalizedAttribute = { + attributePatterns: string[] | null; + locales: string[] | null; +}; + +/** {@link https://www.meilisearch.com/docs/reference/api/settings#prefix-search} */ +export type PrefixSearch = "indexingTime" | "disabled"; + +/** A version of {@link Settings} that can be used to update the settings. */ +export type UpdatableSettings = { + /** {@link https://www.meilisearch.com/docs/reference/api/settings#displayed-attributes} */ + displayedAttributes?: string[] | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#searchable-attributes} */ + searchableAttributes?: string[] | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#filterable-attributes} */ + filterableAttributes?: string[] | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#sortable-attributes} */ + sortableAttributes?: string[] | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#ranking-rules} */ + rankingRules?: string[] | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#stop-words} */ + stopWords?: string[] | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#non-separator-tokens} */ + nonSeparatorTokens?: string[] | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#separator-tokens} */ + separatorTokens?: string[] | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#dictionary} */ + dictionary?: string[] | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#synonyms} */ + synonyms?: Record | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#distinct-attribute} */ + distinctAttribute?: string | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#proximity-precision} */ + proximityPrecision?: ProximityPrecision | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#typo-tolerance} */ + typoTolerance?: TypoTolerance | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#faceting} */ + faceting?: Faceting | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#pagination} */ + pagination?: PaginationSettings | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#embedders-experimental} */ + embedders?: Record | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#search-cutoff} */ + searchCutoffMs?: number | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#localized-attributes} */ + localizedAttributes?: LocalizedAttribute[] | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#facet-search} */ + facetSearch?: boolean | null; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#prefix-search} */ + prefixSearch?: PrefixSearch | null; +}; + +/** + * A version of {@link UpdatableSettings}, the first layer of properties of which + * is used to update or get individual settings. + */ +export type IndividualSettings = Required; + +/** + * {@link https://www.meilisearch.com/docs/reference/api/settings#body} + * + * @see `meilisearch_types::settings::Settings` at {@link https://github.com/meilisearch/meilisearch} + */ +export type Settings = NonNullableDeepRecordValues; diff --git a/src/types/shared.ts b/src/types/shared.ts new file mode 100644 index 000000000..e6302be8b --- /dev/null +++ b/src/types/shared.ts @@ -0,0 +1,7 @@ +export type NonNullableDeepRecordValues = { + [P in keyof T]: T[P] extends any[] + ? Array> + : T[P] extends Record + ? NonNullableDeepRecordValues + : NonNullable; +}; diff --git a/src/types.ts b/src/types/types.ts similarity index 86% rename from src/types.ts rename to src/types/types.ts index 2a73fead3..0de77c036 100644 --- a/src/types.ts +++ b/src/types/types.ts @@ -4,8 +4,9 @@ // Definitions: https://github.com/meilisearch/meilisearch-js // TypeScript Version: ^3.8.3 -import { Task } from "./task.js"; -import { Batch } from "./batch.js"; +import { Task } from "../task.js"; +import { Batch } from "../batch.js"; +import type { Settings } from "./settings.js"; export type Config = { host: string; @@ -374,158 +375,6 @@ export type UpdateDocumentsByFunctionOptions = { context?: Record; }; -/* - ** Settings - */ - -export type FilterableAttributes = string[] | null; -export type DistinctAttribute = string | null; -export type SearchableAttributes = string[] | null; -export type SortableAttributes = string[] | null; -export type DisplayedAttributes = string[] | null; -export type RankingRules = string[] | null; -export type StopWords = string[] | null; -export type Synonyms = { - [field: string]: string[]; -} | null; -export type TypoTolerance = { - enabled?: boolean | null; - disableOnAttributes?: string[] | null; - disableOnWords?: string[] | null; - minWordSizeForTypos?: { - oneTypo?: number | null; - twoTypos?: number | null; - }; -} | null; -export type SeparatorTokens = string[] | null; -export type NonSeparatorTokens = string[] | null; -export type Dictionary = string[] | null; -export type ProximityPrecision = "byWord" | "byAttribute"; - -export type Distribution = { - mean: number; - sigma: number; -}; - -export type OpenAiEmbedder = { - source: "openAi"; - model?: string; - apiKey?: string; - documentTemplate?: string; - dimensions?: number; - distribution?: Distribution; - url?: string; - documentTemplateMaxBytes?: number; - binaryQuantized?: boolean; -}; - -export type HuggingFaceEmbedder = { - source: "huggingFace"; - model?: string; - revision?: string; - documentTemplate?: string; - distribution?: Distribution; - documentTemplateMaxBytes?: number; - binaryQuantized?: boolean; -}; - -export type UserProvidedEmbedder = { - source: "userProvided"; - dimensions: number; - distribution?: Distribution; - binaryQuantized?: boolean; -}; - -export type RestEmbedder = { - source: "rest"; - url: string; - apiKey?: string; - dimensions?: number; - documentTemplate?: string; - distribution?: Distribution; - request: Record; - response: Record; - headers?: Record; - documentTemplateMaxBytes?: number; - binaryQuantized?: boolean; -}; - -export type OllamaEmbedder = { - source: "ollama"; - url?: string; - apiKey?: string; - model?: string; - documentTemplate?: string; - distribution?: Distribution; - dimensions?: number; - documentTemplateMaxBytes?: number; - binaryQuantized?: boolean; -}; - -export type Embedder = - | OpenAiEmbedder - | HuggingFaceEmbedder - | UserProvidedEmbedder - | RestEmbedder - | OllamaEmbedder - | null; - -export type Embedders = Record | null; - -export type FacetOrder = "alpha" | "count"; - -export type Faceting = { - maxValuesPerFacet?: number | null; - sortFacetValuesBy?: Record | null; -}; - -export type PaginationSettings = { - maxTotalHits?: number | null; -}; - -export type SearchCutoffMs = number | null; - -export type LocalizedAttribute = { - attributePatterns: string[]; - locales: Locale[]; -}; - -export type LocalizedAttributes = LocalizedAttribute[] | null; - -export type PrefixSearch = "indexingTime" | "disabled"; - -export type Settings = { - filterableAttributes?: FilterableAttributes; - distinctAttribute?: DistinctAttribute; - sortableAttributes?: SortableAttributes; - searchableAttributes?: SearchableAttributes; - displayedAttributes?: DisplayedAttributes; - rankingRules?: RankingRules; - stopWords?: StopWords; - synonyms?: Synonyms; - typoTolerance?: TypoTolerance; - faceting?: Faceting; - pagination?: PaginationSettings; - separatorTokens?: SeparatorTokens; - nonSeparatorTokens?: NonSeparatorTokens; - dictionary?: Dictionary; - proximityPrecision?: ProximityPrecision; - embedders?: Embedders; - searchCutoffMs?: SearchCutoffMs; - localizedAttributes?: LocalizedAttributes; - - /** - * Enable facet searching on all the filters of an index (requires Meilisearch - * 1.12.0 or later) - */ - facetSearch?: boolean; - /** - * Enable the ability to search a word by prefix on an index (requires - * Meilisearch 1.12.0 or later) - */ - prefixSearch?: "indexingTime" | "disabled"; -}; - /* ** TASKS */ @@ -590,70 +439,47 @@ export type EnqueuedTaskObject = { canceledBy: number; }; -export type TaskObject = Omit & { - uid: number; - /** The UID of the batch that the task belongs to (`null` for enqueued tasks) */ - batchUid: number | null; - details: { - // Number of documents sent - receivedDocuments?: number; - - // Number of documents successfully indexed/updated in Meilisearch - indexedDocuments?: number; - - // Number of deleted documents - deletedDocuments?: number; - - // Number of documents found on a batch-delete - providedIds?: number; - - // Primary key on index creation - primaryKey?: string; - - // Ranking rules on settings actions - rankingRules?: RankingRules; - - // Searchable attributes on settings actions - searchableAttributes?: SearchableAttributes; +export type TaskObject = Settings & + Omit & { + uid: number; + /** The UID of the batch that the task belongs to (`null` for enqueued tasks) */ + batchUid: number | null; + details: { + // Number of documents sent + receivedDocuments?: number; - // Displayed attributes on settings actions - displayedAttributes?: DisplayedAttributes; + // Number of documents successfully indexed/updated in Meilisearch + indexedDocuments?: number; - // Filterable attributes on settings actions - filterableAttributes?: FilterableAttributes; + // Number of deleted documents + deletedDocuments?: number; - // Sortable attributes on settings actions - sortableAttributes?: SortableAttributes; + // Number of documents found on a batch-delete + providedIds?: number; - // Stop words on settings actions - stopWords?: StopWords; + // Primary key on index creation + primaryKey?: string; - // Stop words on settings actions - synonyms?: Synonyms; + // Object containing the payload originating the `indexSwap` task creation + swaps?: SwapIndexesParams; - // Distinct attribute on settings actions - distinctAttribute?: DistinctAttribute; + // Number of tasks that matched the originalQuery filter + matchedTasks?: number; - // Object containing the payload originating the `indexSwap` task creation - swaps?: SwapIndexesParams; + // Number of tasks that were canceled + canceledTasks?: number; - // Number of tasks that matched the originalQuery filter - matchedTasks?: number; + // Number of tasks that were deleted + deletedTasks?: number; - // Number of tasks that were canceled - canceledTasks?: number; - - // Number of tasks that were deleted - deletedTasks?: number; - - // Query parameters used to filter the tasks - originalFilter?: string; + // Query parameters used to filter the tasks + originalFilter?: string; + }; + error: MeiliSearchErrorResponse | null; + duration: string; + startedAt: string; + finishedAt: string; }; - error: MeiliSearchErrorResponse | null; - duration: string; - startedAt: string; - finishedAt: string; -}; export type SwapIndexesParams = Array<{ indexes: string[]; diff --git a/tests/dictionary.test.ts b/tests/dictionary.test.ts index b063d93af..9b74c9ccf 100644 --- a/tests/dictionary.test.ts +++ b/tests/dictionary.test.ts @@ -28,7 +28,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default dictionary`, async () => { const client = await getClient(permission); - const response: string[] = await client.index(index.uid).getDictionary(); + const response = await client.index(index.uid).getDictionary(); expect(response).toEqual([]); }); @@ -41,7 +41,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateDictionary(newDictionary); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client.index(index.uid).getDictionary(); + const response = await client.index(index.uid).getDictionary(); expect(response).toEqual(newDictionary); }); @@ -54,7 +54,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateDictionary(newDictionary); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client.index(index.uid).getDictionary(); + const response = await client.index(index.uid).getDictionary(); expect(response).toEqual([]); }); @@ -66,7 +66,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .resetDictionary(); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client.index(index.uid).getDictionary(); + const response = await client.index(index.uid).getDictionary(); expect(response).toEqual([]); }); diff --git a/tests/displayed_attributes.test.ts b/tests/displayed_attributes.test.ts index d3937ff75..39e399997 100644 --- a/tests/displayed_attributes.test.ts +++ b/tests/displayed_attributes.test.ts @@ -1,5 +1,5 @@ import { afterAll, expect, test, describe, beforeEach } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { clearAllIndexes, config, diff --git a/tests/distinct_attribute.test.ts b/tests/distinct_attribute.test.ts index ca9cf12d5..427558f2d 100644 --- a/tests/distinct_attribute.test.ts +++ b/tests/distinct_attribute.test.ts @@ -1,5 +1,5 @@ import { afterAll, expect, test, describe, beforeEach } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { clearAllIndexes, config, diff --git a/tests/documents.test.ts b/tests/documents.test.ts index 996f9bc92..d17e86394 100644 --- a/tests/documents.test.ts +++ b/tests/documents.test.ts @@ -1,5 +1,5 @@ import { afterAll, expect, test, describe, beforeEach } from "vitest"; -import { ErrorStatusCode, TaskStatus, TaskTypes } from "../src/types.js"; +import { ErrorStatusCode, TaskStatus, TaskTypes } from "../src/types/index.js"; import { clearAllIndexes, config, diff --git a/tests/dump.test.ts b/tests/dump.test.ts index 07085f7bd..c2258fecb 100644 --- a/tests/dump.test.ts +++ b/tests/dump.test.ts @@ -1,5 +1,5 @@ import { expect, test, describe, beforeEach } from "vitest"; -import { ErrorStatusCode, TaskStatus } from "../src/types.js"; +import { ErrorStatusCode, TaskStatus } from "../src/types/index.js"; import { clearAllIndexes, config, diff --git a/tests/embedders.test.ts b/tests/embedders.test.ts index 0b980c1c8..da33719aa 100644 --- a/tests/embedders.test.ts +++ b/tests/embedders.test.ts @@ -1,6 +1,6 @@ import { afterAll, expect, test, describe, beforeEach } from "vitest"; import { EnqueuedTask } from "../src/enqueued-task.js"; -import type { Embedders } from "../src/types.js"; +import type { IndividualSettings } from "../src/types/index.js"; import { clearAllIndexes, config, @@ -75,14 +75,14 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default embedders`, async () => { const client = await getClient(permission); - const response: Embedders = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).getEmbedders(); expect(response).toEqual(null); }); test(`${permission} key: Update embedders with 'userProvided' source`, async () => { const client = await getClient(permission); - const newEmbedder: Embedders = { + const newEmbedder: IndividualSettings["embedders"] = { default: { source: "userProvided", dimensions: 1, @@ -99,7 +99,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( await client.waitForTask(task.taskUid); - const response: Embedders = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).getEmbedders(); expect(response).toEqual(newEmbedder); expect(response).not.toHaveProperty("documentTemplateMaxBytes"); @@ -107,7 +107,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with 'openAi' source`, async () => { const client = await getClient(permission); - const newEmbedder: Embedders = { + const newEmbedder: IndividualSettings["embedders"] = { default: { source: "openAi", apiKey: "", @@ -129,7 +129,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateEmbedders(newEmbedder); await client.waitForTask(task.taskUid); - const response: Embedders = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).getEmbedders(); expect(response).toEqual({ default: { @@ -141,7 +141,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with 'huggingFace' source`, async () => { const client = await getClient(permission); - const newEmbedder: Embedders = { + const newEmbedder: IndividualSettings["embedders"] = { default: { source: "huggingFace", model: "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", @@ -160,14 +160,14 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateEmbedders(newEmbedder); await client.waitForTask(task.taskUid, { timeOutMs: 60_000 }); - const response: Embedders = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).getEmbedders(); expect(response).toEqual(newEmbedder); }); test(`${permission} key: Update embedders with 'rest' source`, async () => { const client = await getClient(permission); - const newEmbedder: Embedders = { + const newEmbedder: IndividualSettings["embedders"] = { default: { source: "rest", url: "https://api.openai.com/v1/embeddings", @@ -203,7 +203,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateEmbedders(newEmbedder); await client.waitForTask(task.taskUid); - const response: Embedders = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).getEmbedders(); expect(response).toEqual({ default: { @@ -215,7 +215,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with 'ollama' source`, async () => { const client = await getClient(permission); - const newEmbedder: Embedders = { + const newEmbedder: IndividualSettings["embedders"] = { default: { source: "ollama", url: "http://localhost:11434/api/embeddings", @@ -236,7 +236,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateEmbedders(newEmbedder); await client.waitForTask(task.taskUid); - const response: Embedders = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).getEmbedders(); expect(response).toEqual({ default: { @@ -249,7 +249,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with a specific name`, async () => { const client = await getClient(permission); - const newEmbedder: Embedders = { + const newEmbedder: IndividualSettings["embedders"] = { image: { source: "userProvided", dimensions: 512, @@ -261,7 +261,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( await client.waitForTask(task.taskUid); - const response: Embedders = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).getEmbedders(); expect(response).toEqual(newEmbedder); }); @@ -271,7 +271,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const task: EnqueuedTask = await client.index(index.uid).resetEmbedders(); await client.waitForTask(task.taskUid); - const response: Embedders = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).getEmbedders(); expect(response).toEqual(null); }); @@ -331,7 +331,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: search for similar documents`, async () => { const client = await getClient(permission); - const newEmbedder: Embedders = { + const newEmbedder: IndividualSettings["embedders"] = { manual: { source: "userProvided", dimensions: 3, diff --git a/tests/facet_search_settings.test.ts b/tests/facet_search_settings.test.ts index 9b3d1e115..779fef062 100644 --- a/tests/facet_search_settings.test.ts +++ b/tests/facet_search_settings.test.ts @@ -1,5 +1,5 @@ import { afterAll, expect, test, describe, beforeEach } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { clearAllIndexes, config, diff --git a/tests/faceting.test.ts b/tests/faceting.test.ts index cb48b7e1e..46ae8c98a 100644 --- a/tests/faceting.test.ts +++ b/tests/faceting.test.ts @@ -6,7 +6,7 @@ import { afterAll, beforeAll, } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { clearAllIndexes, config, diff --git a/tests/filterable_attributes.test.ts b/tests/filterable_attributes.test.ts index f951e96f7..ae0343c89 100644 --- a/tests/filterable_attributes.test.ts +++ b/tests/filterable_attributes.test.ts @@ -1,5 +1,5 @@ import { expect, test, describe, beforeEach, afterAll } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { clearAllIndexes, config, @@ -28,11 +28,9 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default attributes for filtering`, async () => { const client = await getClient(permission); - const response: string[] = await client - .index(index.uid) - .getFilterableAttributes(); + const response = await client.index(index.uid).getFilterableAttributes(); - expect(response.sort()).toEqual([]); + expect(response?.sort()).toEqual([]); }); test(`${permission} key: Update attributes for filtering`, async () => { @@ -43,9 +41,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateFilterableAttributes(newFilterableAttributes); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getFilterableAttributes(); + const response = await client.index(index.uid).getFilterableAttributes(); expect(response).toEqual(newFilterableAttributes); }); @@ -56,11 +52,9 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateFilterableAttributes(null); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getFilterableAttributes(); + const response = await client.index(index.uid).getFilterableAttributes(); - expect(response.sort()).toEqual([]); + expect(response?.sort()).toEqual([]); }); test(`${permission} key: Reset attributes for filtering`, async () => { @@ -68,11 +62,9 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const task = await client.index(index.uid).resetFilterableAttributes(); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getFilterableAttributes(); + const response = await client.index(index.uid).getFilterableAttributes(); - expect(response.sort()).toEqual([]); + expect(response?.sort()).toEqual([]); }); }, ); diff --git a/tests/get_search.test.ts b/tests/get_search.test.ts index 158fe971b..fd7220cf4 100644 --- a/tests/get_search.test.ts +++ b/tests/get_search.test.ts @@ -1,5 +1,5 @@ import { expect, test, describe, afterAll, beforeAll } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { EnqueuedTask } from "../src/enqueued-task.js"; import { clearAllIndexes, diff --git a/tests/index.test.ts b/tests/index.test.ts index 94c1918b3..14f58936f 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -1,5 +1,5 @@ import { expect, test, describe, beforeEach, afterAll } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { clearAllIndexes, config, diff --git a/tests/keys.test.ts b/tests/keys.test.ts index c88dc71de..30792cb0c 100644 --- a/tests/keys.test.ts +++ b/tests/keys.test.ts @@ -1,6 +1,6 @@ import { expect, test, describe, beforeEach, afterAll } from "vitest"; import { MeiliSearch } from "../src/index.js"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { clearAllIndexes, config, diff --git a/tests/localized_attributes.test.ts b/tests/localized_attributes.test.ts index 56d656ef9..81d4755ab 100644 --- a/tests/localized_attributes.test.ts +++ b/tests/localized_attributes.test.ts @@ -6,7 +6,10 @@ import { expect, test, } from "vitest"; -import { ErrorStatusCode, type LocalizedAttributes } from "../src/types.js"; +import { + ErrorStatusCode, + type IndividualSettings, +} from "../src/types/index.js"; import { clearAllIndexes, config, @@ -45,9 +48,8 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update localizedAttributes to valid value`, async () => { const client = await getClient(permission); - const newLocalizedAttributes: LocalizedAttributes = [ - { attributePatterns: ["title"], locales: ["eng"] }, - ]; + const newLocalizedAttributes: IndividualSettings["localizedAttributes"] = + [{ attributePatterns: ["title"], locales: ["eng"] }]; const task = await client .index(index.uid) .updateLocalizedAttributes(newLocalizedAttributes); @@ -87,7 +89,8 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Reset localizedAttributes`, async () => { const client = await getClient(permission); - const newLocalizedAttributes: LocalizedAttributes = []; + const newLocalizedAttributes: IndividualSettings["localizedAttributes"] = + []; const updateTask = await client .index(index.uid) .updateLocalizedAttributes(newLocalizedAttributes); diff --git a/tests/non_separator_tokens.test.ts b/tests/non_separator_tokens.test.ts index 78518bb91..6fe4de81c 100644 --- a/tests/non_separator_tokens.test.ts +++ b/tests/non_separator_tokens.test.ts @@ -28,9 +28,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default non separator tokens`, async () => { const client = await getClient(permission); - const response: string[] = await client - .index(index.uid) - .getNonSeparatorTokens(); + const response = await client.index(index.uid).getNonSeparatorTokens(); expect(response).toEqual([]); }); @@ -43,9 +41,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateNonSeparatorTokens(newNonSeparatorTokens); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getNonSeparatorTokens(); + const response = await client.index(index.uid).getNonSeparatorTokens(); expect(response).toEqual(newNonSeparatorTokens); }); @@ -58,9 +54,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateNonSeparatorTokens(newNonSeparatorTokens); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getNonSeparatorTokens(); + const response = await client.index(index.uid).getNonSeparatorTokens(); expect(response).toEqual([]); }); @@ -72,9 +66,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .resetNonSeparatorTokens(); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getNonSeparatorTokens(); + const response = await client.index(index.uid).getNonSeparatorTokens(); expect(response).toEqual([]); }); diff --git a/tests/pagination.test.ts b/tests/pagination.test.ts index 48e3dfda2..ea0547a55 100644 --- a/tests/pagination.test.ts +++ b/tests/pagination.test.ts @@ -6,7 +6,7 @@ afterAll, beforeAll, } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { clearAllIndexes, config, diff --git a/tests/prefix_search_settings.test.ts b/tests/prefix_search_settings.test.ts index cf6fdd7e2..5e5cc7e68 100644 --- a/tests/prefix_search_settings.test.ts +++ b/tests/prefix_search_settings.test.ts @@ -1,5 +1,5 @@ import { afterAll, expect, test, describe, beforeEach } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { clearAllIndexes, config, diff --git a/tests/proximity_precision.test.ts b/tests/proximity_precision.test.ts index 1a73d4eb9..8598c3566 100644 --- a/tests/proximity_precision.test.ts +++ b/tests/proximity_precision.test.ts @@ -28,9 +28,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default proximity precision`, async () => { const client = await getClient(permission); - const response: string = await client - .index(index.uid) - .getProximityPrecision(); + const response = await client.index(index.uid).getProximityPrecision(); expect(response).toEqual("byWord"); }); @@ -43,9 +41,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateProximityPrecision(newProximityPrecision); await client.index(index.uid).waitForTask(task.taskUid); - const response: string = await client - .index(index.uid) - .getProximityPrecision(); + const response = await client.index(index.uid).getProximityPrecision(); expect(response).toEqual(newProximityPrecision); }); @@ -58,9 +54,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateProximityPrecision(newProximityPrecision); await client.index(index.uid).waitForTask(task.taskUid); - const response: string = await client - .index(index.uid) - .getProximityPrecision(); + const response = await client.index(index.uid).getProximityPrecision(); expect(response).toEqual(newProximityPrecision); }); @@ -72,9 +66,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .resetProximityPrecision(); await client.index(index.uid).waitForTask(task.taskUid); - const response: string = await client - .index(index.uid) - .getProximityPrecision(); + const response = await client.index(index.uid).getProximityPrecision(); expect(response).toEqual("byWord"); }); diff --git a/tests/ranking_rules.test.ts b/tests/ranking_rules.test.ts index 42f4951f3..59b675d14 100644 --- a/tests/ranking_rules.test.ts +++ b/tests/ranking_rules.test.ts @@ -1,5 +1,5 @@ import { expect, test, describe, beforeEach, afterAll } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { EnqueuedTask } from "../src/enqueued-task.js"; import { clearAllIndexes, @@ -39,9 +39,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default ranking rules`, async () => { const client = await getClient(permission); - const response: string[] = await client - .index(index.uid) - .getRankingRules(); + const response = await client.index(index.uid).getRankingRules(); expect(response).toEqual(defaultRankingRules); }); @@ -53,9 +51,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateRankingRules(newRankingRules); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getRankingRules(); + const response = await client.index(index.uid).getRankingRules(); expect(response).toEqual(newRankingRules); }); @@ -67,9 +63,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateRankingRules(null); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getRankingRules(); + const response = await client.index(index.uid).getRankingRules(); expect(response).toEqual(defaultRankingRules); }); @@ -81,9 +75,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .resetRankingRules(); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getRankingRules(); + const response = await client.index(index.uid).getRankingRules(); expect(response).toEqual(defaultRankingRules); }); diff --git a/tests/raw_document.test.ts b/tests/raw_document.test.ts index 96c80286a..bb11d67c1 100644 --- a/tests/raw_document.test.ts +++ b/tests/raw_document.test.ts @@ -4,7 +4,7 @@ import { config, getClient, } from "./utils/meilisearch-test-utils.js"; -import { TaskStatus, ContentTypeEnum } from "../src/types.js"; +import { TaskStatus, ContentTypeEnum } from "../src/types/index.js"; beforeEach(async () => { await clearAllIndexes(config); diff --git a/tests/search.test.ts b/tests/search.test.ts index c51c84956..b381f033e 100644 --- a/tests/search.test.ts +++ b/tests/search.test.ts @@ -6,11 +6,11 @@ import { afterAll, beforeAll, } from "vitest"; -import { ErrorStatusCode, MatchingStrategies } from "../src/types.js"; +import { ErrorStatusCode, MatchingStrategies } from "../src/types/index.js"; import type { FederatedMultiSearchParams, MultiSearchParams, -} from "../src/types.js"; +} from "../src/types/index.js"; import { EnqueuedTask } from "../src/enqueued-task.js"; import { clearAllIndexes, diff --git a/tests/search_cutoff_ms.test.ts b/tests/search_cutoff_ms.test.ts index 5e08cda01..fc1418279 100644 --- a/tests/search_cutoff_ms.test.ts +++ b/tests/search_cutoff_ms.test.ts @@ -6,7 +6,7 @@ import { expect, test, } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { clearAllIndexes, config, diff --git a/tests/searchable_attributes.test.ts b/tests/searchable_attributes.test.ts index f250e0a8d..5cfd968c3 100644 --- a/tests/searchable_attributes.test.ts +++ b/tests/searchable_attributes.test.ts @@ -6,7 +6,7 @@ import { expect, test, } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { clearAllIndexes, config, @@ -36,9 +36,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default searchable attributes`, async () => { const client = await getClient(permission); - const response: string[] = await client - .index(index.uid) - .getSearchableAttributes(); + const response = await client.index(index.uid).getSearchableAttributes(); expect(response).toEqual(["*"]); }); @@ -51,9 +49,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateSearchableAttributes(newSearchableAttributes); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getSearchableAttributes(); + const response = await client.index(index.uid).getSearchableAttributes(); expect(response).toEqual(newSearchableAttributes); }); @@ -65,9 +61,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateSearchableAttributes(null); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getSearchableAttributes(); + const response = await client.index(index.uid).getSearchableAttributes(); expect(response).toEqual(["*"]); }); @@ -77,9 +71,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const task = await client.index(index.uid).resetSearchableAttributes(); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getSearchableAttributes(); + const response = await client.index(index.uid).getSearchableAttributes(); expect(response).toEqual(["*"]); }); diff --git a/tests/separator_tokens.test.ts b/tests/separator_tokens.test.ts index 6b5379f8c..297dcffab 100644 --- a/tests/separator_tokens.test.ts +++ b/tests/separator_tokens.test.ts @@ -28,9 +28,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default separator tokens`, async () => { const client = await getClient(permission); - const response: string[] = await client - .index(index.uid) - .getSeparatorTokens(); + const response = await client.index(index.uid).getSeparatorTokens(); expect(response).toEqual([]); }); @@ -43,9 +41,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateSeparatorTokens(newSeparatorTokens); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getSeparatorTokens(); + const response = await client.index(index.uid).getSeparatorTokens(); expect(response).toEqual(newSeparatorTokens); }); @@ -58,9 +54,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateSeparatorTokens(newSeparatorTokens); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getSeparatorTokens(); + const response = await client.index(index.uid).getSeparatorTokens(); expect(response).toEqual([]); }); @@ -72,9 +66,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .resetSeparatorTokens(); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client - .index(index.uid) - .getSeparatorTokens(); + const response = await client.index(index.uid).getSeparatorTokens(); expect(response).toEqual([]); }); diff --git a/tests/settings.test.ts b/tests/settings.test.ts index b090f72c4..df4dac7e7 100644 --- a/tests/settings.test.ts +++ b/tests/settings.test.ts @@ -1,5 +1,5 @@ import { afterAll, beforeEach, describe, expect, test } from "vitest"; -import { ErrorStatusCode, type Settings } from "../src/types.js"; +import { ErrorStatusCode, type UpdatableSettings } from "../src/types/index.js"; import { clearAllIndexes, config, @@ -60,7 +60,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update settings`, async () => { const client = await getClient(permission); - const newSettings: Settings = { + const newSettings: UpdatableSettings = { filterableAttributes: ["title"], sortableAttributes: ["title"], distinctAttribute: "title", @@ -108,7 +108,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update settings with all null values`, async () => { const client = await getClient(permission); - const newSettings: Settings = { + const newSettings: UpdatableSettings = { filterableAttributes: null, sortableAttributes: null, distinctAttribute: null, @@ -162,7 +162,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( method: "PATCH", }); - const newSettings: Settings = { + const newSettings: UpdatableSettings = { embedders: { default: { source: "huggingFace", @@ -230,7 +230,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( method: "PATCH", }); - const newSettings: Settings = { + const newSettings: UpdatableSettings = { embedders: null, }; const task = await client.index(index.uid).updateSettings(newSettings); diff --git a/tests/snapshots.test.ts b/tests/snapshots.test.ts index be952d541..8561af3cb 100644 --- a/tests/snapshots.test.ts +++ b/tests/snapshots.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, test } from "vitest"; -import { ErrorStatusCode, TaskStatus } from "../src/types.js"; +import { ErrorStatusCode, TaskStatus } from "../src/types/index.js"; import { clearAllIndexes, config, diff --git a/tests/sortable_attributes.test.ts b/tests/sortable_attributes.test.ts index 90a306a9b..babdf695f 100644 --- a/tests/sortable_attributes.test.ts +++ b/tests/sortable_attributes.test.ts @@ -6,7 +6,7 @@ import { expect, test, } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { clearAllIndexes, config, diff --git a/tests/stop_words.test.ts b/tests/stop_words.test.ts index 47fbee68c..51f5a0b0a 100644 --- a/tests/stop_words.test.ts +++ b/tests/stop_words.test.ts @@ -1,5 +1,5 @@ import { afterAll, beforeEach, describe, expect, test } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { EnqueuedTask } from "../src/enqueued-task.js"; import { clearAllIndexes, @@ -29,7 +29,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default stop words`, async () => { const client = await getClient(permission); - const response: string[] = await client.index(index.uid).getStopWords(); + const response = await client.index(index.uid).getStopWords(); expect(response).toEqual([]); }); @@ -42,7 +42,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateStopWords(newStopWords); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client.index(index.uid).getStopWords(); + const response = await client.index(index.uid).getStopWords(); expect(response).toEqual(newStopWords); }); @@ -55,7 +55,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .updateStopWords(newStopWords); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client.index(index.uid).getStopWords(); + const response = await client.index(index.uid).getStopWords(); expect(response).toEqual([]); }); @@ -65,7 +65,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const task: EnqueuedTask = await client.index(index.uid).resetStopWords(); await client.index(index.uid).waitForTask(task.taskUid); - const response: string[] = await client.index(index.uid).getStopWords(); + const response = await client.index(index.uid).getStopWords(); expect(response).toEqual([]); }); diff --git a/tests/synonyms.test.ts b/tests/synonyms.test.ts index 6c7c516bb..21f50dc6a 100644 --- a/tests/synonyms.test.ts +++ b/tests/synonyms.test.ts @@ -1,5 +1,5 @@ import { afterAll, beforeEach, describe, expect, test } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { clearAllIndexes, config, @@ -28,7 +28,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default synonyms`, async () => { const client = await getClient(permission); - const response: object = await client.index(index.uid).getSynonyms(); + const response = await client.index(index.uid).getSynonyms(); expect(response).toEqual({}); }); @@ -41,7 +41,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const task = await client.index(index.uid).updateSynonyms(newSynonyms); await client.waitForTask(task.taskUid); - const response: object = await client.index(index.uid).getSynonyms(); + const response = await client.index(index.uid).getSynonyms(); expect(response).toEqual(newSynonyms); }); @@ -52,7 +52,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const task = await client.index(index.uid).updateSynonyms(newSynonyms); await client.waitForTask(task.taskUid); - const response: object = await client.index(index.uid).getSynonyms(); + const response = await client.index(index.uid).getSynonyms(); expect(response).toEqual({}); }); @@ -62,7 +62,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const task = await client.index(index.uid).resetSynonyms(); await client.waitForTask(task.taskUid); - const response: object = await client.index(index.uid).getSynonyms(); + const response = await client.index(index.uid).getSynonyms(); expect(response).toEqual({}); }); diff --git a/tests/task.test.ts b/tests/task.test.ts index aeecea5d2..ff6744f97 100644 --- a/tests/task.test.ts +++ b/tests/task.test.ts @@ -1,5 +1,5 @@ import { afterAll, beforeEach, describe, expect, test } from "vitest"; -import { ErrorStatusCode, TaskTypes, TaskStatus } from "../src/types.js"; +import { ErrorStatusCode, TaskTypes, TaskStatus } from "../src/types/index.js"; import { sleep } from "../src/utils.js"; import { clearAllIndexes, diff --git a/tests/typed_search.test.ts b/tests/typed_search.test.ts index 06467cfb2..cf23a168a 100644 --- a/tests/typed_search.test.ts +++ b/tests/typed_search.test.ts @@ -6,7 +6,7 @@ import { expect, test, } from "vitest"; -import { ErrorStatusCode, type SearchResponse } from "../src/types.js"; +import { ErrorStatusCode, type SearchResponse } from "../src/types/index.js"; import { EnqueuedTask } from "../src/enqueued-task.js"; import { clearAllIndexes, diff --git a/tests/typo_tolerance.test.ts b/tests/typo_tolerance.test.ts index 06ad08f50..8a3dc77fa 100644 --- a/tests/typo_tolerance.test.ts +++ b/tests/typo_tolerance.test.ts @@ -1,5 +1,5 @@ import { afterAll, beforeEach, describe, expect, test } from "vitest"; -import { ErrorStatusCode } from "../src/types.js"; +import { ErrorStatusCode } from "../src/types/index.js"; import { clearAllIndexes, config, diff --git a/tests/utils/meilisearch-test-utils.ts b/tests/utils/meilisearch-test-utils.ts index 5dd9744b0..ad55b9165 100644 --- a/tests/utils/meilisearch-test-utils.ts +++ b/tests/utils/meilisearch-test-utils.ts @@ -1,5 +1,5 @@ import { MeiliSearch, Index } from "../../src/index.js"; -import type { Config } from "../../src/types.js"; +import type { Config } from "../../src/types/index.js"; // testing const MASTER_KEY = "masterKey"; From 9692533e4d6674aba74831fcc7305e3bf8b3164d Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Tue, 4 Feb 2025 09:46:02 +0200 Subject: [PATCH 02/18] Fix formatting --- src/indexes.ts | 96 +++++++++++++++++--------------------------------- 1 file changed, 33 insertions(+), 63 deletions(-) diff --git a/src/indexes.ts b/src/indexes.ts index d84831aa8..3b0f47fdb 100644 --- a/src/indexes.ts +++ b/src/indexes.ts @@ -671,9 +671,7 @@ class Index = Record> { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-pagination-settings} */ async getPagination(): Promise { const url = `indexes/${this.uid}/settings/pagination`; - return await this.httpRequest.get< - IndividualSettings["pagination"] - >(url); + return await this.httpRequest.get(url); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-pagination-settings} */ @@ -701,9 +699,7 @@ class Index = Record> { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-synonyms} */ async getSynonyms(): Promise { const url = `indexes/${this.uid}/settings/synonyms`; - return await this.httpRequest.get( - url, - ); + return await this.httpRequest.get(url); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-synonyms} */ @@ -733,9 +729,7 @@ class Index = Record> { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-stop-words} */ async getStopWords(): Promise { const url = `indexes/${this.uid}/settings/stop-words`; - return await this.httpRequest.get( - url, - ); + return await this.httpRequest.get(url); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-stop-words} */ @@ -763,13 +757,9 @@ class Index = Record> { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-ranking-rules} */ - async getRankingRules(): Promise< - IndividualSettings["rankingRules"] - > { + async getRankingRules(): Promise { const url = `indexes/${this.uid}/settings/ranking-rules`; - return await this.httpRequest.get< - IndividualSettings["rankingRules"] - >(url); + return await this.httpRequest.get(url); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-ranking-rules} */ @@ -801,9 +791,9 @@ class Index = Record> { IndividualSettings["distinctAttribute"] > { const url = `indexes/${this.uid}/settings/distinct-attribute`; - return await this.httpRequest.get< - IndividualSettings["distinctAttribute"] - >(url); + return await this.httpRequest.get( + url, + ); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-distinct-attribute} */ @@ -869,9 +859,9 @@ class Index = Record> { IndividualSettings["sortableAttributes"] > { const url = `indexes/${this.uid}/settings/sortable-attributes`; - return await this.httpRequest.get< - IndividualSettings["sortableAttributes"] - >(url); + return await this.httpRequest.get( + url, + ); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-sortable-attributes} */ @@ -967,13 +957,9 @@ class Index = Record> { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-typo-tolerance-settings} */ - async getTypoTolerance(): Promise< - IndividualSettings["typoTolerance"] - > { + async getTypoTolerance(): Promise { const url = `indexes/${this.uid}/settings/typo-tolerance`; - return await this.httpRequest.get< - IndividualSettings["typoTolerance"] - >(url); + return await this.httpRequest.get(url); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-typo-tolerance-settings} */ @@ -1005,9 +991,7 @@ class Index = Record> { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-faceting-settings} */ async getFaceting(): Promise { const url = `indexes/${this.uid}/settings/faceting`; - return await this.httpRequest.get( - url, - ); + return await this.httpRequest.get(url); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-faceting-settings} */ @@ -1033,13 +1017,11 @@ class Index = Record> { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-separator-tokens} */ - async getSeparatorTokens(): Promise< - IndividualSettings["separatorTokens"] - > { + async getSeparatorTokens(): Promise { const url = `indexes/${this.uid}/settings/separator-tokens`; - return await this.httpRequest.get< - IndividualSettings["separatorTokens"] - >(url); + return await this.httpRequest.get( + url, + ); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-separator-tokens} */ @@ -1071,9 +1053,9 @@ class Index = Record> { IndividualSettings["nonSeparatorTokens"] > { const url = `indexes/${this.uid}/settings/non-separator-tokens`; - return await this.httpRequest.get< - IndividualSettings["nonSeparatorTokens"] - >(url); + return await this.httpRequest.get( + url, + ); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-non-separator-tokens} */ @@ -1103,9 +1085,7 @@ class Index = Record> { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-dictionary} */ async getDictionary(): Promise { const url = `indexes/${this.uid}/settings/dictionary`; - return await this.httpRequest.get< - IndividualSettings["dictionary"] - >(url); + return await this.httpRequest.get(url); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-dictionary} */ @@ -1137,9 +1117,9 @@ class Index = Record> { IndividualSettings["proximityPrecision"] > { const url = `indexes/${this.uid}/settings/proximity-precision`; - return await this.httpRequest.get< - IndividualSettings["proximityPrecision"] - >(url); + return await this.httpRequest.get( + url, + ); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-proximity-precision-settings} */ @@ -1169,9 +1149,7 @@ class Index = Record> { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-embedder-settings} */ async getEmbedders(): Promise { const url = `indexes/${this.uid}/settings/embedders`; - return await this.httpRequest.get( - url, - ); + return await this.httpRequest.get(url); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-embedder-settings} */ @@ -1199,13 +1177,11 @@ class Index = Record> { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-search-cutoff} */ - async getSearchCutoffMs(): Promise< - IndividualSettings["searchCutoffMs"] - > { + async getSearchCutoffMs(): Promise { const url = `indexes/${this.uid}/settings/search-cutoff-ms`; - return await this.httpRequest.get< - IndividualSettings["searchCutoffMs"] - >(url); + return await this.httpRequest.get( + url, + ); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-search-cutoff} */ @@ -1265,9 +1241,7 @@ class Index = Record> { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-facet-search-settings} */ async getFacetSearch(): Promise { const url = `indexes/${this.uid}/settings/facet-search`; - return await this.httpRequest.get< - IndividualSettings["facetSearch"] - >(url); + return await this.httpRequest.get(url); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-facet-search-settings} */ @@ -1291,13 +1265,9 @@ class Index = Record> { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-prefix-search-settings} */ - async getPrefixSearch(): Promise< - IndividualSettings["prefixSearch"] - > { + async getPrefixSearch(): Promise { const url = `indexes/${this.uid}/settings/prefix-search`; - return await this.httpRequest.get< - IndividualSettings["prefixSearch"] - >(url); + return await this.httpRequest.get(url); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-prefix-search-settings} */ From d8450508994720afc080eda59585028e0a8ce0a3 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Wed, 26 Mar 2025 15:41:32 +0200 Subject: [PATCH 03/18] Fix lint issue --- src/types/shared.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/types/shared.ts b/src/types/shared.ts index e6302be8b..158ef0913 100644 --- a/src/types/shared.ts +++ b/src/types/shared.ts @@ -1,7 +1,10 @@ +import type { RecordAny } from "./types.js"; + export type NonNullableDeepRecordValues = { + // eslint-disable-next-line @typescript-eslint/no-explicit-any [P in keyof T]: T[P] extends any[] ? Array> - : T[P] extends Record + : T[P] extends RecordAny ? NonNullableDeepRecordValues : NonNullable; }; From b8514258c3970dba2f3e2b623654db34aa54165b Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Thu, 10 Apr 2025 15:29:37 +0300 Subject: [PATCH 04/18] Make adjustments, fixes --- src/indexes.ts | 186 +++++++++++++---------- src/types/settings.ts | 232 +++++++++++++++++++---------- src/types/shared.ts | 11 +- tests/embedders.test.ts | 16 +- tests/faceting.test.ts | 4 +- tests/localized_attributes.test.ts | 11 +- tests/ranking_rules.test.ts | 8 +- tests/search_cutoff_ms.test.ts | 7 +- tests/settings.test.ts | 2 +- 9 files changed, 290 insertions(+), 187 deletions(-) diff --git a/src/indexes.ts b/src/indexes.ts index bf5899b4b..21ddd071f 100644 --- a/src/indexes.ts +++ b/src/indexes.ts @@ -20,7 +20,7 @@ import type { IndexObject, IndexOptions, IndexStats, - IndividualSettings, + IndividualUpdatableSettings, RawDocumentAdditionOptions, RecordAny, ResourceResults, @@ -550,15 +550,17 @@ export class Index { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-pagination-settings} */ - async getPagination(): Promise { - return await this.httpRequest.get({ + async getPagination(): Promise { + return await this.httpRequest.get< + IndividualUpdatableSettings["pagination"] + >({ path: `indexes/${this.uid}/settings/pagination`, }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-pagination-settings} */ updatePagination( - pagination: IndividualSettings["pagination"], + pagination: IndividualUpdatableSettings["pagination"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.patch({ path: `indexes/${this.uid}/settings/pagination`, @@ -578,15 +580,15 @@ export class Index { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-synonyms} */ - async getSynonyms(): Promise { - return await this.httpRequest.get({ + async getSynonyms(): Promise { + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/synonyms`, }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-synonyms} */ updateSynonyms( - synonyms: IndividualSettings["synonyms"], + synonyms: IndividualUpdatableSettings["synonyms"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/synonyms`, @@ -606,15 +608,17 @@ export class Index { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-stop-words} */ - async getStopWords(): Promise { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/stop-words`, - }); + async getStopWords(): Promise { + return await this.httpRequest.get( + { + path: `indexes/${this.uid}/settings/stop-words`, + }, + ); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-stop-words} */ updateStopWords( - stopWords: IndividualSettings["stopWords"], + stopWords: IndividualUpdatableSettings["stopWords"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/stop-words`, @@ -634,15 +638,19 @@ export class Index { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-ranking-rules} */ - async getRankingRules(): Promise { - return await this.httpRequest.get({ + async getRankingRules(): Promise< + IndividualUpdatableSettings["rankingRules"] + > { + return await this.httpRequest.get< + IndividualUpdatableSettings["rankingRules"] + >({ path: `indexes/${this.uid}/settings/ranking-rules`, }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-ranking-rules} */ updateRankingRules( - rankingRules: IndividualSettings["rankingRules"], + rankingRules: IndividualUpdatableSettings["rankingRules"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/ranking-rules`, @@ -663,16 +671,18 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-distinct-attribute} */ async getDistinctAttribute(): Promise< - IndividualSettings["distinctAttribute"] + IndividualUpdatableSettings["distinctAttribute"] > { - return await this.httpRequest.get({ + return await this.httpRequest.get< + IndividualUpdatableSettings["distinctAttribute"] + >({ path: `indexes/${this.uid}/settings/distinct-attribute`, }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-distinct-attribute} */ updateDistinctAttribute( - distinctAttribute: IndividualSettings["distinctAttribute"], + distinctAttribute: IndividualUpdatableSettings["distinctAttribute"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/distinct-attribute`, @@ -693,10 +703,10 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-filterable-attributes} */ async getFilterableAttributes(): Promise< - IndividualSettings["filterableAttributes"] + IndividualUpdatableSettings["filterableAttributes"] > { return await this.httpRequest.get< - IndividualSettings["filterableAttributes"] + IndividualUpdatableSettings["filterableAttributes"] >({ path: `indexes/${this.uid}/settings/filterable-attributes`, }); @@ -704,7 +714,7 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-filterable-attributes} */ updateFilterableAttributes( - filterableAttributes: IndividualSettings["filterableAttributes"], + filterableAttributes: IndividualUpdatableSettings["filterableAttributes"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/filterable-attributes`, @@ -725,18 +735,18 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-sortable-attributes} */ async getSortableAttributes(): Promise< - IndividualSettings["sortableAttributes"] + IndividualUpdatableSettings["sortableAttributes"] > { - return await this.httpRequest.get( - { - path: `indexes/${this.uid}/settings/sortable-attributes`, - }, - ); + return await this.httpRequest.get< + IndividualUpdatableSettings["sortableAttributes"] + >({ + path: `indexes/${this.uid}/settings/sortable-attributes`, + }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-sortable-attributes} */ updateSortableAttributes( - sortableAttributes: IndividualSettings["sortableAttributes"], + sortableAttributes: IndividualUpdatableSettings["sortableAttributes"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/sortable-attributes`, @@ -757,10 +767,10 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-searchable-attributes} */ async getSearchableAttributes(): Promise< - IndividualSettings["searchableAttributes"] + IndividualUpdatableSettings["searchableAttributes"] > { return await this.httpRequest.get< - IndividualSettings["searchableAttributes"] + IndividualUpdatableSettings["searchableAttributes"] >({ path: `indexes/${this.uid}/settings/searchable-attributes`, }); @@ -768,7 +778,7 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-searchable-attributes} */ updateSearchableAttributes( - searchableAttributes: IndividualSettings["searchableAttributes"], + searchableAttributes: IndividualUpdatableSettings["searchableAttributes"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/searchable-attributes`, @@ -789,10 +799,10 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-displayed-attributes} */ async getDisplayedAttributes(): Promise< - IndividualSettings["displayedAttributes"] + IndividualUpdatableSettings["displayedAttributes"] > { return await this.httpRequest.get< - IndividualSettings["displayedAttributes"] + IndividualUpdatableSettings["displayedAttributes"] >({ path: `indexes/${this.uid}/settings/displayed-attributes`, }); @@ -800,7 +810,7 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-displayed-attributes} */ updateDisplayedAttributes( - displayedAttributes: IndividualSettings["displayedAttributes"], + displayedAttributes: IndividualUpdatableSettings["displayedAttributes"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/displayed-attributes`, @@ -820,15 +830,19 @@ export class Index { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-typo-tolerance-settings} */ - async getTypoTolerance(): Promise { - return await this.httpRequest.get({ + async getTypoTolerance(): Promise< + IndividualUpdatableSettings["typoTolerance"] + > { + return await this.httpRequest.get< + IndividualUpdatableSettings["typoTolerance"] + >({ path: `indexes/${this.uid}/settings/typo-tolerance`, }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-typo-tolerance-settings} */ updateTypoTolerance( - typoTolerance: IndividualSettings["typoTolerance"], + typoTolerance: IndividualUpdatableSettings["typoTolerance"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.patch({ path: `indexes/${this.uid}/settings/typo-tolerance`, @@ -848,15 +862,15 @@ export class Index { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-faceting-settings} */ - async getFaceting(): Promise { - return await this.httpRequest.get({ + async getFaceting(): Promise { + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/faceting`, }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-faceting-settings} */ updateFaceting( - faceting: IndividualSettings["faceting"], + faceting: IndividualUpdatableSettings["faceting"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.patch({ path: `indexes/${this.uid}/settings/faceting`, @@ -876,15 +890,19 @@ export class Index { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-separator-tokens} */ - async getSeparatorTokens(): Promise { - return await this.httpRequest.get({ + async getSeparatorTokens(): Promise< + IndividualUpdatableSettings["separatorTokens"] + > { + return await this.httpRequest.get< + IndividualUpdatableSettings["separatorTokens"] + >({ path: `indexes/${this.uid}/settings/separator-tokens`, }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-separator-tokens} */ updateSeparatorTokens( - separatorTokens: IndividualSettings["separatorTokens"], + separatorTokens: IndividualUpdatableSettings["separatorTokens"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/separator-tokens`, @@ -905,18 +923,18 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-non-separator-tokens} */ async getNonSeparatorTokens(): Promise< - IndividualSettings["nonSeparatorTokens"] + IndividualUpdatableSettings["nonSeparatorTokens"] > { - return await this.httpRequest.get( - { - path: `indexes/${this.uid}/settings/non-separator-tokens`, - }, - ); + return await this.httpRequest.get< + IndividualUpdatableSettings["nonSeparatorTokens"] + >({ + path: `indexes/${this.uid}/settings/non-separator-tokens`, + }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-non-separator-tokens} */ updateNonSeparatorTokens( - nonSeparatorTokens: IndividualSettings["nonSeparatorTokens"], + nonSeparatorTokens: IndividualUpdatableSettings["nonSeparatorTokens"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/non-separator-tokens`, @@ -936,15 +954,17 @@ export class Index { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-dictionary} */ - async getDictionary(): Promise { - return await this.httpRequest.get({ + async getDictionary(): Promise { + return await this.httpRequest.get< + IndividualUpdatableSettings["dictionary"] + >({ path: `indexes/${this.uid}/settings/dictionary`, }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-dictionary} */ updateDictionary( - dictionary: IndividualSettings["dictionary"], + dictionary: IndividualUpdatableSettings["dictionary"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/dictionary`, @@ -965,18 +985,18 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-proximity-precision-settings} */ async getProximityPrecision(): Promise< - IndividualSettings["proximityPrecision"] + IndividualUpdatableSettings["proximityPrecision"] > { - return await this.httpRequest.get( - { - path: `indexes/${this.uid}/settings/proximity-precision`, - }, - ); + return await this.httpRequest.get< + IndividualUpdatableSettings["proximityPrecision"] + >({ + path: `indexes/${this.uid}/settings/proximity-precision`, + }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-proximity-precision-settings} */ updateProximityPrecision( - proximityPrecision: IndividualSettings["proximityPrecision"], + proximityPrecision: IndividualUpdatableSettings["proximityPrecision"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/proximity-precision`, @@ -996,15 +1016,17 @@ export class Index { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-embedder-settings} */ - async getEmbedders(): Promise { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/embedders`, - }); + async getEmbedders(): Promise { + return await this.httpRequest.get( + { + path: `indexes/${this.uid}/settings/embedders`, + }, + ); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-embedder-settings} */ updateEmbedders( - embedders: IndividualSettings["embedders"], + embedders: IndividualUpdatableSettings["embedders"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.patch({ path: `indexes/${this.uid}/settings/embedders`, @@ -1024,15 +1046,19 @@ export class Index { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-search-cutoff} */ - async getSearchCutoffMs(): Promise { - return await this.httpRequest.get({ + async getSearchCutoffMs(): Promise< + IndividualUpdatableSettings["searchCutoffMs"] + > { + return await this.httpRequest.get< + IndividualUpdatableSettings["searchCutoffMs"] + >({ path: `indexes/${this.uid}/settings/search-cutoff-ms`, }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-search-cutoff} */ updateSearchCutoffMs( - searchCutoffMs: IndividualSettings["searchCutoffMs"], + searchCutoffMs: IndividualUpdatableSettings["searchCutoffMs"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/search-cutoff-ms`, @@ -1053,10 +1079,10 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-localized-attributes-settings} */ async getLocalizedAttributes(): Promise< - IndividualSettings["localizedAttributes"] + IndividualUpdatableSettings["localizedAttributes"] > { return await this.httpRequest.get< - IndividualSettings["localizedAttributes"] + IndividualUpdatableSettings["localizedAttributes"] >({ path: `indexes/${this.uid}/settings/localized-attributes`, }); @@ -1064,7 +1090,7 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-localized-attribute-settings} */ updateLocalizedAttributes( - localizedAttributes: IndividualSettings["localizedAttributes"], + localizedAttributes: IndividualUpdatableSettings["localizedAttributes"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/localized-attributes`, @@ -1084,15 +1110,17 @@ export class Index { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-facet-search-settings} */ - async getFacetSearch(): Promise { - return await this.httpRequest.get({ + async getFacetSearch(): Promise { + return await this.httpRequest.get< + IndividualUpdatableSettings["facetSearch"] + >({ path: `indexes/${this.uid}/settings/facet-search`, }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-facet-search-settings} */ updateFacetSearch( - facetSearch: IndividualSettings["facetSearch"], + facetSearch: IndividualUpdatableSettings["facetSearch"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/facet-search`, @@ -1112,15 +1140,19 @@ export class Index { /// /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-prefix-search-settings} */ - async getPrefixSearch(): Promise { - return await this.httpRequest.get({ + async getPrefixSearch(): Promise< + IndividualUpdatableSettings["prefixSearch"] + > { + return await this.httpRequest.get< + IndividualUpdatableSettings["prefixSearch"] + >({ path: `indexes/${this.uid}/settings/prefix-search`, }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-prefix-search-settings} */ updatePrefixSearch( - prefixSearch: IndividualSettings["prefixSearch"], + prefixSearch: IndividualUpdatableSettings["prefixSearch"], ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ path: `indexes/${this.uid}/settings/prefix-search`, diff --git a/src/types/settings.ts b/src/types/settings.ts index 2d47eed0c..fb78da6a1 100644 --- a/src/types/settings.ts +++ b/src/types/settings.ts @@ -1,127 +1,197 @@ -import type { NonNullableDeepRecordValues } from "./shared.js"; +import type { PascalToCamelCase } from "./shared.js"; -/** {@link https://www.meilisearch.com/docs/reference/api/settings#proximity-precision} */ -export type ProximityPrecision = "byWord" | "byAttribute"; - -/** @see `minWordSizeForTypos` at {@link https://www.meilisearch.com/docs/reference/api/settings#typo-tolerance} */ -export type MinWordSizeForTypos = { - oneTypo?: number | null; - twoTypos?: number | null; +/** Deeply map every property of a record to itself excluding null. */ +type NonNullableDeepRecordValues = { + [TKey in keyof T]: Exclude, null>; }; -/** {@link https://www.meilisearch.com/docs/reference/api/settings#typo-tolerance} */ -export type TypoTolerance = { - enabled?: boolean | null; - minWordSizeForTypos?: MinWordSizeForTypos | null; - disableOnWords?: string[] | null; - disableOnAttributes?: string[] | null; -}; +/** Map properties of a record to be optional and nullable. */ +type PartialAndNullable = { [P in keyof T]?: T[P] | null }; + +/** + * {@link https://www.meilisearch.com/docs/reference/api/settings#proximity-precision} + * + * @see `meilisearch_types::settings::ProximityPrecisionView` + */ +export type ProximityPrecisionView = PascalToCamelCase< + "ByWord" | "ByAttribute" +>; -/** @see `sortFacetValuesBy` at {@link https://www.meilisearch.com/docs/reference/api/settings#faceting} */ -export type FacetOrder = "alpha" | "count"; +/** + * @see `minWordSizeForTypos` at {@link https://www.meilisearch.com/docs/reference/api/settings#typo-tolerance} + * + * @see `meilisearch_types::settings::MinWordSizeTyposSetting` + */ +export type MinWordSizeTyposSetting = PartialAndNullable<{ + oneTypo: number; + twoTypos: number; +}>; -/** {@link https://www.meilisearch.com/docs/reference/api/settings#faceting} */ -export type Faceting = { - maxValuesPerFacet?: number | null; - sortFacetValuesBy?: Record | null; -}; +/** + * {@link https://www.meilisearch.com/docs/reference/api/settings#typo-tolerance} + * + * @see `meilisearch_types::settings::TypoSettings` + */ +export type TypoSettings = PartialAndNullable<{ + enabled: boolean; + minWordSizeForTypos: MinWordSizeTyposSetting; + disableOnWords: string[]; + disableOnAttributes: string[]; +}>; + +/** + * @see `sortFacetValuesBy` at {@link https://www.meilisearch.com/docs/reference/api/settings#faceting} + * @see `meilisearch_types::facet_values_sort::FacetValuesSort` + */ +export type FacetValuesSort = PascalToCamelCase<"Alpha" | "Count">; + +/** + * {@link https://www.meilisearch.com/docs/reference/api/settings#faceting} + * + * @see `meilisearch_types::settings::FacetingSettings` + */ +export type FacetingSettings = PartialAndNullable<{ + maxValuesPerFacet: number; + sortFacetValuesBy: Record; +}>; -/** {@link https://www.meilisearch.com/docs/reference/api/settings#pagination} */ -export type PaginationSettings = { maxTotalHits?: number | null }; +/** + * {@link https://www.meilisearch.com/docs/reference/api/settings#pagination} + * + * @see `meilisearch_types::settings::PaginationSettings` + */ +export type PaginationSettings = PartialAndNullable<{ maxTotalHits: number }>; -/** @see `distribution` at {@link https://www.meilisearch.com/docs/reference/api/settings#embedders-experimental} */ -export type Distribution = { +/** + * @see `distribution` at {@link https://www.meilisearch.com/docs/reference/api/settings#embedders} + * @see `milli::vector::DistributionShift` + */ +export type DistributionShift = { mean: number; sigma: number; }; -/** @see `source` at {@link https://www.meilisearch.com/docs/reference/api/settings#embedders-experimental} */ -export type EmbedderSource = - | "openAi" - | "huggingFace" - | "ollama" - | "userProvided" - | "rest"; - -/** {@link https://www.meilisearch.com/docs/reference/api/settings#embedders-experimental} */ -export type EmbeddingSettings = { - source?: EmbedderSource | null; - model?: string | null; - revision?: string | null; - apiKey?: string | null; - dimensions?: number | null; - binaryQuantized?: boolean | null; - documentTemplate?: string | null; - documentTemplateMaxBytes?: number | null; - url?: string | null; - request?: unknown; - response?: unknown; - headers?: Record | null; - distribution?: Distribution | null; -}; +/** @see `source` at {@link https://www.meilisearch.com/docs/reference/api/settings#embedders} */ +export type EmbedderSource = PascalToCamelCase< + "OpenAi" | "HuggingFace" | "Ollama" | "UserProvided" | "Rest" +>; + +/** @see `milli::vector::hf::OverridePooling` */ +export type OverridePooling = PascalToCamelCase< + "UseModel" | "ForceCls" | "ForceMean" +>; + +/** @see `milli::vector::settings::SubEmbeddingSettings` */ +export type SubEmbeddingSettings = PartialAndNullable<{ + source: EmbedderSource; + model: string; + revision: string; + pooling: OverridePooling; + apiKey: string; + dimensions: number; + documentTemplate: string; + documentTemplateMaxBytes: number; + url: string; + request: unknown; + response: unknown; + headers: Record; +}>; + +/** + * {@link https://www.meilisearch.com/docs/reference/api/settings#embedders} + * + * @see `milli::vector::settings::EmbeddingSettings` + */ +export type EmbeddingSettings = PartialAndNullable<{ + distribution: DistributionShift; + binaryQuantized: boolean; + // upcoming properties + // searchEmbedder: SubEmbeddingSettings; + // indexingEmbedder: SubEmbeddingSettings; +}> & + SubEmbeddingSettings; -/** {@link https://www.meilisearch.com/docs/reference/api/settings#localized-attributes} */ -export type LocalizedAttribute = { - attributePatterns: string[] | null; - locales: string[] | null; +/** + * {@link https://www.meilisearch.com/docs/reference/api/settings#localized-attributes} + * + * @see `meilisearch_types::locales::LocalizedAttributesRuleView` + */ +export type LocalizedAttributesRuleView = { + /** @see `milli::attribute_patterns::AttributePatterns` */ + attributePatterns: string[]; + /** @see `meilisearch_types::locales::Locale` */ + locales: string[]; }; -/** {@link https://www.meilisearch.com/docs/reference/api/settings#prefix-search} */ -export type PrefixSearch = "indexingTime" | "disabled"; +/** + * {@link https://www.meilisearch.com/docs/reference/api/settings#prefix-search} + * + * @see `meilisearch_types::settings::PrefixSearchSettings` + */ +export type PrefixSearchSettings = PascalToCamelCase< + "IndexingTime" | "Disabled" +>; + +/** @see `meilisearch_types::settings::RankingRuleView` */ +export type RankingRuleView = + | PascalToCamelCase< + "Words" | "Typo" | "Proximity" | "Attribute" | "Sort" | "Exactness" + > + | `${string}:${"asc" | "desc"}`; /** A version of {@link Settings} that can be used to update the settings. */ -export type UpdatableSettings = { +export type UpdatableSettings = PartialAndNullable<{ /** {@link https://www.meilisearch.com/docs/reference/api/settings#displayed-attributes} */ - displayedAttributes?: string[] | null; + displayedAttributes: string[]; /** {@link https://www.meilisearch.com/docs/reference/api/settings#searchable-attributes} */ - searchableAttributes?: string[] | null; + searchableAttributes: string[]; /** {@link https://www.meilisearch.com/docs/reference/api/settings#filterable-attributes} */ - filterableAttributes?: string[] | null; + filterableAttributes: string[]; /** {@link https://www.meilisearch.com/docs/reference/api/settings#sortable-attributes} */ - sortableAttributes?: string[] | null; + sortableAttributes: string[]; /** {@link https://www.meilisearch.com/docs/reference/api/settings#ranking-rules} */ - rankingRules?: string[] | null; + rankingRules: RankingRuleView[]; /** {@link https://www.meilisearch.com/docs/reference/api/settings#stop-words} */ - stopWords?: string[] | null; + stopWords: string[]; /** {@link https://www.meilisearch.com/docs/reference/api/settings#non-separator-tokens} */ - nonSeparatorTokens?: string[] | null; + nonSeparatorTokens: string[]; /** {@link https://www.meilisearch.com/docs/reference/api/settings#separator-tokens} */ - separatorTokens?: string[] | null; + separatorTokens: string[]; /** {@link https://www.meilisearch.com/docs/reference/api/settings#dictionary} */ - dictionary?: string[] | null; + dictionary: string[]; /** {@link https://www.meilisearch.com/docs/reference/api/settings#synonyms} */ - synonyms?: Record | null; + synonyms: Record; /** {@link https://www.meilisearch.com/docs/reference/api/settings#distinct-attribute} */ - distinctAttribute?: string | null; + distinctAttribute: string; /** {@link https://www.meilisearch.com/docs/reference/api/settings#proximity-precision} */ - proximityPrecision?: ProximityPrecision | null; + proximityPrecision: ProximityPrecisionView; /** {@link https://www.meilisearch.com/docs/reference/api/settings#typo-tolerance} */ - typoTolerance?: TypoTolerance | null; + typoTolerance: TypoSettings; /** {@link https://www.meilisearch.com/docs/reference/api/settings#faceting} */ - faceting?: Faceting | null; + faceting: FacetingSettings; /** {@link https://www.meilisearch.com/docs/reference/api/settings#pagination} */ - pagination?: PaginationSettings | null; - /** {@link https://www.meilisearch.com/docs/reference/api/settings#embedders-experimental} */ - embedders?: Record | null; + pagination: PaginationSettings; + /** {@link https://www.meilisearch.com/docs/reference/api/settings#embedders} */ + embedders: PartialAndNullable>; /** {@link https://www.meilisearch.com/docs/reference/api/settings#search-cutoff} */ - searchCutoffMs?: number | null; + searchCutoffMs: number; /** {@link https://www.meilisearch.com/docs/reference/api/settings#localized-attributes} */ - localizedAttributes?: LocalizedAttribute[] | null; + localizedAttributes: LocalizedAttributesRuleView[]; /** {@link https://www.meilisearch.com/docs/reference/api/settings#facet-search} */ - facetSearch?: boolean | null; + facetSearch: boolean; /** {@link https://www.meilisearch.com/docs/reference/api/settings#prefix-search} */ - prefixSearch?: PrefixSearch | null; -}; + prefixSearch: PrefixSearchSettings; +}>; /** * A version of {@link UpdatableSettings}, the first layer of properties of which * is used to update or get individual settings. */ -export type IndividualSettings = Required; +export type IndividualUpdatableSettings = Required; /** * {@link https://www.meilisearch.com/docs/reference/api/settings#body} * - * @see `meilisearch_types::settings::Settings` at {@link https://github.com/meilisearch/meilisearch} + * @see `meilisearch_types::settings::Settings` */ export type Settings = NonNullableDeepRecordValues; diff --git a/src/types/shared.ts b/src/types/shared.ts index d475d6948..e0359a927 100644 --- a/src/types/shared.ts +++ b/src/types/shared.ts @@ -1,5 +1,3 @@ -import type { RecordAny } from "./types.js"; - export type CursorResults = { results: T[]; limit: number; @@ -8,11 +6,4 @@ export type CursorResults = { total: number; }; -export type NonNullableDeepRecordValues = { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - [P in keyof T]: T[P] extends any[] - ? Array> - : T[P] extends RecordAny - ? NonNullableDeepRecordValues - : NonNullable; -}; +export type PascalToCamelCase = Uncapitalize; diff --git a/tests/embedders.test.ts b/tests/embedders.test.ts index eb5a8784d..0a3d55537 100644 --- a/tests/embedders.test.ts +++ b/tests/embedders.test.ts @@ -1,5 +1,5 @@ import { afterAll, expect, test, describe, beforeEach } from "vitest"; -import type { IndividualSettings } from "../src/index.js"; +import type { IndividualUpdatableSettings } from "../src/index.js"; import { clearAllIndexes, config, @@ -68,7 +68,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with 'userProvided' source`, async () => { const client = await getClient(permission); - const newEmbedder: IndividualSettings["embedders"] = { + const newEmbedder: IndividualUpdatableSettings["embedders"] = { default: { source: "userProvided", dimensions: 1, @@ -89,7 +89,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with 'openAi' source`, async () => { const client = await getClient(permission); - const newEmbedder: IndividualSettings["embedders"] = { + const newEmbedder: IndividualUpdatableSettings["embedders"] = { default: { source: "openAi", apiKey: "", @@ -120,7 +120,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with 'huggingFace' source`, async () => { const client = await getClient(permission); - const newEmbedder: IndividualSettings["embedders"] = { + const newEmbedder: IndividualUpdatableSettings["embedders"] = { default: { source: "huggingFace", model: "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", @@ -146,7 +146,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with 'rest' source`, async () => { const client = await getClient(permission); - const newEmbedder: IndividualSettings["embedders"] = { + const newEmbedder: IndividualUpdatableSettings["embedders"] = { default: { source: "rest", url: "https://api.openai.com/v1/embeddings", @@ -191,7 +191,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with 'ollama' source`, async () => { const client = await getClient(permission); - const newEmbedder: IndividualSettings["embedders"] = { + const newEmbedder: IndividualUpdatableSettings["embedders"] = { default: { source: "ollama", url: "http://localhost:11434/api/embeddings", @@ -222,7 +222,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with a specific name`, async () => { const client = await getClient(permission); - const newEmbedder: IndividualSettings["embedders"] = { + const newEmbedder: IndividualUpdatableSettings["embedders"] = { image: { source: "userProvided", dimensions: 512, @@ -303,7 +303,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: search for similar documents`, async () => { const client = await getClient(permission); - const newEmbedder: IndividualSettings["embedders"] = { + const newEmbedder: IndividualUpdatableSettings["embedders"] = { manual: { source: "userProvided", dimensions: 3, diff --git a/tests/faceting.test.ts b/tests/faceting.test.ts index dc942b810..32935cccf 100644 --- a/tests/faceting.test.ts +++ b/tests/faceting.test.ts @@ -6,7 +6,7 @@ import { afterAll, beforeAll, } from "vitest"; -import { ErrorStatusCode, type Faceting } from "../src/index.js"; +import { ErrorStatusCode, type FacetingSettings } from "../src/index.js"; import { clearAllIndexes, config, @@ -45,7 +45,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update faceting settings`, async () => { const client = await getClient(permission); - const newFaceting: Faceting = { + const newFaceting: FacetingSettings = { maxValuesPerFacet: 12, sortFacetValuesBy: { test: "count" }, }; diff --git a/tests/localized_attributes.test.ts b/tests/localized_attributes.test.ts index af8fae932..c485f19c3 100644 --- a/tests/localized_attributes.test.ts +++ b/tests/localized_attributes.test.ts @@ -6,7 +6,10 @@ import { expect, test, } from "vitest"; -import { ErrorStatusCode, type IndividualSettings } from "../src/index.js"; +import { + ErrorStatusCode, + type IndividualUpdatableSettings, +} from "../src/index.js"; import { clearAllIndexes, config, @@ -44,7 +47,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update localizedAttributes to valid value`, async () => { const client = await getClient(permission); - const newLocalizedAttributes: IndividualSettings["localizedAttributes"] = + const newLocalizedAttributes: IndividualUpdatableSettings["localizedAttributes"] = [{ attributePatterns: ["title"], locales: ["eng"] }]; await client .index(index.uid) @@ -72,7 +75,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update localizedAttributes with invalid value`, async () => { const client = await getClient(permission); const newLocalizedAttributes = - "hello" as unknown as IndividualSettings["localizedAttributes"]; // bad localizedAttributes value + "hello" as unknown as IndividualUpdatableSettings["localizedAttributes"]; // bad localizedAttributes value await expect( client @@ -86,7 +89,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Reset localizedAttributes`, async () => { const client = await getClient(permission); - const newLocalizedAttributes: IndividualSettings["localizedAttributes"] = + const newLocalizedAttributes: IndividualUpdatableSettings["localizedAttributes"] = []; await client .index(index.uid) diff --git a/tests/ranking_rules.test.ts b/tests/ranking_rules.test.ts index 557cff3bb..4bf114fee 100644 --- a/tests/ranking_rules.test.ts +++ b/tests/ranking_rules.test.ts @@ -1,5 +1,5 @@ import { expect, test, describe, beforeEach, afterAll } from "vitest"; -import { ErrorStatusCode } from "../src/index.js"; +import { ErrorStatusCode, type RankingRuleView } from "../src/index.js"; import { clearAllIndexes, config, @@ -43,7 +43,11 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update ranking rules`, async () => { const client = await getClient(permission); - const newRankingRules = ["title:asc", "typo", "description:desc"]; + const newRankingRules: RankingRuleView[] = [ + "title:asc", + "typo", + "description:desc", + ]; await client .index(index.uid) .updateRankingRules(newRankingRules) diff --git a/tests/search_cutoff_ms.test.ts b/tests/search_cutoff_ms.test.ts index 4556cb2af..7292759b4 100644 --- a/tests/search_cutoff_ms.test.ts +++ b/tests/search_cutoff_ms.test.ts @@ -6,7 +6,10 @@ import { expect, test, } from "vitest"; -import { ErrorStatusCode, type IndividualSettings } from "../src/index.js"; +import { + ErrorStatusCode, + type IndividualUpdatableSettings, +} from "../src/index.js"; import { clearAllIndexes, config, @@ -71,7 +74,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update searchCutoffMs with invalid value`, async () => { const client = await getClient(permission); const newSearchCutoffMs = - "hello" as unknown as IndividualSettings["searchCutoffMs"]; // bad searchCutoffMs value + "hello" as unknown as IndividualUpdatableSettings["searchCutoffMs"]; // bad searchCutoffMs value await expect( client.index(index.uid).updateSearchCutoffMs(newSearchCutoffMs), diff --git a/tests/settings.test.ts b/tests/settings.test.ts index f47837431..06a06d37e 100644 --- a/tests/settings.test.ts +++ b/tests/settings.test.ts @@ -165,7 +165,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update settings on empty index with primary key`, async () => { const client = await getClient(permission); - const newSettings = { + const newSettings: UpdatableSettings = { distinctAttribute: "title", rankingRules: ["title:asc", "typo"], stopWords: ["the"], From 86a8f89dcd4818d7ef07a7e7a8f38ad2cf384caf Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Thu, 10 Apr 2025 15:42:16 +0300 Subject: [PATCH 05/18] Remove unnecessary type params --- src/indexes.ts | 88 ++++++++++++++------------------------------------ 1 file changed, 25 insertions(+), 63 deletions(-) diff --git a/src/indexes.ts b/src/indexes.ts index 21ddd071f..0a56842e5 100644 --- a/src/indexes.ts +++ b/src/indexes.ts @@ -525,9 +525,7 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-settings} */ async getSettings(): Promise { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings`, - }); + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings` }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-settings} */ @@ -551,9 +549,7 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-pagination-settings} */ async getPagination(): Promise { - return await this.httpRequest.get< - IndividualUpdatableSettings["pagination"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/pagination`, }); } @@ -581,7 +577,7 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-synonyms} */ async getSynonyms(): Promise { - return await this.httpRequest.get({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/synonyms`, }); } @@ -609,11 +605,9 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-stop-words} */ async getStopWords(): Promise { - return await this.httpRequest.get( - { - path: `indexes/${this.uid}/settings/stop-words`, - }, - ); + return await this.httpRequest.get({ + path: `indexes/${this.uid}/settings/stop-words`, + }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-stop-words} */ @@ -641,9 +635,7 @@ export class Index { async getRankingRules(): Promise< IndividualUpdatableSettings["rankingRules"] > { - return await this.httpRequest.get< - IndividualUpdatableSettings["rankingRules"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/ranking-rules`, }); } @@ -673,9 +665,7 @@ export class Index { async getDistinctAttribute(): Promise< IndividualUpdatableSettings["distinctAttribute"] > { - return await this.httpRequest.get< - IndividualUpdatableSettings["distinctAttribute"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/distinct-attribute`, }); } @@ -705,9 +695,7 @@ export class Index { async getFilterableAttributes(): Promise< IndividualUpdatableSettings["filterableAttributes"] > { - return await this.httpRequest.get< - IndividualUpdatableSettings["filterableAttributes"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/filterable-attributes`, }); } @@ -737,9 +725,7 @@ export class Index { async getSortableAttributes(): Promise< IndividualUpdatableSettings["sortableAttributes"] > { - return await this.httpRequest.get< - IndividualUpdatableSettings["sortableAttributes"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/sortable-attributes`, }); } @@ -769,9 +755,7 @@ export class Index { async getSearchableAttributes(): Promise< IndividualUpdatableSettings["searchableAttributes"] > { - return await this.httpRequest.get< - IndividualUpdatableSettings["searchableAttributes"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/searchable-attributes`, }); } @@ -801,9 +785,7 @@ export class Index { async getDisplayedAttributes(): Promise< IndividualUpdatableSettings["displayedAttributes"] > { - return await this.httpRequest.get< - IndividualUpdatableSettings["displayedAttributes"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/displayed-attributes`, }); } @@ -833,9 +815,7 @@ export class Index { async getTypoTolerance(): Promise< IndividualUpdatableSettings["typoTolerance"] > { - return await this.httpRequest.get< - IndividualUpdatableSettings["typoTolerance"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/typo-tolerance`, }); } @@ -863,7 +843,7 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-faceting-settings} */ async getFaceting(): Promise { - return await this.httpRequest.get({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/faceting`, }); } @@ -893,9 +873,7 @@ export class Index { async getSeparatorTokens(): Promise< IndividualUpdatableSettings["separatorTokens"] > { - return await this.httpRequest.get< - IndividualUpdatableSettings["separatorTokens"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/separator-tokens`, }); } @@ -925,9 +903,7 @@ export class Index { async getNonSeparatorTokens(): Promise< IndividualUpdatableSettings["nonSeparatorTokens"] > { - return await this.httpRequest.get< - IndividualUpdatableSettings["nonSeparatorTokens"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/non-separator-tokens`, }); } @@ -955,9 +931,7 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-dictionary} */ async getDictionary(): Promise { - return await this.httpRequest.get< - IndividualUpdatableSettings["dictionary"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/dictionary`, }); } @@ -987,9 +961,7 @@ export class Index { async getProximityPrecision(): Promise< IndividualUpdatableSettings["proximityPrecision"] > { - return await this.httpRequest.get< - IndividualUpdatableSettings["proximityPrecision"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/proximity-precision`, }); } @@ -1017,11 +989,9 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-embedder-settings} */ async getEmbedders(): Promise { - return await this.httpRequest.get( - { - path: `indexes/${this.uid}/settings/embedders`, - }, - ); + return await this.httpRequest.get({ + path: `indexes/${this.uid}/settings/embedders`, + }); } /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-embedder-settings} */ @@ -1049,9 +1019,7 @@ export class Index { async getSearchCutoffMs(): Promise< IndividualUpdatableSettings["searchCutoffMs"] > { - return await this.httpRequest.get< - IndividualUpdatableSettings["searchCutoffMs"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/search-cutoff-ms`, }); } @@ -1081,9 +1049,7 @@ export class Index { async getLocalizedAttributes(): Promise< IndividualUpdatableSettings["localizedAttributes"] > { - return await this.httpRequest.get< - IndividualUpdatableSettings["localizedAttributes"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/localized-attributes`, }); } @@ -1111,9 +1077,7 @@ export class Index { /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-facet-search-settings} */ async getFacetSearch(): Promise { - return await this.httpRequest.get< - IndividualUpdatableSettings["facetSearch"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/facet-search`, }); } @@ -1143,9 +1107,7 @@ export class Index { async getPrefixSearch(): Promise< IndividualUpdatableSettings["prefixSearch"] > { - return await this.httpRequest.get< - IndividualUpdatableSettings["prefixSearch"] - >({ + return await this.httpRequest.get({ path: `indexes/${this.uid}/settings/prefix-search`, }); } From 3095a19ebe111c87af67fe1ecbbdc24462ec5d98 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Thu, 10 Apr 2025 23:50:46 +0300 Subject: [PATCH 06/18] Shorten code --- src/indexes.ts | 618 ++------------------------- src/settings.ts | 65 +++ src/types/shared.ts | 1 + tests/dictionary.test.ts | 26 +- tests/displayed_attributes.test.ts | 46 +- tests/distinct_attribute.test.ts | 43 +- tests/documents.test.ts | 12 +- tests/embedders.test.ts | 62 ++- tests/facet_search_settings.test.ts | 30 +- tests/faceting.test.ts | 45 +- tests/filterable_attributes.test.ts | 46 +- tests/localized_attributes.test.ts | 47 +- tests/non_separator_tokens.test.ts | 31 +- tests/pagination.test.ts | 43 +- tests/prefix_search_settings.test.ts | 33 +- tests/proximity_precision.test.ts | 31 +- tests/ranking_rules.test.ts | 32 +- tests/search.test.ts | 3 +- tests/search_cutoff_ms.test.ts | 44 +- tests/searchable_attributes.test.ts | 46 +- tests/separator_tokens.test.ts | 28 +- tests/sortable_attributes.test.ts | 46 +- tests/stop_words.test.ts | 40 +- tests/synonyms.test.ts | 42 +- tests/token.test.ts | 2 +- tests/typed_search.test.ts | 4 +- tests/typo_tolerance.test.ts | 35 +- 27 files changed, 605 insertions(+), 896 deletions(-) create mode 100644 src/settings.ts diff --git a/src/indexes.ts b/src/indexes.ts index 0a56842e5..2bff802cc 100644 --- a/src/indexes.ts +++ b/src/indexes.ts @@ -20,7 +20,6 @@ import type { IndexObject, IndexOptions, IndexStats, - IndividualUpdatableSettings, RawDocumentAdditionOptions, RecordAny, ResourceResults, @@ -40,6 +39,7 @@ import { TaskClient, type HttpRequestsWithEnqueuedTaskPromise, } from "./task.js"; +import { makeSettingFns, type SettingFns } from "./settings.js"; export class Index { uid: string; @@ -64,6 +64,34 @@ export class Index { this.httpRequest, this.tasks, ); + + this.#setting = makeSettingFns( + this.httpRequest, + this.#httpRequestsWithTask, + `indexes/${uid}/settings`, + { + filterableAttributes: "put", + sortableAttributes: "put", + displayedAttributes: "put", + typoTolerance: "patch", + searchableAttributes: "put", + stopWords: "put", + nonSeparatorTokens: "put", + separatorTokens: "put", + dictionary: "put", + synonyms: "put", + distinctAttribute: "put", + proximityPrecision: "put", + localizedAttributes: "put", + rankingRules: "put", + faceting: "patch", + pagination: "patch", + embedders: "patch", + searchCutoffMs: "put", + facetSearch: "put", + prefixSearch: "put", + }, + ); } /// @@ -543,589 +571,9 @@ export class Index { }); } - /// - /// PAGINATION SETTINGS - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-pagination-settings} */ - async getPagination(): Promise { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/pagination`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-pagination-settings} */ - updatePagination( - pagination: IndividualUpdatableSettings["pagination"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.patch({ - path: `indexes/${this.uid}/settings/pagination`, - body: pagination, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-pagination-settings} */ - resetPagination(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/pagination`, - }); - } - - /// - /// SYNONYMS - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-synonyms} */ - async getSynonyms(): Promise { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/synonyms`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-synonyms} */ - updateSynonyms( - synonyms: IndividualUpdatableSettings["synonyms"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/synonyms`, - body: synonyms, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-synonyms} */ - resetSynonyms(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/synonyms`, - }); - } - - /// - /// STOP WORDS - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-stop-words} */ - async getStopWords(): Promise { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/stop-words`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-stop-words} */ - updateStopWords( - stopWords: IndividualUpdatableSettings["stopWords"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/stop-words`, - body: stopWords, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-stop-words} */ - resetStopWords(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/stop-words`, - }); - } - - /// - /// RANKING RULES - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-ranking-rules} */ - async getRankingRules(): Promise< - IndividualUpdatableSettings["rankingRules"] - > { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/ranking-rules`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-ranking-rules} */ - updateRankingRules( - rankingRules: IndividualUpdatableSettings["rankingRules"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/ranking-rules`, - body: rankingRules, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-ranking-rules} */ - resetRankingRules(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/ranking-rules`, - }); - } - - /// - /// DISTINCT ATTRIBUTE - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-distinct-attribute} */ - async getDistinctAttribute(): Promise< - IndividualUpdatableSettings["distinctAttribute"] - > { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/distinct-attribute`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-distinct-attribute} */ - updateDistinctAttribute( - distinctAttribute: IndividualUpdatableSettings["distinctAttribute"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/distinct-attribute`, - body: distinctAttribute, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-distinct-attribute} */ - resetDistinctAttribute(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/distinct-attribute`, - }); - } - - /// - /// FILTERABLE ATTRIBUTES - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-filterable-attributes} */ - async getFilterableAttributes(): Promise< - IndividualUpdatableSettings["filterableAttributes"] - > { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/filterable-attributes`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-filterable-attributes} */ - updateFilterableAttributes( - filterableAttributes: IndividualUpdatableSettings["filterableAttributes"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/filterable-attributes`, - body: filterableAttributes, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-filterable-attributes} */ - resetFilterableAttributes(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/filterable-attributes`, - }); - } - - /// - /// SORTABLE ATTRIBUTES - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-sortable-attributes} */ - async getSortableAttributes(): Promise< - IndividualUpdatableSettings["sortableAttributes"] - > { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/sortable-attributes`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-sortable-attributes} */ - updateSortableAttributes( - sortableAttributes: IndividualUpdatableSettings["sortableAttributes"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/sortable-attributes`, - body: sortableAttributes, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-sortable-attributes} */ - resetSortableAttributes(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/sortable-attributes`, - }); - } - - /// - /// SEARCHABLE ATTRIBUTE - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-searchable-attributes} */ - async getSearchableAttributes(): Promise< - IndividualUpdatableSettings["searchableAttributes"] - > { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/searchable-attributes`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-searchable-attributes} */ - updateSearchableAttributes( - searchableAttributes: IndividualUpdatableSettings["searchableAttributes"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/searchable-attributes`, - body: searchableAttributes, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-searchable-attributes} */ - resetSearchableAttributes(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/searchable-attributes`, - }); - } - - /// - /// DISPLAYED ATTRIBUTE - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-displayed-attributes} */ - async getDisplayedAttributes(): Promise< - IndividualUpdatableSettings["displayedAttributes"] - > { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/displayed-attributes`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-displayed-attributes} */ - updateDisplayedAttributes( - displayedAttributes: IndividualUpdatableSettings["displayedAttributes"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/displayed-attributes`, - body: displayedAttributes, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-displayed-attributes} */ - resetDisplayedAttributes(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/displayed-attributes`, - }); - } - - /// - /// TYPO TOLERANCE - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-typo-tolerance-settings} */ - async getTypoTolerance(): Promise< - IndividualUpdatableSettings["typoTolerance"] - > { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/typo-tolerance`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-typo-tolerance-settings} */ - updateTypoTolerance( - typoTolerance: IndividualUpdatableSettings["typoTolerance"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.patch({ - path: `indexes/${this.uid}/settings/typo-tolerance`, - body: typoTolerance, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-typo-tolerance-settings} */ - resetTypoTolerance(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/typo-tolerance`, - }); - } - - /// - /// FACETING - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-faceting-settings} */ - async getFaceting(): Promise { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/faceting`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-faceting-settings} */ - updateFaceting( - faceting: IndividualUpdatableSettings["faceting"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.patch({ - path: `indexes/${this.uid}/settings/faceting`, - body: faceting, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-faceting-settings} */ - resetFaceting(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/faceting`, - }); - } - - /// - /// SEPARATOR TOKENS - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-separator-tokens} */ - async getSeparatorTokens(): Promise< - IndividualUpdatableSettings["separatorTokens"] - > { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/separator-tokens`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-separator-tokens} */ - updateSeparatorTokens( - separatorTokens: IndividualUpdatableSettings["separatorTokens"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/separator-tokens`, - body: separatorTokens, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-separator-tokens} */ - resetSeparatorTokens(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/separator-tokens`, - }); - } - - /// - /// NON-SEPARATOR TOKENS - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-non-separator-tokens} */ - async getNonSeparatorTokens(): Promise< - IndividualUpdatableSettings["nonSeparatorTokens"] - > { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/non-separator-tokens`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-non-separator-tokens} */ - updateNonSeparatorTokens( - nonSeparatorTokens: IndividualUpdatableSettings["nonSeparatorTokens"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/non-separator-tokens`, - body: nonSeparatorTokens, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-non-separator-tokens} */ - resetNonSeparatorTokens(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/non-separator-tokens`, - }); - } - - /// - /// DICTIONARY - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-dictionary} */ - async getDictionary(): Promise { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/dictionary`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-dictionary} */ - updateDictionary( - dictionary: IndividualUpdatableSettings["dictionary"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/dictionary`, - body: dictionary, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-dictionary} */ - resetDictionary(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/dictionary`, - }); - } - - /// - /// PROXIMITY PRECISION - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-proximity-precision-settings} */ - async getProximityPrecision(): Promise< - IndividualUpdatableSettings["proximityPrecision"] - > { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/proximity-precision`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-proximity-precision-settings} */ - updateProximityPrecision( - proximityPrecision: IndividualUpdatableSettings["proximityPrecision"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/proximity-precision`, - body: proximityPrecision, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-proximity-precision-settings} */ - resetProximityPrecision(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/proximity-precision`, - }); - } - - /// - /// EMBEDDERS - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-embedder-settings} */ - async getEmbedders(): Promise { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/embedders`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-embedder-settings} */ - updateEmbedders( - embedders: IndividualUpdatableSettings["embedders"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.patch({ - path: `indexes/${this.uid}/settings/embedders`, - body: embedders, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-embedder-settings} */ - resetEmbedders(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/embedders`, - }); - } - - /// - /// SEARCHCUTOFFMS SETTINGS - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-search-cutoff} */ - async getSearchCutoffMs(): Promise< - IndividualUpdatableSettings["searchCutoffMs"] - > { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/search-cutoff-ms`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-search-cutoff} */ - updateSearchCutoffMs( - searchCutoffMs: IndividualUpdatableSettings["searchCutoffMs"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/search-cutoff-ms`, - body: searchCutoffMs, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-search-cutoff} */ - resetSearchCutoffMs(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/search-cutoff-ms`, - }); - } - - /// - /// LOCALIZED ATTRIBUTES SETTINGS - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-localized-attributes-settings} */ - async getLocalizedAttributes(): Promise< - IndividualUpdatableSettings["localizedAttributes"] - > { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/localized-attributes`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-localized-attribute-settings} */ - updateLocalizedAttributes( - localizedAttributes: IndividualUpdatableSettings["localizedAttributes"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/localized-attributes`, - body: localizedAttributes, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-localized-attributes-settings} */ - resetLocalizedAttributes(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/localized-attributes`, - }); - } - - /// - /// FACET SEARCH SETTINGS - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-facet-search-settings} */ - async getFacetSearch(): Promise { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/facet-search`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-facet-search-settings} */ - updateFacetSearch( - facetSearch: IndividualUpdatableSettings["facetSearch"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/facet-search`, - body: facetSearch, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-facet-search-settings} */ - resetFacetSearch(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/facet-search`, - }); - } - - /// - /// PREFIX SEARCH SETTINGS - /// - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#get-prefix-search-settings} */ - async getPrefixSearch(): Promise< - IndividualUpdatableSettings["prefixSearch"] - > { - return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/prefix-search`, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#update-prefix-search-settings} */ - updatePrefixSearch( - prefixSearch: IndividualUpdatableSettings["prefixSearch"], - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/prefix-search`, - body: prefixSearch, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/settings#reset-prefix-search-settings} */ - resetPrefixSearch(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/prefix-search`, - }); + // TODO: Doc + readonly #setting: SettingFns; + get setting() { + return this.#setting; } } diff --git a/src/settings.ts b/src/settings.ts new file mode 100644 index 000000000..8349ab27d --- /dev/null +++ b/src/settings.ts @@ -0,0 +1,65 @@ +import type { HttpRequests } from "./http-requests.js"; +import type { HttpRequestsWithEnqueuedTaskPromise } from "./task.js"; +import type { + EnqueuedTaskPromise, + IndividualUpdatableSettings, + RecordAny, +} from "./types/index.js"; + +/** Each setting mapped to their REST method required for updates. */ +type MakeSettingsRecord = { + [TKey in keyof IndividualUpdatableSettings]: "put" | "patch"; +}; + +export type SettingFns = { + [TKey in keyof IndividualUpdatableSettings as `get${Capitalize}`]: () => Promise< + IndividualUpdatableSettings[TKey] + >; +} & { + [TKey in keyof IndividualUpdatableSettings as `update${Capitalize}`]: ( + body: IndividualUpdatableSettings[TKey], + ) => EnqueuedTaskPromise; +} & { + [TKey in keyof IndividualUpdatableSettings as `reset${Capitalize}`]: () => EnqueuedTaskPromise; +}; + +function capitalize(str: string): string { + return str.charAt(0).toUpperCase() + str.slice(1); +} + +function camelToKebabCase(str: string): string { + return str.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`); +} + +// TODO: Doc +export function makeSettingFns( + httpRequest: HttpRequests, + httpRequestsWithTask: HttpRequestsWithEnqueuedTaskPromise, + basePath: string, + opts: MakeSettingsRecord, +): SettingFns { + const settingFns = {} as RecordAny; + + for (const [name, method] of Object.entries(opts)) { + const uppercaseName = capitalize(name); + const path = `${basePath}/${camelToKebabCase(name)}`; + + settingFns[`get${uppercaseName}`] = async function (): Promise< + IndividualUpdatableSettings[keyof typeof opts] + > { + return await httpRequest.get({ path }); + }; + + settingFns[`update${uppercaseName}`] = function ( + body: IndividualUpdatableSettings[keyof typeof opts], + ): EnqueuedTaskPromise { + return httpRequestsWithTask[method]({ path, body }); + }; + + settingFns[`reset${uppercaseName}`] = function (): EnqueuedTaskPromise { + return httpRequestsWithTask.delete({ path }); + }; + } + + return settingFns as SettingFns; +} diff --git a/src/types/shared.ts b/src/types/shared.ts index e0359a927..4678a0988 100644 --- a/src/types/shared.ts +++ b/src/types/shared.ts @@ -6,4 +6,5 @@ export type CursorResults = { total: number; }; +// taken from https://stackoverflow.com/a/65642944 export type PascalToCamelCase = Uncapitalize; diff --git a/tests/dictionary.test.ts b/tests/dictionary.test.ts index c4ca74a78..aa0e6f927 100644 --- a/tests/dictionary.test.ts +++ b/tests/dictionary.test.ts @@ -26,7 +26,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default dictionary`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getDictionary(); + const response = await client.index(index.uid).setting.getDictionary(); expect(response).toEqual([]); }); @@ -34,9 +34,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update dictionary`, async () => { const client = await getClient(permission); const newDictionary = ["J. K.", "J. R. R."]; - await client.index(index.uid).updateDictionary(newDictionary).waitTask(); + await client + .index(index.uid) + .setting.updateDictionary(newDictionary) + .waitTask(); - const response = await client.index(index.uid).getDictionary(); + const response = await client.index(index.uid).setting.getDictionary(); expect(response).toEqual(newDictionary); }); @@ -44,18 +47,21 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update dictionary with null value`, async () => { const client = await getClient(permission); const newDictionary = null; - await client.index(index.uid).updateDictionary(newDictionary).waitTask(); + await client + .index(index.uid) + .setting.updateDictionary(newDictionary) + .waitTask(); - const response = await client.index(index.uid).getDictionary(); + const response = await client.index(index.uid).setting.getDictionary(); expect(response).toEqual([]); }); test(`${permission} key: Reset dictionary`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetDictionary().waitTask(); + await client.index(index.uid).setting.resetDictionary().waitTask(); - const response = await client.index(index.uid).getDictionary(); + const response = await client.index(index.uid).setting.getDictionary(); expect(response).toEqual([]); }); @@ -72,7 +78,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getDictionary(), + client.index(index.uid).setting.getDictionary(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -84,7 +90,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateDictionary([]), + client.index(index.uid).setting.updateDictionary([]), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -96,7 +102,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetDictionary(), + client.index(index.uid).setting.resetDictionary(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/displayed_attributes.test.ts b/tests/displayed_attributes.test.ts index 4195791ca..6e2847474 100644 --- a/tests/displayed_attributes.test.ts +++ b/tests/displayed_attributes.test.ts @@ -29,7 +29,9 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default displayed attributes`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getDisplayedAttributes(); + const response = await client + .index(index.uid) + .setting.getDisplayedAttributes(); expect(response).toEqual(["*"]); }); @@ -38,10 +40,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newDisplayedAttribute = ["title"]; await client .index(index.uid) - .updateDisplayedAttributes(newDisplayedAttribute) + .setting.updateDisplayedAttributes(newDisplayedAttribute) .waitTask(); - const response = await client.index(index.uid).getDisplayedAttributes(); + const response = await client + .index(index.uid) + .setting.getDisplayedAttributes(); expect(response).toEqual(newDisplayedAttribute); }); @@ -49,9 +53,14 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update displayed attributes at null`, async () => { const client = await getClient(permission); - await client.index(index.uid).updateDisplayedAttributes(null).waitTask(); + await client + .index(index.uid) + .setting.updateDisplayedAttributes(null) + .waitTask(); - const response = await client.index(index.uid).getDisplayedAttributes(); + const response = await client + .index(index.uid) + .setting.getDisplayedAttributes(); expect(response).toEqual(["*"]); }); @@ -59,9 +68,14 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Reset displayed attributes`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetDisplayedAttributes().waitTask(); + await client + .index(index.uid) + .setting.resetDisplayedAttributes() + .waitTask(); - const response = await client.index(index.uid).getDisplayedAttributes(); + const response = await client + .index(index.uid) + .setting.getDisplayedAttributes(); expect(response).toEqual(["*"]); }); @@ -80,21 +94,21 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get displayed attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getDisplayedAttributes(), + client.index(index.uid).setting.getDisplayedAttributes(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update displayed attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateDisplayedAttributes([]), + client.index(index.uid).setting.updateDisplayedAttributes([]), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset displayed attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetDisplayedAttributes(), + client.index(index.uid).setting.resetDisplayedAttributes(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -112,7 +126,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to get displayed attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getDisplayedAttributes(), + client.index(index.uid).setting.getDisplayedAttributes(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -122,7 +136,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to update displayed attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateDisplayedAttributes([]), + client.index(index.uid).setting.updateDisplayedAttributes([]), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -132,7 +146,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to reset displayed attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetDisplayedAttributes(), + client.index(index.uid).setting.resetDisplayedAttributes(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -151,7 +165,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getDisplayedAttributes(), + client.index(index.uid).setting.getDisplayedAttributes(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -163,7 +177,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateDisplayedAttributes([]), + client.index(index.uid).setting.updateDisplayedAttributes([]), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -175,7 +189,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetDisplayedAttributes(), + client.index(index.uid).setting.resetDisplayedAttributes(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/distinct_attribute.test.ts b/tests/distinct_attribute.test.ts index de3f8abe0..11db3d43d 100644 --- a/tests/distinct_attribute.test.ts +++ b/tests/distinct_attribute.test.ts @@ -29,7 +29,9 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default distinct attribute`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getDistinctAttribute(); + const response = await client + .index(index.uid) + .setting.getDistinctAttribute(); expect(response).toEqual(null); }); @@ -38,28 +40,37 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newDistinctAttribute = "title"; await client .index(index.uid) - .updateDistinctAttribute(newDistinctAttribute) + .setting.updateDistinctAttribute(newDistinctAttribute) .waitTask(); - const response = await client.index(index.uid).getDistinctAttribute(); + const response = await client + .index(index.uid) + .setting.getDistinctAttribute(); expect(response).toEqual(newDistinctAttribute); }); test(`${permission} key: Update distinct attribute at undefined`, async () => { const client = await getClient(permission); - await client.index(index.uid).updateDistinctAttribute(null).waitTask(); + await client + .index(index.uid) + .setting.updateDistinctAttribute(null) + .waitTask(); - const response = await client.index(index.uid).getDistinctAttribute(); + const response = await client + .index(index.uid) + .setting.getDistinctAttribute(); expect(response).toEqual(null); }); test(`${permission} key: Reset distinct attribute`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetDistinctAttribute().waitTask(); + await client.index(index.uid).setting.resetDistinctAttribute().waitTask(); - const response = await client.index(index.uid).getDistinctAttribute(); + const response = await client + .index(index.uid) + .setting.getDistinctAttribute(); expect(response).toEqual(null); }); @@ -76,21 +87,21 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get distinct attribute and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getDistinctAttribute(), + client.index(index.uid).setting.getDistinctAttribute(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update distinct attribute and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateDistinctAttribute("title"), + client.index(index.uid).setting.updateDistinctAttribute("title"), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset distinct attribute and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetDistinctAttribute(), + client.index(index.uid).setting.resetDistinctAttribute(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -106,7 +117,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to get distinct attribute and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getDistinctAttribute(), + client.index(index.uid).setting.getDistinctAttribute(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -116,7 +127,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to update distinct attribute and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateDistinctAttribute("title"), + client.index(index.uid).setting.updateDistinctAttribute("title"), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -126,7 +137,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to reset distinct attribute and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetDistinctAttribute(), + client.index(index.uid).setting.resetDistinctAttribute(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -145,7 +156,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getDistinctAttribute(), + client.index(index.uid).setting.getDistinctAttribute(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -157,7 +168,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateDistinctAttribute("a"), + client.index(index.uid).setting.updateDistinctAttribute("a"), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -169,7 +180,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetDistinctAttribute(), + client.index(index.uid).setting.resetDistinctAttribute(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/documents.test.ts b/tests/documents.test.ts index 786ca2b97..800f624d7 100644 --- a/tests/documents.test.ts +++ b/tests/documents.test.ts @@ -130,7 +130,7 @@ describe("Documents tests", () => { await client .index(indexPk.uid) - .updateFilterableAttributes(["id"]) + .setting.updateFilterableAttributes(["id"]) .waitTask(); await client.index(indexPk.uid).addDocuments(dataset).waitTask(); @@ -479,7 +479,9 @@ describe("Documents tests", () => { test(`${permission} key: Delete some documents with string filters`, async () => { const client = await getClient(permission); - await client.index(indexPk.uid).updateFilterableAttributes(["id"]); + await client + .index(indexPk.uid) + .setting.updateFilterableAttributes(["id"]); await client.index(indexPk.uid).addDocuments(dataset).waitTask(); const resolvedTask = await client @@ -495,7 +497,9 @@ describe("Documents tests", () => { test(`${permission} key: Delete some documents with array filters`, async () => { const client = await getClient(permission); - await client.index(indexPk.uid).updateFilterableAttributes(["id"]); + await client + .index(indexPk.uid) + .setting.updateFilterableAttributes(["id"]); await client.index(indexPk.uid).addDocuments(dataset).waitTask(); const resolvedTask = await client @@ -670,7 +674,7 @@ describe("Documents tests", () => { const index = client.index<(typeof dataset)[number]>(indexPk.uid); const adminKey = await getKey("Admin"); - await index.updateFilterableAttributes(["id"]).waitTask(); + await index.setting.updateFilterableAttributes(["id"]).waitTask(); await fetch(`${HOST}/experimental-features`, { body: JSON.stringify({ editDocumentsByFunction: true }), diff --git a/tests/embedders.test.ts b/tests/embedders.test.ts index 0a3d55537..9aa2c9708 100644 --- a/tests/embedders.test.ts +++ b/tests/embedders.test.ts @@ -61,7 +61,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default embedders`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).setting.getEmbedders(); expect(response).toEqual({}); }); @@ -79,9 +79,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( binaryQuantized: false, }, }; - await client.index(index.uid).updateEmbedders(newEmbedder).waitTask(); + await client + .index(index.uid) + .setting.updateEmbedders(newEmbedder) + .waitTask(); - const response = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).setting.getEmbedders(); expect(response).toEqual(newEmbedder); expect(response).not.toHaveProperty("documentTemplateMaxBytes"); @@ -106,9 +109,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( binaryQuantized: false, }, }; - await client.index(index.uid).updateEmbedders(newEmbedder).waitTask(); + await client + .index(index.uid) + .setting.updateEmbedders(newEmbedder) + .waitTask(); - const response = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).setting.getEmbedders(); expect(response).toEqual({ default: { @@ -136,10 +142,10 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( }; await client .index(index.uid) - .updateEmbedders(newEmbedder) + .setting.updateEmbedders(newEmbedder) .waitTask({ timeout: 60_000 }); - const response = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).setting.getEmbedders(); expect(response).toEqual(newEmbedder); }); @@ -177,9 +183,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( binaryQuantized: false, }, }; - await client.index(index.uid).updateEmbedders(newEmbedder).waitTask(); + await client + .index(index.uid) + .setting.updateEmbedders(newEmbedder) + .waitTask(); - const response = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).setting.getEmbedders(); expect(response).toEqual({ default: { @@ -207,9 +216,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( binaryQuantized: false, }, }; - await client.index(index.uid).updateEmbedders(newEmbedder).waitTask(); + await client + .index(index.uid) + .setting.updateEmbedders(newEmbedder) + .waitTask(); - const response = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).setting.getEmbedders(); expect(response).toEqual({ default: { @@ -228,18 +240,21 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( dimensions: 512, }, }; - await client.index(index.uid).updateEmbedders(newEmbedder).waitTask(); + await client + .index(index.uid) + .setting.updateEmbedders(newEmbedder) + .waitTask(); - const response = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).setting.getEmbedders(); expect(response).toEqual(newEmbedder); }); test(`${permission} key: Reset embedders`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetEmbedders().waitTask(); + await client.index(index.uid).setting.resetEmbedders().waitTask(); - const response = await client.index(index.uid).getEmbedders(); + const response = await client.index(index.uid).setting.getEmbedders(); expect(response).toEqual({}); }); @@ -249,7 +264,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( await client .index(index.uid) - .updateEmbedders({ + .setting.updateEmbedders({ default: { source: "userProvided", dimensions: 1, @@ -278,7 +293,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( await client .index(index.uid) - .updateEmbedders({ + .setting.updateEmbedders({ default: { source: "userProvided", dimensions: 1, @@ -309,7 +324,10 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( dimensions: 3, }, }; - await client.index(index.uid).updateEmbedders(newEmbedder).waitTask(); + await client + .index(index.uid) + .setting.updateEmbedders(newEmbedder) + .waitTask(); await client .index(index.uid) @@ -339,7 +357,9 @@ describe.each([ const route = `indexes/${index.uid}/settings/embedders`; const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.index(index.uid).getEmbedders()).rejects.toHaveProperty( + await expect( + client.index(index.uid).setting.getEmbedders(), + ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, ); @@ -350,7 +370,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateEmbedders({}), + client.index(index.uid).setting.updateEmbedders({}), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -362,7 +382,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetEmbedders(), + client.index(index.uid).setting.resetEmbedders(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/facet_search_settings.test.ts b/tests/facet_search_settings.test.ts index b0cc69531..6d3b2ad5a 100644 --- a/tests/facet_search_settings.test.ts +++ b/tests/facet_search_settings.test.ts @@ -29,25 +29,27 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get facetSearch settings on empty index`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getFacetSearch(); + const response = await client.index(index.uid).setting.getFacetSearch(); expect(response).toMatchSnapshot(); }); test(`${permission} key: Set facetSearch settings with dedicated endpoint on empty index`, async () => { const client = await getClient(permission); - await client.index(index.uid).updateFacetSearch(false).waitTask(); + await client.index(index.uid).setting.updateFacetSearch(false).waitTask(); - const updatedSettings = await client.index(index.uid).getFacetSearch(); + const updatedSettings = await client + .index(index.uid) + .setting.getFacetSearch(); expect(updatedSettings).toBe(false); }); test(`${permission} key: Reset facetSearch settings on an empty index`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetFacetSearch().waitTask(); + await client.index(index.uid).setting.resetFacetSearch().waitTask(); - const response = await client.index(index.uid).getFacetSearch(); + const response = await client.index(index.uid).setting.getFacetSearch(); expect(response).toMatchSnapshot(); }); }, @@ -65,21 +67,21 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get facet search settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getFacetSearch(), + client.index(index.uid).setting.getFacetSearch(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update facet search settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateFacetSearch(false), + client.index(index.uid).setting.updateFacetSearch(false), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset facet search settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetFacetSearch(), + client.index(index.uid).setting.resetFacetSearch(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -97,7 +99,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to get facet search settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getFacetSearch(), + client.index(index.uid).setting.getFacetSearch(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -107,7 +109,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to update facet search settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateFacetSearch(false), + client.index(index.uid).setting.updateFacetSearch(false), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -117,7 +119,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to reset facet search settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetFacetSearch(), + client.index(index.uid).setting.resetFacetSearch(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -136,7 +138,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getFacetSearch(), + client.index(index.uid).setting.getFacetSearch(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -148,7 +150,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateFacetSearch(false), + client.index(index.uid).setting.updateFacetSearch(false), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -160,7 +162,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetFacetSearch(), + client.index(index.uid).setting.resetFacetSearch(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/faceting.test.ts b/tests/faceting.test.ts index 32935cccf..ccde334be 100644 --- a/tests/faceting.test.ts +++ b/tests/faceting.test.ts @@ -38,7 +38,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default faceting object`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getFaceting(); + const response = await client.index(index.uid).setting.getFaceting(); expect(response).toMatchSnapshot(); }); @@ -49,9 +49,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( maxValuesPerFacet: 12, sortFacetValuesBy: { test: "count" }, }; - await client.index(index.uid).updateFaceting(newFaceting).waitTask(); + await client + .index(index.uid) + .setting.updateFaceting(newFaceting) + .waitTask(); - const response = await client.index(index.uid).getFaceting(); + const response = await client.index(index.uid).setting.getFaceting(); expect(response).toMatchSnapshot(); }); @@ -60,10 +63,10 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const client = await getClient(permission); await client .index(index.uid) - .updateFaceting({ maxValuesPerFacet: null }) + .setting.updateFaceting({ maxValuesPerFacet: null }) .waitTask(); - const response = await client.index(index.uid).getFaceting(); + const response = await client.index(index.uid).setting.getFaceting(); expect(response).toMatchSnapshot(); }); @@ -72,12 +75,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const client = await getClient(permission); await client .index(index.uid) - .updateFaceting({ maxValuesPerFacet: 12 }) + .setting.updateFaceting({ maxValuesPerFacet: 12 }) .waitTask(); - await client.index(index.uid).resetFaceting().waitTask(); + await client.index(index.uid).setting.resetFaceting().waitTask(); - const response = await client.index(index.uid).getFaceting(); + const response = await client.index(index.uid).setting.getFaceting(); expect(response).toMatchSnapshot(); }); @@ -95,21 +98,23 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get faceting and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getFaceting(), + client.index(index.uid).setting.getFaceting(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update faceting and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateFaceting({ maxValuesPerFacet: 13 }), + client + .index(index.uid) + .setting.updateFaceting({ maxValuesPerFacet: 13 }), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset faceting and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetFaceting(), + client.index(index.uid).setting.resetFaceting(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -123,7 +128,9 @@ describe.each([{ permission: "No" }])("Test on faceting", ({ permission }) => { test(`${permission} key: try to get faceting and be denied`, async () => { const client = await getClient(permission); - await expect(client.index(index.uid).getFaceting()).rejects.toHaveProperty( + await expect( + client.index(index.uid).setting.getFaceting(), + ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, ); @@ -132,7 +139,7 @@ describe.each([{ permission: "No" }])("Test on faceting", ({ permission }) => { test(`${permission} key: try to update faceting and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateFaceting({ maxValuesPerFacet: 13 }), + client.index(index.uid).setting.updateFaceting({ maxValuesPerFacet: 13 }), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -142,7 +149,7 @@ describe.each([{ permission: "No" }])("Test on faceting", ({ permission }) => { test(`${permission} key: try to reset faceting and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetFaceting(), + client.index(index.uid).setting.resetFaceting(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -159,7 +166,9 @@ describe.each([ const route = `indexes/${index.uid}/settings/faceting`; const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.index(index.uid).getFaceting()).rejects.toHaveProperty( + await expect( + client.index(index.uid).setting.getFaceting(), + ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, ); @@ -170,7 +179,9 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateFaceting({ maxValuesPerFacet: undefined }), + client + .index(index.uid) + .setting.updateFaceting({ maxValuesPerFacet: undefined }), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -182,7 +193,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetFaceting(), + client.index(index.uid).setting.resetFaceting(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/filterable_attributes.test.ts b/tests/filterable_attributes.test.ts index 3f3914826..be4f36e67 100644 --- a/tests/filterable_attributes.test.ts +++ b/tests/filterable_attributes.test.ts @@ -27,7 +27,9 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default attributes for filtering`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getFilterableAttributes(); + const response = await client + .index(index.uid) + .setting.getFilterableAttributes(); expect(response?.sort()).toEqual([]); }); @@ -37,27 +39,39 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newFilterableAttributes = ["genre"]; await client .index(index.uid) - .updateFilterableAttributes(newFilterableAttributes) + .setting.updateFilterableAttributes(newFilterableAttributes) .waitTask(); - const response = await client.index(index.uid).getFilterableAttributes(); + const response = await client + .index(index.uid) + .setting.getFilterableAttributes(); expect(response).toEqual(newFilterableAttributes); }); test(`${permission} key: Update attributes for filtering at null`, async () => { const client = await getClient(permission); - await client.index(index.uid).updateFilterableAttributes(null).waitTask(); + await client + .index(index.uid) + .setting.updateFilterableAttributes(null) + .waitTask(); - const response = await client.index(index.uid).getFilterableAttributes(); + const response = await client + .index(index.uid) + .setting.getFilterableAttributes(); expect(response?.sort()).toEqual([]); }); test(`${permission} key: Reset attributes for filtering`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetFilterableAttributes().waitTask(); + await client + .index(index.uid) + .setting.resetFilterableAttributes() + .waitTask(); - const response = await client.index(index.uid).getFilterableAttributes(); + const response = await client + .index(index.uid) + .setting.getFilterableAttributes(); expect(response?.sort()).toEqual([]); }); @@ -75,21 +89,21 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get attributes for filtering and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getFilterableAttributes(), + client.index(index.uid).setting.getFilterableAttributes(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update attributes for filtering and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateFilterableAttributes([]), + client.index(index.uid).setting.updateFilterableAttributes([]), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset attributes for filtering and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetFilterableAttributes(), + client.index(index.uid).setting.resetFilterableAttributes(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -106,7 +120,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to get attributes for filtering and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getFilterableAttributes(), + client.index(index.uid).setting.getFilterableAttributes(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -116,7 +130,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to update attributes for filtering and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateFilterableAttributes([]), + client.index(index.uid).setting.updateFilterableAttributes([]), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -126,7 +140,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to reset attributes for filtering and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetFilterableAttributes(), + client.index(index.uid).setting.resetFilterableAttributes(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -145,7 +159,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getFilterableAttributes(), + client.index(index.uid).setting.getFilterableAttributes(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -157,7 +171,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateFilterableAttributes([]), + client.index(index.uid).setting.updateFilterableAttributes([]), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -169,7 +183,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetFilterableAttributes(), + client.index(index.uid).setting.resetFilterableAttributes(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/localized_attributes.test.ts b/tests/localized_attributes.test.ts index c485f19c3..2c325fbd0 100644 --- a/tests/localized_attributes.test.ts +++ b/tests/localized_attributes.test.ts @@ -40,7 +40,9 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default localizedAttributes settings`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getLocalizedAttributes(); + const response = await client + .index(index.uid) + .setting.getLocalizedAttributes(); expect(response).toEqual(DEFAULT_LOCALIZED_ATTRIBUTES); }); @@ -51,10 +53,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( [{ attributePatterns: ["title"], locales: ["eng"] }]; await client .index(index.uid) - .updateLocalizedAttributes(newLocalizedAttributes) + .setting.updateLocalizedAttributes(newLocalizedAttributes) .waitTask(); - const response = await client.index(index.uid).getLocalizedAttributes(); + const response = await client + .index(index.uid) + .setting.getLocalizedAttributes(); expect(response).toEqual(newLocalizedAttributes); }); @@ -64,10 +68,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newLocalizedAttributes = null; await client .index(index.uid) - .updateLocalizedAttributes(newLocalizedAttributes) + .setting.updateLocalizedAttributes(newLocalizedAttributes) .waitTask(); - const response = await client.index(index.uid).getLocalizedAttributes(); + const response = await client + .index(index.uid) + .setting.getLocalizedAttributes(); expect(response).toEqual(DEFAULT_LOCALIZED_ATTRIBUTES); }); @@ -80,7 +86,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( await expect( client .index(index.uid) - .updateLocalizedAttributes(newLocalizedAttributes), + .setting.updateLocalizedAttributes(newLocalizedAttributes), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.INVALID_SETTINGS_LOCALIZED_ATTRIBUTES, @@ -93,11 +99,16 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( []; await client .index(index.uid) - .updateLocalizedAttributes(newLocalizedAttributes) + .setting.updateLocalizedAttributes(newLocalizedAttributes) + .waitTask(); + await client + .index(index.uid) + .setting.resetLocalizedAttributes() .waitTask(); - await client.index(index.uid).resetLocalizedAttributes().waitTask(); - const response = await client.index(index.uid).getLocalizedAttributes(); + const response = await client + .index(index.uid) + .setting.getLocalizedAttributes(); expect(response).toEqual(DEFAULT_LOCALIZED_ATTRIBUTES); }); @@ -115,21 +126,21 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get localizedAttributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getLocalizedAttributes(), + client.index(index.uid).setting.getLocalizedAttributes(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update localizedAttributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateLocalizedAttributes([]), + client.index(index.uid).setting.updateLocalizedAttributes([]), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset localizedAttributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetLocalizedAttributes(), + client.index(index.uid).setting.resetLocalizedAttributes(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -146,7 +157,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to get localizedAttributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getLocalizedAttributes(), + client.index(index.uid).setting.getLocalizedAttributes(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -156,7 +167,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to update localizedAttributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateLocalizedAttributes([]), + client.index(index.uid).setting.updateLocalizedAttributes([]), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -166,7 +177,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to reset localizedAttributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetLocalizedAttributes(), + client.index(index.uid).setting.resetLocalizedAttributes(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -185,7 +196,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getLocalizedAttributes(), + client.index(index.uid).setting.getLocalizedAttributes(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -197,7 +208,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateLocalizedAttributes(null), + client.index(index.uid).setting.updateLocalizedAttributes(null), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -209,7 +220,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetLocalizedAttributes(), + client.index(index.uid).setting.resetLocalizedAttributes(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/non_separator_tokens.test.ts b/tests/non_separator_tokens.test.ts index 28c9dae82..9279693ad 100644 --- a/tests/non_separator_tokens.test.ts +++ b/tests/non_separator_tokens.test.ts @@ -26,7 +26,9 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default non separator tokens`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getNonSeparatorTokens(); + const response = await client + .index(index.uid) + .setting.getNonSeparatorTokens(); expect(response).toEqual([]); }); @@ -36,10 +38,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newNonSeparatorTokens = ["&sep", "/", "|"]; await client .index(index.uid) - .updateNonSeparatorTokens(newNonSeparatorTokens) + .setting.updateNonSeparatorTokens(newNonSeparatorTokens) .waitTask(); - const response = await client.index(index.uid).getNonSeparatorTokens(); + const response = await client + .index(index.uid) + .setting.getNonSeparatorTokens(); expect(response).toEqual(newNonSeparatorTokens); }); @@ -49,19 +53,26 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newNonSeparatorTokens = null; await client .index(index.uid) - .updateNonSeparatorTokens(newNonSeparatorTokens) + .setting.updateNonSeparatorTokens(newNonSeparatorTokens) .waitTask(); - const response = await client.index(index.uid).getNonSeparatorTokens(); + const response = await client + .index(index.uid) + .setting.getNonSeparatorTokens(); expect(response).toEqual([]); }); test(`${permission} key: Reset NonSeparator tokens`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetNonSeparatorTokens().waitTask(); + await client + .index(index.uid) + .setting.resetNonSeparatorTokens() + .waitTask(); - const response = await client.index(index.uid).getNonSeparatorTokens(); + const response = await client + .index(index.uid) + .setting.getNonSeparatorTokens(); expect(response).toEqual([]); }); @@ -78,7 +89,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getNonSeparatorTokens(), + client.index(index.uid).setting.getNonSeparatorTokens(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -90,7 +101,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateNonSeparatorTokens([]), + client.index(index.uid).setting.updateNonSeparatorTokens([]), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -102,7 +113,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetNonSeparatorTokens(), + client.index(index.uid).setting.resetNonSeparatorTokens(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/pagination.test.ts b/tests/pagination.test.ts index 38d812d01..25280f509 100644 --- a/tests/pagination.test.ts +++ b/tests/pagination.test.ts @@ -35,7 +35,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default pagination settings`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getPagination(); + const response = await client.index(index.uid).setting.getPagination(); expect(response).toEqual({ maxTotalHits: 1000 }); }); @@ -45,9 +45,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newPagination = { maxTotalHits: 100, }; - await client.index(index.uid).updatePagination(newPagination).waitTask(); + await client + .index(index.uid) + .setting.updatePagination(newPagination) + .waitTask(); - const response = await client.index(index.uid).getPagination(); + const response = await client.index(index.uid).setting.getPagination(); expect(response).toEqual(newPagination); }); @@ -57,9 +60,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newPagination = { maxTotalHits: null, }; - await client.index(index.uid).updatePagination(newPagination).waitTask(); + await client + .index(index.uid) + .setting.updatePagination(newPagination) + .waitTask(); - const response = await client.index(index.uid).getPagination(); + const response = await client.index(index.uid).setting.getPagination(); expect(response).toEqual({ maxTotalHits: 1000 }); }); @@ -69,10 +75,13 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newPagination = { maxTotalHits: 100, }; - await client.index(index.uid).updatePagination(newPagination).waitTask(); - await client.index(index.uid).resetPagination().waitTask(); + await client + .index(index.uid) + .setting.updatePagination(newPagination) + .waitTask(); + await client.index(index.uid).setting.resetPagination().waitTask(); - const response = await client.index(index.uid).getPagination(); + const response = await client.index(index.uid).setting.getPagination(); expect(response).toEqual({ maxTotalHits: 1000 }); }); @@ -90,21 +99,21 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get pagination and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getPagination(), + client.index(index.uid).setting.getPagination(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update pagination and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updatePagination({ maxTotalHits: 10 }), + client.index(index.uid).setting.updatePagination({ maxTotalHits: 10 }), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset pagination and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetPagination(), + client.index(index.uid).setting.resetPagination(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -121,7 +130,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to get pagination and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getPagination(), + client.index(index.uid).setting.getPagination(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -131,7 +140,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to update pagination and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updatePagination({ maxTotalHits: 10 }), + client.index(index.uid).setting.updatePagination({ maxTotalHits: 10 }), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -141,7 +150,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to reset pagination and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetPagination(), + client.index(index.uid).setting.resetPagination(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -160,7 +169,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getPagination(), + client.index(index.uid).setting.getPagination(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -172,7 +181,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updatePagination({ maxTotalHits: null }), + client.index(index.uid).setting.updatePagination({ maxTotalHits: null }), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -184,7 +193,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetPagination(), + client.index(index.uid).setting.resetPagination(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/prefix_search_settings.test.ts b/tests/prefix_search_settings.test.ts index 951953374..6453b7fae 100644 --- a/tests/prefix_search_settings.test.ts +++ b/tests/prefix_search_settings.test.ts @@ -29,25 +29,30 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get prefixSearch settings on empty index`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getPrefixSearch(); + const response = await client.index(index.uid).setting.getPrefixSearch(); expect(response).toMatchSnapshot(); }); test(`${permission} key: Set prefixSearch settings with dedicated endpoint on empty index`, async () => { const client = await getClient(permission); - await client.index(index.uid).updatePrefixSearch("disabled").waitTask(); + await client + .index(index.uid) + .setting.updatePrefixSearch("disabled") + .waitTask(); - const updatedSettings = await client.index(index.uid).getPrefixSearch(); + const updatedSettings = await client + .index(index.uid) + .setting.getPrefixSearch(); expect(updatedSettings).toBe("disabled"); }); test(`${permission} key: Reset prefixSearch settings on an empty index`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetPrefixSearch().waitTask(); + await client.index(index.uid).setting.resetPrefixSearch().waitTask(); - const response = await client.index(index.uid).getPrefixSearch(); + const response = await client.index(index.uid).setting.getPrefixSearch(); expect(response).toMatchSnapshot(); }); }, @@ -65,21 +70,21 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get prefix search settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getPrefixSearch(), + client.index(index.uid).setting.getPrefixSearch(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update prefix search settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updatePrefixSearch("disabled"), + client.index(index.uid).setting.updatePrefixSearch("disabled"), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset prefix search settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetPrefixSearch(), + client.index(index.uid).setting.resetPrefixSearch(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -97,7 +102,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to get prefix search settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getPrefixSearch(), + client.index(index.uid).setting.getPrefixSearch(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -107,7 +112,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to update prefix search settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updatePrefixSearch("disabled"), + client.index(index.uid).setting.updatePrefixSearch("disabled"), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -117,7 +122,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to reset prefix search settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetPrefixSearch(), + client.index(index.uid).setting.resetPrefixSearch(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -136,7 +141,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getPrefixSearch(), + client.index(index.uid).setting.getPrefixSearch(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -148,7 +153,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updatePrefixSearch("disabled"), + client.index(index.uid).setting.updatePrefixSearch("disabled"), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -160,7 +165,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetPrefixSearch(), + client.index(index.uid).setting.resetPrefixSearch(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/proximity_precision.test.ts b/tests/proximity_precision.test.ts index 8500ca3fd..e76b88b4a 100644 --- a/tests/proximity_precision.test.ts +++ b/tests/proximity_precision.test.ts @@ -26,7 +26,9 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default proximity precision`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getProximityPrecision(); + const response = await client + .index(index.uid) + .setting.getProximityPrecision(); expect(response).toEqual("byWord"); }); @@ -36,10 +38,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newProximityPrecision = "byAttribute"; await client .index(index.uid) - .updateProximityPrecision(newProximityPrecision) + .setting.updateProximityPrecision(newProximityPrecision) .waitTask(); - const response = await client.index(index.uid).getProximityPrecision(); + const response = await client + .index(index.uid) + .setting.getProximityPrecision(); expect(response).toEqual(newProximityPrecision); }); @@ -49,19 +53,26 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newProximityPrecision = "byWord"; await client .index(index.uid) - .updateProximityPrecision(newProximityPrecision) + .setting.updateProximityPrecision(newProximityPrecision) .waitTask(); - const response = await client.index(index.uid).getProximityPrecision(); + const response = await client + .index(index.uid) + .setting.getProximityPrecision(); expect(response).toEqual(newProximityPrecision); }); test(`${permission} key: Reset proximity precision`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetProximityPrecision().waitTask(); + await client + .index(index.uid) + .setting.resetProximityPrecision() + .waitTask(); - const response = await client.index(index.uid).getProximityPrecision(); + const response = await client + .index(index.uid) + .setting.getProximityPrecision(); expect(response).toEqual("byWord"); }); @@ -78,7 +89,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getProximityPrecision(), + client.index(index.uid).setting.getProximityPrecision(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -90,7 +101,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateProximityPrecision("byAttribute"), + client.index(index.uid).setting.updateProximityPrecision("byAttribute"), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -102,7 +113,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetProximityPrecision(), + client.index(index.uid).setting.resetProximityPrecision(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/ranking_rules.test.ts b/tests/ranking_rules.test.ts index 4bf114fee..8da726f7a 100644 --- a/tests/ranking_rules.test.ts +++ b/tests/ranking_rules.test.ts @@ -37,7 +37,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default ranking rules`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getRankingRules(); + const response = await client.index(index.uid).setting.getRankingRules(); expect(response).toEqual(defaultRankingRules); }); @@ -50,28 +50,28 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( ]; await client .index(index.uid) - .updateRankingRules(newRankingRules) + .setting.updateRankingRules(newRankingRules) .waitTask(); - const response = await client.index(index.uid).getRankingRules(); + const response = await client.index(index.uid).setting.getRankingRules(); expect(response).toEqual(newRankingRules); }); test(`${permission} key: Update ranking rules at null`, async () => { const client = await getClient(permission); - await client.index(index.uid).updateRankingRules(null).waitTask(); + await client.index(index.uid).setting.updateRankingRules(null).waitTask(); - const response = await client.index(index.uid).getRankingRules(); + const response = await client.index(index.uid).setting.getRankingRules(); expect(response).toEqual(defaultRankingRules); }); test(`${permission} key: Reset ranking rules`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetRankingRules().waitTask(); + await client.index(index.uid).setting.resetRankingRules().waitTask(); - const response = await client.index(index.uid).getRankingRules(); + const response = await client.index(index.uid).setting.getRankingRules(); expect(response).toEqual(defaultRankingRules); }); @@ -88,21 +88,21 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get ranking rules and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getRankingRules(), + client.index(index.uid).setting.getRankingRules(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update ranking rules and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateRankingRules([]), + client.index(index.uid).setting.updateRankingRules([]), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset ranking rules and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetRankingRules(), + client.index(index.uid).setting.resetRankingRules(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -118,7 +118,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to get ranking rules and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getRankingRules(), + client.index(index.uid).setting.getRankingRules(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -128,7 +128,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to update ranking rules and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateRankingRules([]), + client.index(index.uid).setting.updateRankingRules([]), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -138,7 +138,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to reset ranking rules and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetRankingRules(), + client.index(index.uid).setting.resetRankingRules(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -157,7 +157,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getRankingRules(), + client.index(index.uid).setting.getRankingRules(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -169,7 +169,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateRankingRules([]), + client.index(index.uid).setting.updateRankingRules([]), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -181,7 +181,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetRankingRules(), + client.index(index.uid).setting.resetRankingRules(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/search.test.ts b/tests/search.test.ts index 5f4643b9c..233afecfe 100644 --- a/tests/search.test.ts +++ b/tests/search.test.ts @@ -1221,7 +1221,7 @@ describe.each([ await masterClient .index(index.uid) - .updateLocalizedAttributes([ + .setting.updateLocalizedAttributes([ { attributePatterns: ["title", "comment"], locales: ["fra", "eng"] }, ]) .waitTask(); @@ -1429,6 +1429,7 @@ describe.each([ }); test(`${permission} key: search should be aborted when reaching timeout`, async () => { + // TODO: AssertionError: expected value to not resolve const key = await getKey(permission); const client = new MeiliSearch({ ...config, diff --git a/tests/search_cutoff_ms.test.ts b/tests/search_cutoff_ms.test.ts index 7292759b4..4098cb681 100644 --- a/tests/search_cutoff_ms.test.ts +++ b/tests/search_cutoff_ms.test.ts @@ -40,7 +40,9 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default searchCutoffMs settings`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getSearchCutoffMs(); + const response = await client + .index(index.uid) + .setting.getSearchCutoffMs(); expect(response).toEqual(DEFAULT_SEARCHCUTOFF_MS); }); @@ -50,10 +52,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newSearchCutoffMs = 100; await client .index(index.uid) - .updateSearchCutoffMs(newSearchCutoffMs) + .setting.updateSearchCutoffMs(newSearchCutoffMs) .waitTask(); - const response = await client.index(index.uid).getSearchCutoffMs(); + const response = await client + .index(index.uid) + .setting.getSearchCutoffMs(); expect(response).toEqual(newSearchCutoffMs); }); @@ -63,10 +67,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newSearchCutoffMs = null; await client .index(index.uid) - .updateSearchCutoffMs(newSearchCutoffMs) + .setting.updateSearchCutoffMs(newSearchCutoffMs) .waitTask(); - const response = await client.index(index.uid).getSearchCutoffMs(); + const response = await client + .index(index.uid) + .setting.getSearchCutoffMs(); expect(response).toEqual(DEFAULT_SEARCHCUTOFF_MS); }); @@ -77,7 +83,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( "hello" as unknown as IndividualUpdatableSettings["searchCutoffMs"]; // bad searchCutoffMs value await expect( - client.index(index.uid).updateSearchCutoffMs(newSearchCutoffMs), + client.index(index.uid).setting.updateSearchCutoffMs(newSearchCutoffMs), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.INVALID_SETTINGS_SEARCH_CUTOFF_MS, @@ -89,11 +95,13 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newSearchCutoffMs = 100; await client .index(index.uid) - .updateSearchCutoffMs(newSearchCutoffMs) + .setting.updateSearchCutoffMs(newSearchCutoffMs) .waitTask(); - await client.index(index.uid).resetSearchCutoffMs().waitTask(); + await client.index(index.uid).setting.resetSearchCutoffMs().waitTask(); - const response = await client.index(index.uid).getSearchCutoffMs(); + const response = await client + .index(index.uid) + .setting.getSearchCutoffMs(); expect(response).toEqual(DEFAULT_SEARCHCUTOFF_MS); }); @@ -111,21 +119,21 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get searchCutoffMs and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getSearchCutoffMs(), + client.index(index.uid).setting.getSearchCutoffMs(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update searchCutoffMs and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateSearchCutoffMs(100), + client.index(index.uid).setting.updateSearchCutoffMs(100), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset searchCutoffMs and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetSearchCutoffMs(), + client.index(index.uid).setting.resetSearchCutoffMs(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -142,7 +150,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to get searchCutoffMs and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getSearchCutoffMs(), + client.index(index.uid).setting.getSearchCutoffMs(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -152,7 +160,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to update searchCutoffMs and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateSearchCutoffMs(100), + client.index(index.uid).setting.updateSearchCutoffMs(100), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -162,7 +170,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to reset searchCutoffMs and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetSearchCutoffMs(), + client.index(index.uid).setting.resetSearchCutoffMs(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -181,7 +189,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getSearchCutoffMs(), + client.index(index.uid).setting.getSearchCutoffMs(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -193,7 +201,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateSearchCutoffMs(null), + client.index(index.uid).setting.updateSearchCutoffMs(null), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -205,7 +213,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetSearchCutoffMs(), + client.index(index.uid).setting.resetSearchCutoffMs(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/searchable_attributes.test.ts b/tests/searchable_attributes.test.ts index 9bb1e0f25..0fd890532 100644 --- a/tests/searchable_attributes.test.ts +++ b/tests/searchable_attributes.test.ts @@ -35,7 +35,9 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default searchable attributes`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getSearchableAttributes(); + const response = await client + .index(index.uid) + .setting.getSearchableAttributes(); expect(response).toEqual(["*"]); }); @@ -45,28 +47,40 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newSearchableAttributes = ["title"]; await client .index(index.uid) - .updateSearchableAttributes(newSearchableAttributes) + .setting.updateSearchableAttributes(newSearchableAttributes) .waitTask(); - const response = await client.index(index.uid).getSearchableAttributes(); + const response = await client + .index(index.uid) + .setting.getSearchableAttributes(); expect(response).toEqual(newSearchableAttributes); }); test(`${permission} key: Update searchable attributes at null`, async () => { const client = await getClient(permission); - await client.index(index.uid).updateSearchableAttributes(null).waitTask(); + await client + .index(index.uid) + .setting.updateSearchableAttributes(null) + .waitTask(); - const response = await client.index(index.uid).getSearchableAttributes(); + const response = await client + .index(index.uid) + .setting.getSearchableAttributes(); expect(response).toEqual(["*"]); }); test(`${permission} key: Reset searchable attributes`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetSearchableAttributes().waitTask(); + await client + .index(index.uid) + .setting.resetSearchableAttributes() + .waitTask(); - const response = await client.index(index.uid).getSearchableAttributes(); + const response = await client + .index(index.uid) + .setting.getSearchableAttributes(); expect(response).toEqual(["*"]); }); @@ -84,21 +98,21 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get searchable attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getSearchableAttributes(), + client.index(index.uid).setting.getSearchableAttributes(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update searchable attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateSearchableAttributes([]), + client.index(index.uid).setting.updateSearchableAttributes([]), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset searchable attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetSearchableAttributes(), + client.index(index.uid).setting.resetSearchableAttributes(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -115,7 +129,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to get searchable attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getSearchableAttributes(), + client.index(index.uid).setting.getSearchableAttributes(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -125,7 +139,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to update searchable attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateSearchableAttributes([]), + client.index(index.uid).setting.updateSearchableAttributes([]), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -135,7 +149,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to reset searchable attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetSearchableAttributes(), + client.index(index.uid).setting.resetSearchableAttributes(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -154,7 +168,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getSearchableAttributes(), + client.index(index.uid).setting.getSearchableAttributes(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -166,7 +180,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateSearchableAttributes([]), + client.index(index.uid).setting.updateSearchableAttributes([]), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -178,7 +192,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetSearchableAttributes(), + client.index(index.uid).setting.resetSearchableAttributes(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/separator_tokens.test.ts b/tests/separator_tokens.test.ts index d780eacde..875869a89 100644 --- a/tests/separator_tokens.test.ts +++ b/tests/separator_tokens.test.ts @@ -26,7 +26,9 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default separator tokens`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getSeparatorTokens(); + const response = await client + .index(index.uid) + .setting.getSeparatorTokens(); expect(response).toEqual([]); }); @@ -36,10 +38,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newSeparatorTokens = ["&sep", "/", "|"]; await client .index(index.uid) - .updateSeparatorTokens(newSeparatorTokens) + .setting.updateSeparatorTokens(newSeparatorTokens) .waitTask(); - const response = await client.index(index.uid).getSeparatorTokens(); + const response = await client + .index(index.uid) + .setting.getSeparatorTokens(); expect(response).toEqual(newSeparatorTokens); }); @@ -49,19 +53,23 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newSeparatorTokens = null; await client .index(index.uid) - .updateSeparatorTokens(newSeparatorTokens) + .setting.updateSeparatorTokens(newSeparatorTokens) .waitTask(); - const response = await client.index(index.uid).getSeparatorTokens(); + const response = await client + .index(index.uid) + .setting.getSeparatorTokens(); expect(response).toEqual([]); }); test(`${permission} key: Reset separator tokens`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetSeparatorTokens().waitTask(); + await client.index(index.uid).setting.resetSeparatorTokens().waitTask(); - const response = await client.index(index.uid).getSeparatorTokens(); + const response = await client + .index(index.uid) + .setting.getSeparatorTokens(); expect(response).toEqual([]); }); @@ -78,7 +86,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getSeparatorTokens(), + client.index(index.uid).setting.getSeparatorTokens(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -90,7 +98,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateSeparatorTokens([]), + client.index(index.uid).setting.updateSeparatorTokens([]), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -102,7 +110,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetSeparatorTokens(), + client.index(index.uid).setting.resetSeparatorTokens(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/sortable_attributes.test.ts b/tests/sortable_attributes.test.ts index 3ae4b6fb7..fda20e7ee 100644 --- a/tests/sortable_attributes.test.ts +++ b/tests/sortable_attributes.test.ts @@ -37,7 +37,9 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default sortable attributes`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getSortableAttributes(); + const response = await client + .index(index.uid) + .setting.getSortableAttributes(); expect(response).toEqual([]); }); @@ -47,27 +49,39 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newSortableAttributes = ["title"]; await client .index(index.uid) - .updateSortableAttributes(newSortableAttributes) + .setting.updateSortableAttributes(newSortableAttributes) .waitTask(); - const response = await client.index(index.uid).getSortableAttributes(); + const response = await client + .index(index.uid) + .setting.getSortableAttributes(); expect(response).toEqual(newSortableAttributes); }); test(`${permission} key: Update sortable attributes at null`, async () => { const client = await getClient(permission); - await client.index(index.uid).updateSortableAttributes(null).waitTask(); + await client + .index(index.uid) + .setting.updateSortableAttributes(null) + .waitTask(); - const response = await client.index(index.uid).getSortableAttributes(); + const response = await client + .index(index.uid) + .setting.getSortableAttributes(); expect(response).toEqual([]); }); test(`${permission} key: Reset sortable attributes`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetSortableAttributes().waitTask(); + await client + .index(index.uid) + .setting.resetSortableAttributes() + .waitTask(); - const response = await client.index(index.uid).getSortableAttributes(); + const response = await client + .index(index.uid) + .setting.getSortableAttributes(); expect(response).toEqual([]); }); @@ -85,21 +99,21 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get sortable attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getSortableAttributes(), + client.index(index.uid).setting.getSortableAttributes(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update sortable attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateSortableAttributes([]), + client.index(index.uid).setting.updateSortableAttributes([]), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset sortable attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetSortableAttributes(), + client.index(index.uid).setting.resetSortableAttributes(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -116,7 +130,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to get sortable attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getSortableAttributes(), + client.index(index.uid).setting.getSortableAttributes(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -127,7 +141,7 @@ describe.each([{ permission: "No" }])( const client = await getClient(permission); const resetSortable: string[] = []; await expect( - client.index(index.uid).updateSortableAttributes(resetSortable), + client.index(index.uid).setting.updateSortableAttributes(resetSortable), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -137,7 +151,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to reset sortable attributes and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetSortableAttributes(), + client.index(index.uid).setting.resetSortableAttributes(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -156,7 +170,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getSortableAttributes(), + client.index(index.uid).setting.getSortableAttributes(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -168,7 +182,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateSortableAttributes([]), + client.index(index.uid).setting.updateSortableAttributes([]), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -180,7 +194,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetSortableAttributes(), + client.index(index.uid).setting.resetSortableAttributes(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/stop_words.test.ts b/tests/stop_words.test.ts index be3a43305..3e718a581 100644 --- a/tests/stop_words.test.ts +++ b/tests/stop_words.test.ts @@ -27,7 +27,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default stop words`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getStopWords(); + const response = await client.index(index.uid).setting.getStopWords(); expect(response).toEqual([]); }); @@ -35,9 +35,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update stop words`, async () => { const client = await getClient(permission); const newStopWords = ["the"]; - await client.index(index.uid).updateStopWords(newStopWords).waitTask(); + await client + .index(index.uid) + .setting.updateStopWords(newStopWords) + .waitTask(); - const response = await client.index(index.uid).getStopWords(); + const response = await client.index(index.uid).setting.getStopWords(); expect(response).toEqual(newStopWords); }); @@ -45,18 +48,21 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update stop words with null value`, async () => { const client = await getClient(permission); const newStopWords = null; - await client.index(index.uid).updateStopWords(newStopWords).waitTask(); + await client + .index(index.uid) + .setting.updateStopWords(newStopWords) + .waitTask(); - const response = await client.index(index.uid).getStopWords(); + const response = await client.index(index.uid).setting.getStopWords(); expect(response).toEqual([]); }); test(`${permission} key: Reset stop words`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetStopWords().waitTask(); + await client.index(index.uid).setting.resetStopWords().waitTask(); - const response = await client.index(index.uid).getStopWords(); + const response = await client.index(index.uid).setting.getStopWords(); expect(response).toEqual([]); }); @@ -73,21 +79,21 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get stop words and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getStopWords(), + client.index(index.uid).setting.getStopWords(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update stop words and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateStopWords([]), + client.index(index.uid).setting.updateStopWords([]), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset stop words and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetStopWords(), + client.index(index.uid).setting.resetStopWords(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -103,7 +109,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to get stop words and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getStopWords(), + client.index(index.uid).setting.getStopWords(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -113,7 +119,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to update stop words and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateStopWords([]), + client.index(index.uid).setting.updateStopWords([]), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -123,7 +129,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to reset stop words and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetStopWords(), + client.index(index.uid).setting.resetStopWords(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -141,7 +147,9 @@ describe.each([ const route = `indexes/${index.uid}/settings/stop-words`; const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.index(index.uid).getStopWords()).rejects.toHaveProperty( + await expect( + client.index(index.uid).setting.getStopWords(), + ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, ); @@ -152,7 +160,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateStopWords([]), + client.index(index.uid).setting.updateStopWords([]), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -164,7 +172,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetStopWords(), + client.index(index.uid).setting.resetStopWords(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/synonyms.test.ts b/tests/synonyms.test.ts index b2c07c33a..b5eed8b6a 100644 --- a/tests/synonyms.test.ts +++ b/tests/synonyms.test.ts @@ -27,7 +27,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default synonyms`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getSynonyms(); + const response = await client.index(index.uid).setting.getSynonyms(); expect(response).toEqual({}); }); @@ -37,9 +37,12 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const newSynonyms = { hp: ["harry potter"], }; - await client.index(index.uid).updateSynonyms(newSynonyms).waitTask(); + await client + .index(index.uid) + .setting.updateSynonyms(newSynonyms) + .waitTask(); - const response = await client.index(index.uid).getSynonyms(); + const response = await client.index(index.uid).setting.getSynonyms(); expect(response).toEqual(newSynonyms); }); @@ -47,18 +50,21 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update synonyms with null value`, async () => { const client = await getClient(permission); const newSynonyms = null; - await client.index(index.uid).updateSynonyms(newSynonyms).waitTask(); + await client + .index(index.uid) + .setting.updateSynonyms(newSynonyms) + .waitTask(); - const response = await client.index(index.uid).getSynonyms(); + const response = await client.index(index.uid).setting.getSynonyms(); expect(response).toEqual({}); }); test(`${permission} key: Reset synonyms`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetSynonyms().waitTask(); + await client.index(index.uid).setting.resetSynonyms().waitTask(); - const response = await client.index(index.uid).getSynonyms(); + const response = await client.index(index.uid).setting.getSynonyms(); expect(response).toEqual({}); }); @@ -75,21 +81,21 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get synonyms and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getSynonyms(), + client.index(index.uid).setting.getSynonyms(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update synonyms and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateSynonyms({}), + client.index(index.uid).setting.updateSynonyms({}), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset synonyms and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetSynonyms(), + client.index(index.uid).setting.resetSynonyms(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -102,7 +108,9 @@ describe.each([{ permission: "No" }])("Test on synonyms", ({ permission }) => { test(`${permission} key: try to get synonyms and be denied`, async () => { const client = await getClient(permission); - await expect(client.index(index.uid).getSynonyms()).rejects.toHaveProperty( + await expect( + client.index(index.uid).setting.getSynonyms(), + ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, ); @@ -111,7 +119,7 @@ describe.each([{ permission: "No" }])("Test on synonyms", ({ permission }) => { test(`${permission} key: try to update synonyms and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateSynonyms({}), + client.index(index.uid).setting.updateSynonyms({}), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -121,7 +129,7 @@ describe.each([{ permission: "No" }])("Test on synonyms", ({ permission }) => { test(`${permission} key: try to reset synonyms and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetSynonyms(), + client.index(index.uid).setting.resetSynonyms(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -138,7 +146,9 @@ describe.each([ const route = `indexes/${index.uid}/settings/synonyms`; const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.index(index.uid).getSynonyms()).rejects.toHaveProperty( + await expect( + client.index(index.uid).setting.getSynonyms(), + ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, ); @@ -149,7 +159,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateSynonyms({}), + client.index(index.uid).setting.updateSynonyms({}), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -161,7 +171,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetSynonyms(), + client.index(index.uid).setting.resetSynonyms(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, diff --git a/tests/token.test.ts b/tests/token.test.ts index 349c95037..e2b25f301 100644 --- a/tests/token.test.ts +++ b/tests/token.test.ts @@ -299,7 +299,7 @@ describe.each([{ permission: "Admin" }])( const masterClient = await getClient("master"); await masterClient .index(UID) - .updateFilterableAttributes(["id"]) + .setting.updateFilterableAttributes(["id"]) .waitTask(); const client = await getClient(permission); const apiKey = await getKey(permission); diff --git a/tests/typed_search.test.ts b/tests/typed_search.test.ts index 5b135528e..89794c561 100644 --- a/tests/typed_search.test.ts +++ b/tests/typed_search.test.ts @@ -118,8 +118,8 @@ describe.each([ const newFilterableAttributes = ["genre", "title"]; await client - .index(index.uid) - .updateFilterableAttributes(newFilterableAttributes) + .index(index.uid) + .setting.updateFilterableAttributes(newFilterableAttributes) .waitTask(); await client.index(index.uid).addDocuments(dataset).waitTask(); diff --git a/tests/typo_tolerance.test.ts b/tests/typo_tolerance.test.ts index 6bc7427c9..6329991a8 100644 --- a/tests/typo_tolerance.test.ts +++ b/tests/typo_tolerance.test.ts @@ -38,7 +38,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Get default typo tolerance settings`, async () => { const client = await getClient(permission); - const response = await client.index(index.uid).getTypoTolerance(); + const response = await client.index(index.uid).setting.getTypoTolerance(); expect(response).toEqual(defaultTypoTolerance); }); @@ -55,28 +55,31 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( }; await client .index(index.uid) - .updateTypoTolerance(newTypoTolerance) + .setting.updateTypoTolerance(newTypoTolerance) .waitTask(); - const response = await client.index(index.uid).getTypoTolerance(); + const response = await client.index(index.uid).setting.getTypoTolerance(); expect(response).toEqual(newTypoTolerance); }); test(`${permission} key: Update typo tolerance using null as value`, async () => { const client = await getClient(permission); - await client.index(index.uid).updateTypoTolerance(null).waitTask(); + await client + .index(index.uid) + .setting.updateTypoTolerance(null) + .waitTask(); - const response = await client.index(index.uid).getTypoTolerance(); + const response = await client.index(index.uid).setting.getTypoTolerance(); expect(response).toEqual(defaultTypoTolerance); }); test(`${permission} key: Reset typo tolerance settings`, async () => { const client = await getClient(permission); - await client.index(index.uid).resetTypoTolerance().waitTask(); + await client.index(index.uid).setting.resetTypoTolerance().waitTask(); - const response = await client.index(index.uid).getTypoTolerance(); + const response = await client.index(index.uid).setting.getTypoTolerance(); expect(response).toEqual(defaultTypoTolerance); }); @@ -93,21 +96,21 @@ describe.each([{ permission: "Search" }])( test(`${permission} key: try to get typo tolerance settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getTypoTolerance(), + client.index(index.uid).setting.getTypoTolerance(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to update typo tolerance settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateTypoTolerance({}), + client.index(index.uid).setting.updateTypoTolerance({}), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); test(`${permission} key: try to reset typo tolerance settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetTypoTolerance(), + client.index(index.uid).setting.resetTypoTolerance(), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); }); }, @@ -123,7 +126,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to get typo tolerance settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).getTypoTolerance(), + client.index(index.uid).setting.getTypoTolerance(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -133,7 +136,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to update typo tolerance settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).updateTypoTolerance({}), + client.index(index.uid).setting.updateTypoTolerance({}), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -143,7 +146,7 @@ describe.each([{ permission: "No" }])( test(`${permission} key: try to reset typo tolerance settings and be denied`, async () => { const client = await getClient(permission); await expect( - client.index(index.uid).resetTypoTolerance(), + client.index(index.uid).setting.resetTypoTolerance(), ).rejects.toHaveProperty( "cause.code", ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, @@ -162,7 +165,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).getTypoTolerance(), + client.index(index.uid).setting.getTypoTolerance(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -174,7 +177,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).updateTypoTolerance({}), + client.index(index.uid).setting.updateTypoTolerance({}), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, @@ -186,7 +189,7 @@ describe.each([ const client = new MeiliSearch({ host }); const strippedHost = trailing ? host.slice(0, -1) : host; await expect( - client.index(index.uid).resetTypoTolerance(), + client.index(index.uid).setting.resetTypoTolerance(), ).rejects.toHaveProperty( "message", `Request to ${strippedHost}/${route} has failed`, From d35cc368a0044247417d7f9f672acf3aca0e4eea Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Fri, 11 Apr 2025 09:13:18 +0300 Subject: [PATCH 07/18] Adjust documentation, fix test --- .code-samples.meilisearch.yaml | 166 ++++++++++++++--------------- README.md | 116 ++++++++++---------- tests/env/node/getting_started.cjs | 2 +- 3 files changed, 142 insertions(+), 142 deletions(-) diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 84676a78c..86cc2639f 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -4,7 +4,7 @@ # You can read more on https://github.com/meilisearch/documentation/tree/master/.vuepress/code-samples --- synonyms_guide_1: |- - client.index('movies').updateSynonyms({ + client.index('movies').setting.updateSynonyms({ 'great': ['fantastic'], 'fantastic': ['great'] }) @@ -12,13 +12,13 @@ date_guide_index_1: |- const games = require('./games.json') client.index('games').addDocuments(games).then((res) => console.log(res)) date_guide_filterable_attributes_1: |- - client.index('games').updateFilterableAttributes(['release_timestamp']) + client.index('games').setting.updateFilterableAttributes(['release_timestamp']) date_guide_filter_1: |- client.index('games').search('', { filter: 'release_timestamp >= 1514761200 AND release_timestamp < 1672527600' }) date_guide_sortable_attributes_1: |- - client.index('games').updateSortableAttributes(['release_timestamp']) + client.index('games').setting.updateSortableAttributes(['release_timestamp']) date_guide_sort_1: |- client.index('games').search('', { sort: ['release_timestamp:desc'], @@ -205,25 +205,25 @@ update_settings_1: |- reset_settings_1: |- client.index('movies').resetSettings() get_synonyms_1: |- - client.index('movies').getSynonyms() + client.index('movies').setting.getSynonyms() update_synonyms_1: |- - client.index('movies').updateSynonyms({ + client.index('movies').setting.updateSynonyms({ wolverine: ['xmen', 'logan'], logan: ['wolverine', 'xmen'], wow: ['world of warcraft'] }) reset_synonyms_1: |- - client.index('movies').resetSynonyms() + client.index('movies').setting.resetSynonyms() get_stop_words_1: |- - client.index('movies').getStopWords() + client.index('movies').setting.getStopWords() update_stop_words_1: |- - client.index('movies').updateStopWords(['of', 'the', 'to']) + client.index('movies').setting.updateStopWords(['of', 'the', 'to']) reset_stop_words_1: |- - client.index('movies').resetStopWords() + client.index('movies').setting.resetStopWords() get_ranking_rules_1: |- - client.index('movies').getRankingRules() + client.index('movies').setting.getRankingRules() update_ranking_rules_1: |- - client.index('movies').updateRankingRules([ + client.index('movies').setting.updateRankingRules([ 'words', 'typo', 'proximity', @@ -234,38 +234,38 @@ update_ranking_rules_1: |- 'rank:desc' ]) reset_ranking_rules_1: |- - client.index('movies').resetRankingRules() + client.index('movies').setting.resetRankingRules() get_distinct_attribute_1: |- - client.index('shoes').getDistinctAttribute() + client.index('shoes').setting.getDistinctAttribute() update_distinct_attribute_1: |- - client.index('shoes').updateDistinctAttribute('skuid') + client.index('shoes').setting.updateDistinctAttribute('skuid') reset_distinct_attribute_1: |- - client.index('shoes').resetDistinctAttribute() + client.index('shoes').setting.resetDistinctAttribute() get_searchable_attributes_1: |- - client.index('movies').getSearchableAttributes() + client.index('movies').setting.getSearchableAttributes() update_searchable_attributes_1: |- - client.index('movies').updateSearchableAttributes([ + client.index('movies').setting.updateSearchableAttributes([ 'title', 'overview', 'genres' ]) reset_searchable_attributes_1: |- - client.index('movies').resetSearchableAttributes() + client.index('movies').setting.resetSearchableAttributes() get_displayed_attributes_1: |- - client.index('movies').getDisplayedAttributes() + client.index('movies').setting.getDisplayedAttributes() update_displayed_attributes_1: |- - client.index('movies').updateDisplayedAttributes([ + client.index('movies').setting.updateDisplayedAttributes([ 'title', 'overview', 'genres', 'release_date' ]) reset_displayed_attributes_1: |- - client.index('movies').resetDisplayedAttributes() + client.index('movies').setting.resetDisplayedAttributes() get_typo_tolerance_1: |- - client.index('books').getTypoTolerance() + client.index('books').setting.getTypoTolerance() update_typo_tolerance_1: |- - client.index('books').updateTypoTolerance({ + client.index('books').setting.updateTypoTolerance({ minWordSizeForTypos: { oneTypo: 4, twoTypos: 10 @@ -275,7 +275,7 @@ update_typo_tolerance_1: |- ] }) reset_typo_tolerance_1: |- - client.index('books').resetTypoTolerance() + client.index('books').setting.resetTypoTolerance() get_index_stats_1: |- client.index('movies').getStats() get_indexes_stats_1: |- @@ -285,16 +285,16 @@ get_health_1: |- get_version_1: |- client.getVersion() distinct_attribute_guide_1: |- - client.index('jackets').updateDistinctAttribute('product_id') + client.index('jackets').setting.updateDistinctAttribute('product_id') field_properties_guide_searchable_1: |- - client.index('movies').updateSearchableAttributes([ + client.index('movies').setting.updateSearchableAttributes([ 'title', 'overview', 'genres', ] ) field_properties_guide_displayed_1: |- - client.index('movies').updateDisplayedAttributes([ + client.index('movies').setting.updateDisplayedAttributes([ 'title', 'overview', 'genres', @@ -380,19 +380,19 @@ search_parameter_guide_attributes_to_search_on_1: |- attributesToSearchOn: ['overview'] }) typo_tolerance_guide_1: |- - client.index('movies').updateTypoTolerance({ + client.index('movies').setting.updateTypoTolerance({ enabled: false }) typo_tolerance_guide_2: |- - client.index('movies').updateTypoTolerance({ + client.index('movies').setting.updateTypoTolerance({ disableOnAttributes: ['title'] }) typo_tolerance_guide_3: |- - client.index('movies').updateTypoTolerance({ + client.index('movies').setting.updateTypoTolerance({ disableOnWords: ['shrek'] }) typo_tolerance_guide_4: |- - client.index('movies').updateTypoTolerance({ + client.index('movies').setting.updateTypoTolerance({ minWordSizeForTypos: { oneTypo: 4, twoTypos: 10 @@ -459,7 +459,7 @@ getting_started_search_md: |- [About this SDK](https://github.com/meilisearch/meilisearch-js/) getting_started_update_ranking_rules: |- - client.index('movies').updateRankingRules([ + client.index('movies').setting.updateRankingRules([ 'exactness', 'words', 'typo', @@ -470,20 +470,20 @@ getting_started_update_ranking_rules: |- 'rank:desc' ]) getting_started_update_searchable_attributes: |- - client.index('movies').updateSearchableAttributes([ + client.index('movies').setting.updateSearchableAttributes([ 'title' ]) getting_started_update_stop_words: |- - client.index('movies').updateStopWords(['the']) + client.index('movies').setting.updateStopWords(['the']) getting_started_check_task_status: |- client.getTask(0) getting_started_synonyms: |- - client.index('movies').updateSynonyms({ + client.index('movies').setting.updateSynonyms({ winnie: ['piglet'], piglet: ['winnie'] }) getting_started_update_displayed_attributes: |- - client.index('movies').updateDisplayedAttributes([ + client.index('movies').setting.updateDisplayedAttributes([ 'title', 'overview', 'poster' @@ -507,14 +507,14 @@ getting_started_sorting: |- filter: 'mass < 200' }) getting_started_faceting: |- - client.index('movies').updateFaceting({ + client.index('movies').setting.updateFaceting({ maxValuesPerFacet: 2, sortFacetValuesBy: { '*': 'count' } }) getting_started_typo_tolerance: |- - client.index('movies').updateTypoTolerance({ + client.index('movies').setting.updateTypoTolerance({ minWordSizeForTypos: { oneTypo: 4 } @@ -522,20 +522,20 @@ getting_started_typo_tolerance: |- getting_started_filtering: |- client.index('meteorites').search('', { filter: 'mass < 200' }) getting_started_pagination: |- - client.index('movies').updatePagination({ maxTotalHits: 500 }) + client.index('movies').setting.updatePagination({ maxTotalHits: 500 }) get_filterable_attributes_1: |- - client.index('movies').getFilterableAttributes() + client.index('movies').setting.getFilterableAttributes() update_filterable_attributes_1: |- client.index('movies') - .updateFilterableAttributes([ + .setting.updateFilterableAttributes([ 'genres', 'director' ]) reset_filterable_attributes_1: |- - client.index('movies').resetFilterableAttributes() + client.index('movies').setting.resetFilterableAttributes() filtering_update_settings_1: |- client.index('movies') - .updateFilterableAttributes([ + .setting.updateFilterableAttributes([ 'director', 'genres' ]) @@ -545,7 +545,7 @@ faceted_search_walkthrough_filter_1: |- filter: [['genres = Horror', 'genres = Mystery'], 'director = "Jordan Peele"'] }) faceted_search_update_settings_1: |- - client.index('movie_ratings').updateFilterableAttributes(['genres', 'rating', 'language']) + client.index('movie_ratings').setting.updateFilterableAttributes(['genres', 'rating', 'language']) faceted_search_1: |- client.index('books').search('classic', { facets: ['genres', 'rating', 'language'] }) post_dump_1: |- @@ -556,12 +556,12 @@ phrase_search_1: |- client.index('movies') .search('"african american" horror') sorting_guide_update_sortable_attributes_1: |- - client.index('books').updateSortableAttributes([ + client.index('books').setting.updateSortableAttributes([ 'author', 'price' ]) sorting_guide_update_ranking_rules_1: |- - client.index('books').updateRankingRules([ + client.index('books').setting.updateRankingRules([ 'words', 'sort', 'typo', @@ -582,25 +582,25 @@ sorting_guide_sort_nested_1: |- 'sort': ['rating.users:asc'], }) get_sortable_attributes_1: |- - client.index('books').getSortableAttributes() + client.index('books').setting.getSortableAttributes() update_sortable_attributes_1: |- client.index('books') - .updateSortableAttributes([ + .setting.updateSortableAttributes([ 'price', 'author' ]) reset_sortable_attributes_1: |- - client.index('books').resetSortableAttributes() + client.index('books').setting.resetSortableAttributes() get_pagination_settings_1: |- - client.index('books').getPagination() + client.index('books').setting.getPagination() update_pagination_settings_1: |- client.index('books').updateSettings({ pagination: { maxTotalHits: 100 }}) reset_pagination_settings_1: |- - client.index('books').resetPagination() + client.index('books').setting.resetPagination() get_faceting_settings_1: |- - client.index('books').getFaceting() + client.index('books').setting.getFaceting() update_faceting_settings_1: |- - client.index('books').updateFaceting({ + client.index('books').setting.updateFaceting({ maxValuesPerFacet: 2 sortFacetValuesBy: { '*': 'alpha', @@ -608,46 +608,46 @@ update_faceting_settings_1: |- } }) reset_faceting_settings_1: |- - client.index('books').resetFaceting() + client.index('books').setting.resetFaceting() get_dictionary_1: |- - client.index('books').getDictionary() + client.index('books').setting.getDictionary() update_dictionary_1: |- - client.index('books').updateDictionary(['J. R. R.', 'W. E. B.']) + client.index('books').setting.updateDictionary(['J. R. R.', 'W. E. B.']) reset_dictionary_1: |- - client.index('books').resetDictionary() + client.index('books').setting.resetDictionary() search_parameter_guide_sort_1: |- client.index('books').search('science fiction', { sort: ['price:asc'], }) get_separator_tokens_1: |- - client.index('books').getSeparatorTokens() + client.index('books').setting.getSeparatorTokens() update_separator_tokens_1: |- - client.index('books').updateSeparatorTokens(['|', '…']) + client.index('books').setting.updateSeparatorTokens(['|', '…']) reset_separator_tokens_1: |- - client.index('books').resetSeparatorTokens() + client.index('books').setting.resetSeparatorTokens() get_non_separator_tokens_1: |- - client.index('books').getNonSeparatorTokens() + client.index('books').setting.getNonSeparatorTokens() update_non_separator_tokens_1: |- - client.index('books').updateNonSeparatorTokens(['@', '#']) + client.index('books').setting.updateNonSeparatorTokens(['@', '#']) reset_non_separator_tokens_1: |- - client.index('books').resetNonSeparatorTokens() + client.index('books').setting.resetNonSeparatorTokens() get_proximity_precision_settings_1: |- - client.index('books').getProximityPrecision() + client.index('books').setting.getProximityPrecision() update_proximity_precision_settings_1: |- - client.index('books').updateProximityPrecision('byAttribute') + client.index('books').setting.updateProximityPrecision('byAttribute') reset_proximity_precision_settings_1: |- - client.index('books').resetProximityPrecision() + client.index('books').setting.resetProximityPrecision() get_search_cutoff_1: |- - client.index('movies').getSearchCutoffMs() + client.index('movies').setting.getSearchCutoffMs() update_search_cutoff_1: |- - client.index('movies').updateSearchCutoffMs(150) + client.index('movies').setting.updateSearchCutoffMs(150) reset_search_cutoff_1: |- - client.index('movies').resetSearchCutoffMs() + client.index('movies').setting.resetSearchCutoffMs() search_parameter_guide_facet_stats_1: |- client.index('movie_ratings').search('Batman', { facets: ['genres', 'rating'] }) geosearch_guide_filter_settings_1: |- client.index('restaurants') - .updateFilterableAttributes([ + .setting.updateFilterableAttributes([ '_geo' ]) geosearch_guide_filter_usage_1: |- @@ -663,7 +663,7 @@ geosearch_guide_filter_usage_3: |- filter: ['_geoBoundingBox([45.494181, 9.214024], [45.449484, 9.179175])'], }) geosearch_guide_sort_settings_1: |- - client.index('restaurants').updateSortableAttributes([ + client.index('restaurants').setting.updateSortableAttributes([ '_geo' ]) geosearch_guide_sort_usage_1: |- @@ -737,7 +737,7 @@ facet_search_1: |- filter: 'rating > 3' }) facet_search_2: |- - client.index('books').updateFaceting({ + client.index('books').setting.updateFaceting({ sortFacetValuesBy: { genres: 'count' } @@ -778,7 +778,7 @@ search_parameter_guide_matching_strategy_3: |- search_parameter_reference_distinct_1: |- client.index('INDEX_NAME').search('QUERY TERMS', { distinct: 'ATTRIBUTE_A' }) distinct_attribute_guide_filterable_1: |- - client.index('products').updateFilterableAttributes(['product_id', 'sku', 'url']) + client.index('products').setting.updateFilterableAttributes(['product_id', 'sku', 'url']) distinct_attribute_guide_distinct_parameter_1: |- client.index('products').search('white shirt', { distinct: 'sku' }) multi_search_federated_1: |- @@ -798,32 +798,32 @@ multi_search_federated_1: |- search_parameter_reference_locales_1: |- client.index('INDEX_NAME').search('QUERY TEXT IN JAPANESE', { locales: ['jpn'] }) get_localized_attribute_settings_1: |- - client.index('INDEX_NAME').getLocalizedAttributes() + client.index('INDEX_NAME').setting.getLocalizedAttributes() update_localized_attribute_settings_1: |- - client.index('INDEX_NAME').updateLocalizedAttributes([ + client.index('INDEX_NAME').setting.updateLocalizedAttributes([ { attributePatterns: ['*_ja'], locales: ['jpn'] }, ]) reset_localized_attribute_settings_1: |- - client.index('INDEX_NAME').resetLocalizedAttributes() + client.index('INDEX_NAME').setting.resetLocalizedAttributes() get_facet_search_settings_1: |- - client.index('INDEX_NAME').getFacetSearch(); + client.index('INDEX_NAME').setting.getFacetSearch(); update_facet_search_settings_1: |- - client.index('INDEX_NAME').updateFacetSearch(false); + client.index('INDEX_NAME').setting.updateFacetSearch(false); reset_facet_search_settings_1: |- - client.index('INDEX_NAME').resetFacetSearch(); + client.index('INDEX_NAME').setting.resetFacetSearch(); get_prefix_search_settings_1: |- - client.index('INDEX_NAME').getPrefixSearch(); + client.index('INDEX_NAME').setting.getPrefixSearch(); update_prefix_search_settings_1: |- - client.index('INDEX_NAME').updatePrefixSearch('disabled'); + client.index('INDEX_NAME').setting.updatePrefixSearch('disabled'); reset_prefix_search_settings_1: |- - client.index('INDEX_NAME').resetPrefixSearch(); + client.index('INDEX_NAME').setting.resetPrefixSearch(); get_all_batches_1: |- client.getBatches(); get_batch_1: |- client.getBatch(BATCH_UID); # Vector search update_embedders_1: |- - client.index('INDEX_NAME').updateEmbedders({ + client.index('INDEX_NAME').setting.updateEmbedders({ default: { source: 'openAi', apiKey: 'OPEN_AI_API_KEY', diff --git a/README.md b/README.md index 3d5e3441f..6e0fbe4f3 100644 --- a/README.md +++ b/README.md @@ -262,7 +262,7 @@ await index.search( To enable filtering, you must first add your attributes to the [`filterableAttributes` index setting](https://www.meilisearch.com/docs/reference/api/settings#filterable-attributes). ```js -await index.updateFilterableAttributes([ +await index.setting.updateFilterableAttributes([ 'id', 'genres' ]) @@ -710,19 +710,19 @@ client.index('myIndex').resetSettings(): Promise #### [Get pagination](https://www.meilisearch.com/docs/reference/api/settings#get-pagination-settings) ```ts -client.index('myIndex').getPagination(): Promise +client.index('myIndex').setting.getPagination(): Promise ``` #### [Update pagination](https://www.meilisearch.com/docs/reference/api/settings#update-pagination-settings) ```ts -client.index('myIndex').updatePagination(pagination: PaginationSettings): Promise +client.index('myIndex').setting.updatePagination(pagination: PaginationSettings): Promise ``` #### [Reset pagination](https://www.meilisearch.com/docs/reference/api/settings#reset-pagination-settings) ```ts -client.index('myIndex').resetPagination(): Promise +client.index('myIndex').setting.resetPagination(): Promise ``` ### Synonyms @@ -730,19 +730,19 @@ client.index('myIndex').resetPagination(): Promise #### [Get synonyms](https://www.meilisearch.com/docs/reference/api/settings#get-synonyms) ```ts -client.index('myIndex').getSynonyms(): Promise +client.index('myIndex').setting.getSynonyms(): Promise ``` #### [Update synonyms](https://www.meilisearch.com/docs/reference/api/settings#update-synonyms) ```ts -client.index('myIndex').updateSynonyms(synonyms: Synonyms): Promise +client.index('myIndex').setting.updateSynonyms(synonyms: Synonyms): Promise ``` #### [Reset synonyms](https://www.meilisearch.com/docs/reference/api/settings#reset-synonyms) ```ts -client.index('myIndex').resetSynonyms(): Promise +client.index('myIndex').setting.resetSynonyms(): Promise ``` ### Stop words @@ -750,19 +750,19 @@ client.index('myIndex').resetSynonyms(): Promise #### [Get stop words](https://www.meilisearch.com/docs/reference/api/settings#get-stop-words) ```ts -client.index('myIndex').getStopWords(): Promise +client.index('myIndex').setting.getStopWords(): Promise ``` #### [Update stop words](https://www.meilisearch.com/docs/reference/api/settings#update-stop-words) ```ts -client.index('myIndex').updateStopWords(stopWords: string[] | null ): Promise +client.index('myIndex').setting.updateStopWords(stopWords: string[] | null ): Promise ``` #### [Reset stop words](https://www.meilisearch.com/docs/reference/api/settings#reset-stop-words) ```ts -client.index('myIndex').resetStopWords(): Promise +client.index('myIndex').setting.resetStopWords(): Promise ``` ### Ranking rules @@ -770,19 +770,19 @@ client.index('myIndex').resetStopWords(): Promise #### [Get ranking rules](https://www.meilisearch.com/docs/reference/api/settings#get-ranking-rules) ```ts -client.index('myIndex').getRankingRules(): Promise +client.index('myIndex').setting.getRankingRules(): Promise ``` #### [Update ranking rules](https://www.meilisearch.com/docs/reference/api/settings#update-ranking-rules) ```ts -client.index('myIndex').updateRankingRules(rankingRules: string[] | null): Promise +client.index('myIndex').setting.updateRankingRules(rankingRules: string[] | null): Promise ``` #### [Reset ranking rules](https://www.meilisearch.com/docs/reference/api/settings#reset-ranking-rules) ```ts -client.index('myIndex').resetRankingRules(): Promise +client.index('myIndex').setting.resetRankingRules(): Promise ``` ### Distinct Attribute @@ -790,19 +790,19 @@ client.index('myIndex').resetRankingRules(): Promise #### [Get distinct attribute](https://www.meilisearch.com/docs/reference/api/settings#get-distinct-attribute) ```ts -client.index('myIndex').getDistinctAttribute(): Promise +client.index('myIndex').setting.getDistinctAttribute(): Promise ``` #### [Update distinct attribute](https://www.meilisearch.com/docs/reference/api/settings#update-distinct-attribute) ```ts -client.index('myIndex').updateDistinctAttribute(distinctAttribute: string | null): Promise +client.index('myIndex').setting.updateDistinctAttribute(distinctAttribute: string | null): Promise ``` #### [Reset distinct attribute](https://www.meilisearch.com/docs/reference/api/settings#reset-distinct-attribute) ```ts -client.index('myIndex').resetDistinctAttribute(): Promise +client.index('myIndex').setting.resetDistinctAttribute(): Promise ``` ### Searchable attributes @@ -810,19 +810,19 @@ client.index('myIndex').resetDistinctAttribute(): Promise #### [Get searchable attributes](https://www.meilisearch.com/docs/reference/api/settings#get-searchable-attributes) ```ts -client.index('myIndex').getSearchableAttributes(): Promise +client.index('myIndex').setting.getSearchableAttributes(): Promise ``` #### [Update searchable attributes](https://www.meilisearch.com/docs/reference/api/settings#update-searchable-attributes) ```ts -client.index('myIndex').updateSearchableAttributes(searchableAttributes: string[] | null): Promise +client.index('myIndex').setting.updateSearchableAttributes(searchableAttributes: string[] | null): Promise ``` #### [Reset searchable attributes](https://www.meilisearch.com/docs/reference/api/settings#reset-searchable-attributes) ```ts -client.index('myIndex').resetSearchableAttributes(): Promise +client.index('myIndex').setting.resetSearchableAttributes(): Promise ``` ### Displayed attributes @@ -830,19 +830,19 @@ client.index('myIndex').resetSearchableAttributes(): Promise #### [Get displayed attributes](https://www.meilisearch.com/docs/reference/api/settings#get-displayed-attributes) ```ts -client.index('myIndex').getDisplayedAttributes(): Promise +client.index('myIndex').setting.getDisplayedAttributes(): Promise ``` #### [Update displayed attributes](https://www.meilisearch.com/docs/reference/api/settings#update-displayed-attributes) ```ts -client.index('myIndex').updateDisplayedAttributes(displayedAttributes: string[] | null): Promise +client.index('myIndex').setting.updateDisplayedAttributes(displayedAttributes: string[] | null): Promise ``` #### [Reset displayed attributes](https://www.meilisearch.com/docs/reference/api/settings#reset-displayed-attributes) ```ts -client.index('myIndex').resetDisplayedAttributes(): Promise +client.index('myIndex').setting.resetDisplayedAttributes(): Promise ``` ### Filterable attributes @@ -850,19 +850,19 @@ client.index('myIndex').resetDisplayedAttributes(): Promise #### [Get filterable attributes](https://www.meilisearch.com/docs/reference/api/settings#get-filterable-attributes) ```ts -client.index('myIndex').getFilterableAttributes(): Promise +client.index('myIndex').setting.getFilterableAttributes(): Promise ``` #### [Update filterable attributes](https://www.meilisearch.com/docs/reference/api/settings#update-filterable-attributes) ```ts -client.index('myIndex').updateFilterableAttributes(filterableAttributes: string[] | null): Promise +client.index('myIndex').setting.updateFilterableAttributes(filterableAttributes: string[] | null): Promise ``` #### [Reset filterable attributes](https://www.meilisearch.com/docs/reference/api/settings#reset-filterable-attributes) ```ts -client.index('myIndex').resetFilterableAttributes(): Promise +client.index('myIndex').setting.resetFilterableAttributes(): Promise ``` ### Sortable attributes @@ -870,19 +870,19 @@ client.index('myIndex').resetFilterableAttributes(): Promise #### [Get sortable attributes](https://www.meilisearch.com/docs/reference/api/settings#get-sortable-attributes) ```ts -client.index('myIndex').getSortableAttributes(): Promise +client.index('myIndex').setting.getSortableAttributes(): Promise ``` #### [Update sortable attributes](https://www.meilisearch.com/docs/reference/api/settings#update-sortable-attributes) ```ts -client.index('myIndex').updateSortableAttributes(sortableAttributes: string[] | null): Promise +client.index('myIndex').setting.updateSortableAttributes(sortableAttributes: string[] | null): Promise ``` #### [Reset sortable attributes](https://www.meilisearch.com/docs/reference/api/settings#reset-sortable-attributes) ```ts -client.index('myIndex').resetSortableAttributes(): Promise +client.index('myIndex').setting.resetSortableAttributes(): Promise ``` ### Faceting @@ -890,19 +890,19 @@ client.index('myIndex').resetSortableAttributes(): Promise #### [Get faceting](https://www.meilisearch.com/docs/reference/api/settings#get-faceting-settings) ```ts -client.index('myIndex').getFaceting(): Promise +client.index('myIndex').setting.getFaceting(): Promise ``` #### [Update faceting](https://www.meilisearch.com/docs/reference/api/settings#update-faceting-settings) ```ts -client.index('myIndex').updateFaceting(faceting: Faceting): Promise +client.index('myIndex').setting.updateFaceting(faceting: Faceting): Promise ``` #### [Reset faceting](https://www.meilisearch.com/docs/reference/api/settings#reset-faceting-settings) ```ts -client.index('myIndex').resetFaceting(): Promise +client.index('myIndex').setting.resetFaceting(): Promise ``` ### Typo tolerance @@ -910,19 +910,19 @@ client.index('myIndex').resetFaceting(): Promise #### [Get typo tolerance](https://www.meilisearch.com/docs/reference/api/settings#get-typo-tolerance-settings) ```ts -client.index('myIndex').getTypoTolerance(): Promise +client.index('myIndex').setting.getTypoTolerance(): Promise ``` #### [Update typo tolerance](https://www.meilisearch.com/docs/reference/api/settings#update-typo-tolerance-settings) ```ts -client.index('myIndex').updateTypoTolerance(typoTolerance: TypoTolerance | null): Promise +client.index('myIndex').setting.updateTypoTolerance(typoTolerance: TypoTolerance | null): Promise ``` #### [Reset typo tolerance](https://www.meilisearch.com/docs/reference/api/settings#reset-typo-tolerance-settings) ```ts -client.index('myIndex').resetTypoTolerance(): Promise +client.index('myIndex').setting.resetTypoTolerance(): Promise ``` @@ -931,19 +931,19 @@ client.index('myIndex').resetTypoTolerance(): Promise #### [Get separator tokens](https://www.meilisearch.com/docs/reference/api/settings#get-separator-tokens) ```ts -client.index('myIndex').getSeparatorTokens(): Promise +client.index('myIndex').setting.getSeparatorTokens(): Promise ``` #### [Update separator tokens](https://www.meilisearch.com/docs/reference/api/settings#update-separator-tokens) ```ts -client.index('myIndex').updateSeparatorTokens(separatorTokens: SeparatorTokens | null): Promise +client.index('myIndex').setting.updateSeparatorTokens(separatorTokens: SeparatorTokens | null): Promise ``` #### [Reset separator tokens](https://www.meilisearch.com/docs/reference/api/settings#reset-separator-tokens) ```ts -client.index('myIndex').resetSeparatorTokens(): Promise +client.index('myIndex').setting.resetSeparatorTokens(): Promise ``` ### Non Separator tokens @@ -951,19 +951,19 @@ client.index('myIndex').resetSeparatorTokens(): Promise #### [Get non separator tokens](https://www.meilisearch.com/docs/reference/api/settings#get-non-separator-tokens) ```ts -client.index('myIndex').getNonSeparatorTokens(): Promise +client.index('myIndex').setting.getNonSeparatorTokens(): Promise ``` #### [Update non separator tokens](https://www.meilisearch.com/docs/reference/api/settings#update-non-separator-tokens) ```ts -client.index('myIndex').updateNonSeparatorTokens(nonSeparatorTokens: NonSeparatorTokens | null): Promise +client.index('myIndex').setting.updateNonSeparatorTokens(nonSeparatorTokens: NonSeparatorTokens | null): Promise ``` #### [Reset non separator tokens](https://www.meilisearch.com/docs/reference/api/settings#reset-non-separator-tokens) ```ts -client.index('myIndex').resetNonSeparatorTokens(): Promise +client.index('myIndex').setting.resetNonSeparatorTokens(): Promise ``` ### Dictionary @@ -971,19 +971,19 @@ client.index('myIndex').resetNonSeparatorTokens(): Promise #### [Get dictionary](https://www.meilisearch.com/docs/reference/api/settings#get-dictionary) ```ts -client.index('myIndex').getDictionary(): Promise +client.index('myIndex').setting.getDictionary(): Promise ``` #### [Update dictionary](https://www.meilisearch.com/docs/reference/api/settings#update-dictionary) ```ts -client.index('myIndex').updateDictionary(dictionary: Dictionary | null): Promise +client.index('myIndex').setting.updateDictionary(dictionary: Dictionary | null): Promise ``` #### [Reset dictionary](https://www.meilisearch.com/docs/reference/api/settings#reset-dictionary) ```ts -client.index('myIndex').resetDictionary(): Promise +client.index('myIndex').setting.resetDictionary(): Promise ``` ### Proximity Precision @@ -991,19 +991,19 @@ client.index('myIndex').resetDictionary(): Promise #### [Get proximity precision](https://www.meilisearch.com/docs/reference/api/settings#get-proximity-precision-settings) ```ts -client.index('myIndex').getProximityPrecision(): Promise +client.index('myIndex').setting.getProximityPrecision(): Promise ``` #### [Update proximity precision](https://www.meilisearch.com/docs/reference/api/settings#update-proximity-precision-settings) ```ts -client.index('myIndex').updateProximityPrecision(proximityPrecision: ProximityPrecision): Promise +client.index('myIndex').setting.updateProximityPrecision(proximityPrecision: ProximityPrecision): Promise ``` #### [Reset proximity precision](https://www.meilisearch.com/docs/reference/api/settings#reset-proximity-precision-settings) ```ts -client.index('myIndex').resetProximityPrecision(): Promise +client.index('myIndex').setting.resetProximityPrecision(): Promise ``` ### Facet search settings @@ -1011,19 +1011,19 @@ client.index('myIndex').resetProximityPrecision(): Promise #### [Get facet search settings](https://www.meilisearch.com/docs/reference/api/settings#get-facet-search-settings) ```ts -client.index('myIndex').getFacetSearch(): Promise +client.index('myIndex').setting.getFacetSearch(): Promise ``` #### [Update facet search settings](https://www.meilisearch.com/docs/reference/api/settings#update-facet-search-settings) ```ts -client.index('myIndex').updateFacetSearch(enabled: boolean): Promise +client.index('myIndex').setting.updateFacetSearch(enabled: boolean): Promise ``` #### [Reset facet search settings](https://www.meilisearch.com/docs/reference/api/settings#reset-facet-search-settings) ```ts -client.index('myIndex').resetFacetSearch(): Promise +client.index('myIndex').setting.resetFacetSearch(): Promise ``` ### Prefix search settings @@ -1031,19 +1031,19 @@ client.index('myIndex').resetFacetSearch(): Promise #### [Get prefix search settings](https://www.meilisearch.com/docs/reference/api/settings#get-prefix-search-settings) ```ts -client.index('myIndex').getPrefixSearch(): Promise +client.index('myIndex').setting.getPrefixSearch(): Promise ``` #### [Update prefix search settings](https://www.meilisearch.com/docs/reference/api/settings#update-prefix-search-settings) ```ts -client.index('myIndex').updatePrefixSearch(prefixSearch: PrefixSearch): Promise +client.index('myIndex').setting.updatePrefixSearch(prefixSearch: PrefixSearch): Promise ``` #### [Reset prefix search settings](https://www.meilisearch.com/docs/reference/api/settings#reset-prefix-search-settings) ```ts -client.index('myIndex').resetPrefixSearch(): Promise +client.index('myIndex').setting.resetPrefixSearch(): Promise ``` ### Embedders @@ -1051,19 +1051,19 @@ client.index('myIndex').resetPrefixSearch(): Promise #### Get embedders ```ts -client.index('myIndex').getEmbedders(): Promise +client.index('myIndex').setting.getEmbedders(): Promise ``` #### Update embedders ```ts -client.index('myIndex').updateEmbedders(embedders: Embedders): Promise +client.index('myIndex').setting.updateEmbedders(embedders: Embedders): Promise ``` #### Reset embedders ```ts -client.index('myIndex').resetEmbedders(): Promise +client.index('myIndex').setting.resetEmbedders(): Promise ``` ### SearchCutoffMs @@ -1071,19 +1071,19 @@ client.index('myIndex').resetEmbedders(): Promise #### [Get SearchCutoffMs](https://www.meilisearch.com/docs/reference/api/settings#get-search-cutoff) ```ts -client.index('myIndex').getSearchCutoffMs(): Promise +client.index('myIndex').setting.getSearchCutoffMs(): Promise ``` #### [Update SearchCutoffMs](https://www.meilisearch.com/docs/reference/api/settings#update-search-cutoff) ```ts -client.index('myIndex').updateSearchCutoffMs(searchCutoffMs: SearchCutoffMs): Promise +client.index('myIndex').setting.updateSearchCutoffMs(searchCutoffMs: SearchCutoffMs): Promise ``` #### [Reset SearchCutoffMs](https://www.meilisearch.com/docs/reference/api/settings#reset-search-cutoff) ```ts -client.index('myIndex').resetSearchCutoffMs(): Promise +client.index('myIndex').setting.resetSearchCutoffMs(): Promise ``` ### Keys diff --git a/tests/env/node/getting_started.cjs b/tests/env/node/getting_started.cjs index f16d357c6..43fbf90ce 100644 --- a/tests/env/node/getting_started.cjs +++ b/tests/env/node/getting_started.cjs @@ -19,7 +19,7 @@ const { MeiliSearch } = require('../../../dist/cjs/index.cjs') ] // If the index 'movies' does not exist, MeiliSearch creates it when you first add the documents. - await index.updateFilterableAttributes([ + await index.setting.updateFilterableAttributes([ 'director', 'genres', 'id' From 65fb90e3c6334819e927a90009bbb3d6794dff22 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Fri, 11 Apr 2025 09:41:15 +0300 Subject: [PATCH 08/18] Documentation --- src/indexes.ts | 7 ++++++- src/settings.ts | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/indexes.ts b/src/indexes.ts index 2bff802cc..130ea70d6 100644 --- a/src/indexes.ts +++ b/src/indexes.ts @@ -571,8 +571,13 @@ export class Index { }); } - // TODO: Doc readonly #setting: SettingFns; + + /** + * Contains the get, update and reset functions for every individual setting. + * + * @see {@link https://www.meilisearch.com/docs/reference/api/settings} + */ get setting() { return this.#setting; } diff --git a/src/settings.ts b/src/settings.ts index 8349ab27d..534fed988 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -6,11 +6,12 @@ import type { RecordAny, } from "./types/index.js"; -/** Each setting mapped to their REST method required for updates. */ +/** Each setting property mapped to their REST method required for updates. */ type MakeSettingsRecord = { [TKey in keyof IndividualUpdatableSettings]: "put" | "patch"; }; +/** Each setting property mapped to its get, update and reset functions. */ export type SettingFns = { [TKey in keyof IndividualUpdatableSettings as `get${Capitalize}`]: () => Promise< IndividualUpdatableSettings[TKey] @@ -31,7 +32,7 @@ function camelToKebabCase(str: string): string { return str.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`); } -// TODO: Doc +/** Returns an object containing all the setting functions. */ export function makeSettingFns( httpRequest: HttpRequests, httpRequestsWithTask: HttpRequestsWithEnqueuedTaskPromise, From a8b99d1e907a11cf55e31a3641ef9c55e92e53ac Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Thu, 24 Apr 2025 16:06:30 +0300 Subject: [PATCH 09/18] Progress --- src/settings.ts | 18 +- src/types/settings.ts | 2 +- src/types/task_and_batch.ts | 4 +- tests/__snapshots__/settings.test.ts.snap | 1383 --------------------- tests/embedders.test.ts | 18 +- tests/filterable_attributes.test.ts | 7 +- tests/localized_attributes.test.ts | 11 +- tests/search_cutoff_ms.test.ts | 7 +- tests/settings.test.ts | 932 +++++++++----- tests/utils/meilisearch-test-utils.ts | 11 +- 10 files changed, 634 insertions(+), 1759 deletions(-) delete mode 100644 tests/__snapshots__/settings.test.ts.snap diff --git a/src/settings.ts b/src/settings.ts index 534fed988..841c119ec 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -2,26 +2,26 @@ import type { HttpRequests } from "./http-requests.js"; import type { HttpRequestsWithEnqueuedTaskPromise } from "./task.js"; import type { EnqueuedTaskPromise, - IndividualUpdatableSettings, + SingleUpdatableSettings, RecordAny, } from "./types/index.js"; /** Each setting property mapped to their REST method required for updates. */ type MakeSettingsRecord = { - [TKey in keyof IndividualUpdatableSettings]: "put" | "patch"; + [TKey in keyof SingleUpdatableSettings]: "put" | "patch"; }; /** Each setting property mapped to its get, update and reset functions. */ export type SettingFns = { - [TKey in keyof IndividualUpdatableSettings as `get${Capitalize}`]: () => Promise< - IndividualUpdatableSettings[TKey] + [TKey in keyof SingleUpdatableSettings as `get${Capitalize}`]: () => Promise< + SingleUpdatableSettings[TKey] >; } & { - [TKey in keyof IndividualUpdatableSettings as `update${Capitalize}`]: ( - body: IndividualUpdatableSettings[TKey], + [TKey in keyof SingleUpdatableSettings as `update${Capitalize}`]: ( + body: SingleUpdatableSettings[TKey], ) => EnqueuedTaskPromise; } & { - [TKey in keyof IndividualUpdatableSettings as `reset${Capitalize}`]: () => EnqueuedTaskPromise; + [TKey in keyof SingleUpdatableSettings as `reset${Capitalize}`]: () => EnqueuedTaskPromise; }; function capitalize(str: string): string { @@ -46,13 +46,13 @@ export function makeSettingFns( const path = `${basePath}/${camelToKebabCase(name)}`; settingFns[`get${uppercaseName}`] = async function (): Promise< - IndividualUpdatableSettings[keyof typeof opts] + SingleUpdatableSettings[keyof typeof opts] > { return await httpRequest.get({ path }); }; settingFns[`update${uppercaseName}`] = function ( - body: IndividualUpdatableSettings[keyof typeof opts], + body: SingleUpdatableSettings[keyof typeof opts], ): EnqueuedTaskPromise { return httpRequestsWithTask[method]({ path, body }); }; diff --git a/src/types/settings.ts b/src/types/settings.ts index a1c6fbacf..7959dfcda 100644 --- a/src/types/settings.ts +++ b/src/types/settings.ts @@ -214,7 +214,7 @@ export type UpdatableSettings = PartialAndNullable<{ * A version of {@link UpdatableSettings}, the first layer of properties of which * is used to update or get individual settings. */ -export type IndividualUpdatableSettings = Required; +export type SingleUpdatableSettings = Required; /** * {@link https://www.meilisearch.com/docs/reference/api/settings#body} diff --git a/src/types/task_and_batch.ts b/src/types/task_and_batch.ts index 56d0d4ecb..8efed6b7f 100644 --- a/src/types/task_and_batch.ts +++ b/src/types/task_and_batch.ts @@ -1,4 +1,4 @@ -import type { Settings } from "./settings.js"; +import type { UpdatableSettings } from "./settings.js"; import type { CursorResults } from "./shared.js"; import type { MeiliSearchErrorResponse } from "./types.js"; @@ -97,7 +97,7 @@ export type TaskUidOrEnqueuedTask = EnqueuedTask["taskUid"] | EnqueuedTask; export type IndexSwap = { indexes: [string, string] }; /** {@link https://www.meilisearch.com/docs/reference/api/tasks#details} */ -export type TaskDetails = Settings & { +export type TaskDetails = UpdatableSettings & { receivedDocuments?: number; indexedDocuments?: number; editedDocuments?: number; diff --git a/tests/__snapshots__/settings.test.ts.snap b/tests/__snapshots__/settings.test.ts.snap deleted file mode 100644 index f755b2549..000000000 --- a/tests/__snapshots__/settings.test.ts.snap +++ /dev/null @@ -1,1383 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`Test on settings > Admin key: Get default settings of an index 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Admin key: Get default settings of empty index with primary key 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Admin key: Reset embedders settings 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Admin key: Reset settings 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Admin key: Reset settings of empty index 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Admin key: Update embedders settings 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": { - "default": { - "documentTemplate": "{% for field in fields %}{% if field.is_searchable and field.value != nil %}{{ field.name }}: {{ field.value }} -{% endif %}{% endfor %}", - "documentTemplateMaxBytes": 400, - "model": "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", - "pooling": "useModel", - "source": "huggingFace", - }, - }, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Admin key: Update facetSearch settings on empty index 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": false, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Admin key: Update prefixSearch settings on an empty index 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "disabled", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Admin key: Update searchableAttributes settings on empty index 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "title", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Admin key: Update searchableAttributes settings on empty index with a primary key 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "title", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Admin key: Update settings 1`] = ` -{ - "dictionary": [ - "J. K.", - "J. R. R.", - ], - "displayedAttributes": [ - "title", - ], - "distinctAttribute": "title", - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 50, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [ - "title", - ], - "localizedAttributes": null, - "nonSeparatorTokens": [ - "&sep", - "/", - "|", - ], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byAttribute", - "rankingRules": [ - "id:asc", - "typo", - ], - "searchCutoffMs": 1000, - "searchableAttributes": [ - "title", - ], - "separatorTokens": [ - "&sep", - "/", - "|", - ], - "sortableAttributes": [ - "title", - ], - "stopWords": [ - "the", - ], - "synonyms": { - "harry": [ - "potter", - ], - }, - "typoTolerance": { - "disableOnAttributes": [ - "comment", - ], - "disableOnWords": [ - "prince", - ], - "enabled": false, - "minWordSizeForTypos": { - "oneTypo": 1, - "twoTypos": 100, - }, - }, -} -`; - -exports[`Test on settings > Admin key: Update settings on empty index with primary key 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": "title", - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "title:asc", - "typo", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [ - "the", - ], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Admin key: Update settings with all null values 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Master key: Get default settings of an index 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Master key: Get default settings of empty index with primary key 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Master key: Reset embedders settings 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Master key: Reset settings 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Master key: Reset settings of empty index 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Master key: Update embedders settings 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": { - "default": { - "documentTemplate": "{% for field in fields %}{% if field.is_searchable and field.value != nil %}{{ field.name }}: {{ field.value }} -{% endif %}{% endfor %}", - "documentTemplateMaxBytes": 400, - "model": "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", - "pooling": "useModel", - "source": "huggingFace", - }, - }, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Master key: Update facetSearch settings on empty index 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": false, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Master key: Update prefixSearch settings on an empty index 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "disabled", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Master key: Update searchableAttributes settings on empty index 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "title", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Master key: Update searchableAttributes settings on empty index with a primary key 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "title", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Master key: Update settings 1`] = ` -{ - "dictionary": [ - "J. K.", - "J. R. R.", - ], - "displayedAttributes": [ - "title", - ], - "distinctAttribute": "title", - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 50, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [ - "title", - ], - "localizedAttributes": null, - "nonSeparatorTokens": [ - "&sep", - "/", - "|", - ], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byAttribute", - "rankingRules": [ - "id:asc", - "typo", - ], - "searchCutoffMs": 1000, - "searchableAttributes": [ - "title", - ], - "separatorTokens": [ - "&sep", - "/", - "|", - ], - "sortableAttributes": [ - "title", - ], - "stopWords": [ - "the", - ], - "synonyms": { - "harry": [ - "potter", - ], - }, - "typoTolerance": { - "disableOnAttributes": [ - "comment", - ], - "disableOnWords": [ - "prince", - ], - "enabled": false, - "minWordSizeForTypos": { - "oneTypo": 1, - "twoTypos": 100, - }, - }, -} -`; - -exports[`Test on settings > Master key: Update settings on empty index with primary key 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": "title", - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "title:asc", - "typo", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [ - "the", - ], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; - -exports[`Test on settings > Master key: Update settings with all null values 1`] = ` -{ - "dictionary": [], - "displayedAttributes": [ - "*", - ], - "distinctAttribute": null, - "embedders": {}, - "facetSearch": true, - "faceting": { - "maxValuesPerFacet": 100, - "sortFacetValuesBy": { - "*": "alpha", - }, - }, - "filterableAttributes": [], - "localizedAttributes": null, - "nonSeparatorTokens": [], - "pagination": { - "maxTotalHits": 1000, - }, - "prefixSearch": "indexingTime", - "proximityPrecision": "byWord", - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", - ], - "searchCutoffMs": null, - "searchableAttributes": [ - "*", - ], - "separatorTokens": [], - "sortableAttributes": [], - "stopWords": [], - "synonyms": {}, - "typoTolerance": { - "disableOnAttributes": [], - "disableOnWords": [], - "enabled": true, - "minWordSizeForTypos": { - "oneTypo": 5, - "twoTypos": 9, - }, - }, -} -`; diff --git a/tests/embedders.test.ts b/tests/embedders.test.ts index e0d4b3a91..f7ec3053b 100644 --- a/tests/embedders.test.ts +++ b/tests/embedders.test.ts @@ -1,5 +1,5 @@ import { afterAll, expect, test, describe, beforeEach } from "vitest"; -import type { IndividualUpdatableSettings } from "../src/index.js"; +import type { SingleUpdatableSettings } from "../src/index.js"; import { clearAllIndexes, config, @@ -70,7 +70,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with 'userProvided' source`, async () => { const client = await getClient(permission); - const newEmbedder: IndividualUpdatableSettings["embedders"] = { + const newEmbedder: SingleUpdatableSettings["embedders"] = { default: { source: "userProvided", dimensions: 1, @@ -94,7 +94,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with 'openAi' source`, async () => { const client = await getClient(permission); - const newEmbedder: IndividualUpdatableSettings["embedders"] = { + const newEmbedder: SingleUpdatableSettings["embedders"] = { default: { source: "openAi", apiKey: "", @@ -128,7 +128,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with 'huggingFace' source`, async () => { const client = await getClient(permission); - const newEmbedder: IndividualUpdatableSettings["embedders"] = { + const newEmbedder: SingleUpdatableSettings["embedders"] = { default: { source: "huggingFace", model: "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", @@ -155,7 +155,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with 'rest' source`, async () => { const client = await getClient(permission); - const newEmbedder: IndividualUpdatableSettings["embedders"] = { + const newEmbedder: SingleUpdatableSettings["embedders"] = { default: { source: "rest", url: "https://api.openai.com/v1/embeddings", @@ -203,7 +203,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with 'ollama' source`, async () => { const client = await getClient(permission); - const newEmbedder: IndividualUpdatableSettings["embedders"] = { + const newEmbedder: SingleUpdatableSettings["embedders"] = { default: { source: "ollama", url: "http://localhost:11434/api/embeddings", @@ -237,7 +237,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update embedders with a specific name`, async () => { const client = await getClient(permission); - const newEmbedder: IndividualUpdatableSettings["embedders"] = { + const newEmbedder: SingleUpdatableSettings["embedders"] = { image: { source: "userProvided", dimensions: 512, @@ -267,7 +267,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( }); const client = await getClient(permission); - const embedders: IndividualUpdatableSettings["embedders"] = { + const embedders: SingleUpdatableSettings["embedders"] = { default: { source: "composite", searchEmbedder: { @@ -366,7 +366,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: search for similar documents`, async () => { const client = await getClient(permission); - const newEmbedder: IndividualUpdatableSettings["embedders"] = { + const newEmbedder: SingleUpdatableSettings["embedders"] = { manual: { source: "userProvided", dimensions: 3, diff --git a/tests/filterable_attributes.test.ts b/tests/filterable_attributes.test.ts index 07040e58e..c2ad29c55 100644 --- a/tests/filterable_attributes.test.ts +++ b/tests/filterable_attributes.test.ts @@ -1,8 +1,5 @@ import { expect, test, describe, beforeEach, afterAll } from "vitest"; -import { - ErrorStatusCode, - type IndividualUpdatableSettings, -} from "../src/index.js"; +import { ErrorStatusCode, type SingleUpdatableSettings } from "../src/index.js"; import { clearAllIndexes, config, @@ -67,7 +64,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update attributes with granular attribute syntax`, async () => { const client = await getClient(permission); - const newFilterableAttributes: IndividualUpdatableSettings["filterableAttributes"] = + const newFilterableAttributes: SingleUpdatableSettings["filterableAttributes"] = [ "author", { diff --git a/tests/localized_attributes.test.ts b/tests/localized_attributes.test.ts index 2c325fbd0..ffd3245f3 100644 --- a/tests/localized_attributes.test.ts +++ b/tests/localized_attributes.test.ts @@ -6,10 +6,7 @@ import { expect, test, } from "vitest"; -import { - ErrorStatusCode, - type IndividualUpdatableSettings, -} from "../src/index.js"; +import { ErrorStatusCode, type SingleUpdatableSettings } from "../src/index.js"; import { clearAllIndexes, config, @@ -49,7 +46,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update localizedAttributes to valid value`, async () => { const client = await getClient(permission); - const newLocalizedAttributes: IndividualUpdatableSettings["localizedAttributes"] = + const newLocalizedAttributes: SingleUpdatableSettings["localizedAttributes"] = [{ attributePatterns: ["title"], locales: ["eng"] }]; await client .index(index.uid) @@ -81,7 +78,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update localizedAttributes with invalid value`, async () => { const client = await getClient(permission); const newLocalizedAttributes = - "hello" as unknown as IndividualUpdatableSettings["localizedAttributes"]; // bad localizedAttributes value + "hello" as unknown as SingleUpdatableSettings["localizedAttributes"]; // bad localizedAttributes value await expect( client @@ -95,7 +92,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Reset localizedAttributes`, async () => { const client = await getClient(permission); - const newLocalizedAttributes: IndividualUpdatableSettings["localizedAttributes"] = + const newLocalizedAttributes: SingleUpdatableSettings["localizedAttributes"] = []; await client .index(index.uid) diff --git a/tests/search_cutoff_ms.test.ts b/tests/search_cutoff_ms.test.ts index 4098cb681..45792a57a 100644 --- a/tests/search_cutoff_ms.test.ts +++ b/tests/search_cutoff_ms.test.ts @@ -6,10 +6,7 @@ import { expect, test, } from "vitest"; -import { - ErrorStatusCode, - type IndividualUpdatableSettings, -} from "../src/index.js"; +import { ErrorStatusCode, type SingleUpdatableSettings } from "../src/index.js"; import { clearAllIndexes, config, @@ -80,7 +77,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Update searchCutoffMs with invalid value`, async () => { const client = await getClient(permission); const newSearchCutoffMs = - "hello" as unknown as IndividualUpdatableSettings["searchCutoffMs"]; // bad searchCutoffMs value + "hello" as unknown as SingleUpdatableSettings["searchCutoffMs"]; // bad searchCutoffMs value await expect( client.index(index.uid).setting.updateSearchCutoffMs(newSearchCutoffMs), diff --git a/tests/settings.test.ts b/tests/settings.test.ts index 06a06d37e..a841f30d3 100644 --- a/tests/settings.test.ts +++ b/tests/settings.test.ts @@ -1,359 +1,617 @@ -import { afterAll, beforeEach, describe, expect, test } from "vitest"; -import { ErrorStatusCode, type UpdatableSettings } from "../src/index.js"; +import { test, describe, afterAll } from "vitest"; +import type { + EnqueuedTaskPromise, + FacetValuesSort, + SingleUpdatableSettings, + PrefixSearchSettings, + ProximityPrecisionView, + RankingRuleView, + EmbedderSource, + UpdatableSettings, +} from "../src/index.js"; import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, + assert, getClient, - dataset, + ObjectKeys, } from "./utils/meilisearch-test-utils.js"; -const index = { - uid: "movies_test", -}; -const indexAndPK = { - uid: "movies_test_with_pk", - primaryKey: "id", +const INDEX_UID = "e16993ea-0cd2-4a29-9365-b99778a92c74"; +const ms = await getClient("Master"); +const index = ms.index(INDEX_UID); + +type InputAndAssertion = { + input: SingleUpdatableSettings[T]; + assertion: ( + input: SingleUpdatableSettings[T], + output: SingleUpdatableSettings[T], + ) => void; }; -afterAll(() => { - return clearAllIndexes(config); -}); +type MappedSettings = { + [TKey in keyof SingleUpdatableSettings]: [ + text: string | undefined, + inputAndAssertion: InputAndAssertion, + ][]; +}; -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on settings", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("Master"); - await client - .index(indexAndPK.uid) - .addDocuments(dataset, { - primaryKey: indexAndPK.primaryKey, - }) - .waitTask(); - - await client.index(index.uid).addDocuments(dataset, {}).waitTask(); - }); - - test(`${permission} key: Get default settings of an index`, async () => { - const client = await getClient(permission); - - const response = await client.index(index.uid).getSettings(); - - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Get default settings of empty index with primary key`, async () => { - const client = await getClient(permission); - - const response = await client.index(indexAndPK.uid).getSettings(); - - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Update settings`, async () => { - const client = await getClient(permission); - const newSettings: UpdatableSettings = { - filterableAttributes: ["title"], - sortableAttributes: ["title"], - distinctAttribute: "title", - proximityPrecision: "byAttribute", - searchableAttributes: ["title"], - displayedAttributes: ["title"], - rankingRules: ["id:asc", "typo"], - stopWords: ["the"], - synonyms: { harry: ["potter"] }, - typoTolerance: { - enabled: false, - minWordSizeForTypos: { - oneTypo: 1, - twoTypos: 100, - }, - disableOnWords: ["prince"], - disableOnAttributes: ["comment"], +const mappedSettings = { + displayedAttributes: [ + [ + undefined, + { + input: ["uno", "dos"], + assertion: (input, output) => { + assert.isNotNull(input); + assert.isNotNull(output); + assert.sameMembers(input, output); }, - pagination: { - maxTotalHits: 1000, + }, + ], + ], + + searchableAttributes: [ + [ + undefined, + { + input: ["tres", "cuatro"], + assertion: (input, output) => { + assert.isNotNull(input); + assert.isNotNull(output); + assert.sameMembers(input, output); }, - faceting: { - maxValuesPerFacet: 50, - sortFacetValuesBy: { - "*": "alpha", + }, + ], + ], + + filterableAttributes: [ + [ + undefined, + { + input: [ + // pattern + "genre", + // granular + { + attributePatterns: ["modèleUn", "modèleDeux"], + features: { + facetSearch: true, + filter: { equality: true, comparison: true }, + }, }, + ], + assertion: (input, output) => { + assert.isNotNull(input); + assert.isNotNull(output); + assert.sameDeepMembers(input, output); }, - separatorTokens: ["&sep", "/", "|"], - nonSeparatorTokens: ["&sep", "/", "|"], - dictionary: ["J. K.", "J. R. R."], - searchCutoffMs: 1000, - facetSearch: true, - prefixSearch: "indexingTime", - }; - // Add the settings - await client.index(index.uid).updateSettings(newSettings).waitTask(); - - // Fetch the settings - const response = await client.index(index.uid).getSettings(); - - // tests - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Update settings with all null values`, async () => { - const client = await getClient(permission); - const newSettings: UpdatableSettings = { - filterableAttributes: null, - sortableAttributes: null, - distinctAttribute: null, - searchableAttributes: null, - displayedAttributes: null, - rankingRules: null, - stopWords: null, - synonyms: null, - typoTolerance: { - enabled: null, - minWordSizeForTypos: { - oneTypo: null, - twoTypos: null, - }, - disableOnWords: null, - disableOnAttributes: null, + }, + ], + ], + + sortableAttributes: [ + [ + undefined, + { + input: ["cinco", "seis"], + assertion: (input, output) => { + assert.isNotNull(input); + assert.isNotNull(output); + assert.sameMembers(input, output); }, - faceting: { - maxValuesPerFacet: null, - sortFacetValuesBy: null, + }, + ], + ], + + rankingRules: [ + [ + undefined, + { + input: ObjectKeys({ + words: null, + typo: null, + proximity: null, + attribute: null, + sort: null, + exactness: null, + "some_field:asc": null, + "some_other_field:desc": null, + }), + assertion: (input, output) => { + assert.isNotNull(input); + assert.isNotNull(output); + assert.sameMembers(input, output); }, - pagination: { - maxTotalHits: null, + }, + ], + ], + + stopWords: [ + [ + undefined, + { + input: ["siete", "ocho"], + assertion: (input, output) => { + assert.isNotNull(input); + assert.isNotNull(output); + assert.sameMembers(input, output); }, - separatorTokens: null, - nonSeparatorTokens: null, - dictionary: null, - searchCutoffMs: null, - }; - // Add the settings - await client.index(index.uid).updateSettings(newSettings).waitTask(); - - // Fetch the settings - const response = await client.index(index.uid).getSettings(); - - // tests - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Update embedders settings `, async () => { - const client = await getClient(permission); - - const newSettings: UpdatableSettings = { - embedders: { - default: { - source: "huggingFace", - model: - "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", - }, + }, + ], + ], + + nonSeparatorTokens: [ + [ + undefined, + { + input: ["nueve", "diez"], + assertion: (input, output) => { + assert.isNotNull(input); + assert.isNotNull(output); + assert.sameMembers(input, output); }, - }; - await client - .index(index.uid) - .updateSettings(newSettings) - .waitTask({ timeout: 60_000 }); - const response = await client.index(index.uid).getSettings(); - - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Update settings on empty index with primary key`, async () => { - const client = await getClient(permission); - const newSettings: UpdatableSettings = { - distinctAttribute: "title", - rankingRules: ["title:asc", "typo"], - stopWords: ["the"], - }; - await client.index(indexAndPK.uid).updateSettings(newSettings).waitTask(); - - const response = await client.index(indexAndPK.uid).getSettings(); - - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Reset settings`, async () => { - const client = await getClient(permission); - await client.index(index.uid).resetSettings().waitTask(); - - const response = await client.index(index.uid).getSettings(); - - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Reset settings of empty index`, async () => { - const client = await getClient(permission); - await client.index(indexAndPK.uid).resetSettings().waitTask(); - - const response = await client.index(indexAndPK.uid).getSettings(); - - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Reset embedders settings `, async () => { - const client = await getClient(permission); - - const newSettings: UpdatableSettings = { - embedders: null, - }; - await client.index(index.uid).updateSettings(newSettings).waitTask(); - const response = await client.index(index.uid).getSettings(); - - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Update searchableAttributes settings on empty index`, async () => { - const client = await getClient(permission); - const newSettings = { - searchableAttributes: ["title"], - }; - await client.index(index.uid).updateSettings(newSettings).waitTask(); - - const response = await client.index(index.uid).getSettings(); - - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Update searchableAttributes settings on empty index with a primary key`, async () => { - const client = await getClient(permission); - const newSettings = { - searchableAttributes: ["title"], - }; - // Update settings - await client.index(indexAndPK.uid).updateSettings(newSettings).waitTask(); - // Wait for setting addition to be done - - // Fetch settings - const response = await client.index(indexAndPK.uid).getSettings(); - - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Update facetSearch settings on empty index`, async () => { - const client = await getClient(permission); - - await client - .index(index.uid) - .updateSettings({ facetSearch: false }) - .waitTask(); - - const response = await client.index(index.uid).getSettings(); - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Update prefixSearch settings on an empty index`, async () => { - const client = await getClient(permission); - - await client - .index(index.uid) - .updateSettings({ prefixSearch: "disabled" }) - .waitTask(); - - const response = await client.index(index.uid).getSettings(); - expect(response).toMatchSnapshot(); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on settings", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - }); - test(`${permission} key: try to get settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).getSettings(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - test(`${permission} key: try to update settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).updateSettings({}), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - test(`${permission} key: try to reset settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).resetSettings(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])("Test on settings", ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - }); - test(`${permission} key: try to get settings and be denied`, async () => { - const client = await getClient(permission); - await expect(client.index(index.uid).getSettings()).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - test(`${permission} key: try to update settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).updateSettings({}), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - test(`${permission} key: try to reset settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).resetSettings(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); + }, + ], + ], + + separatorTokens: [ + [ + undefined, + { + input: ["once", "doce"], + assertion: (input, output) => { + assert.isNotNull(input); + assert.isNotNull(output); + assert.sameMembers(input, output); + }, + }, + ], + ], + + dictionary: [ + [ + undefined, + { + input: ["suge", "bucle"], + assertion: (input, output) => { + assert.isNotNull(input); + assert.isNotNull(output); + assert.sameMembers(input, output); + }, + }, + ], + ], + + synonyms: [ + [ + undefined, + { + input: { + language: ["speech", "tongue", "lingo"], + land: ["country", "nation", "state"], + }, + assertion: (input, output) => { + assert.deepEqual(input, output); + }, + }, + ], + ], + + distinctAttribute: [ + [ + undefined, + { + input: "trece", + assertion: (input, output) => { + assert.strictEqual(input, output); + }, + }, + ], + ], + + proximityPrecision: ObjectKeys({ + byWord: null, + byAttribute: null, + }).map((v) => [ + v, + { + input: v, + assertion: (input, output) => { + assert.strictEqual(input, output); + }, + }, + ]), + + typoTolerance: [ + [ + undefined, + { + input: { + enabled: true, + minWordSizeForTypos: { oneTypo: 2, twoTypos: 3 }, + disableOnWords: ["mot-un", "mot-deux"], + disableOnAttributes: ["attributUn", "attributDeux"], + }, + assertion: (input, output) => { + assert.isNotNull(input); + assert.isNotNull(output); + + const { + disableOnWords: dow1, + disableOnAttributes: doa1, + ...restInput + } = input; + const { + disableOnWords: dow2, + disableOnAttributes: doa2, + ...restOutput + } = output; + + assert(dow1 != null); + assert(dow2 != null); + assert(doa1 != null); + assert(doa2 != null); + + assert.sameMembers(dow1, dow2); + assert.sameMembers(doa1, doa2); + + assert.deepEqual(restInput, restOutput); + }, + }, + ], + ], + + faceting: ObjectKeys({ + alpha: null, + count: null, + }).map((v) => [ + `${v} facet value sort`, + { + input: { maxValuesPerFacet: 42, sortFacetValuesBy: { random_field: v } }, + assertion: (input, output) => { + assert.isNotNull(input); + assert.isNotNull(output); + + assert(output.sortFacetValuesBy != null); + const star = output.sortFacetValuesBy["*"]; + delete output.sortFacetValuesBy["*"]; + assert.oneOf(star, ["alpha", undefined]); + + assert.deepEqual(input, output); + }, + }, + ]), + + pagination: [ + [ + undefined, + { + input: { maxTotalHits: 42 }, + assertion: (input, output) => { + assert.deepEqual(input, output); + }, + }, + ], + ], + + embedders: ObjectKeys({ + openAi: null, + huggingFace: null, + ollama: null, + userProvided: null, + rest: null, + composite: null, + }).map((source) => { + return [ + source, + (() => { + switch (source) { + case "openAi": + return { + input: { + default: { + source, + apiKey: "", + model: "text-embedding-3-small", + documentTemplate: + "A movie titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}", + dimensions: 1536, + distribution: { + mean: 0.7, + sigma: 0.3, + }, + url: "https://api.openai.com/v1/embeddings", + documentTemplateMaxBytes: 500, + binaryQuantized: false, + }, + }, + assertion: (input, output) => { + assert.deepEqual(input, output); + }, + }; + case "huggingFace": + return { + input: { + default: { + source, + model: + "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", + documentTemplate: + "A movie titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}", + distribution: { + mean: 0.7, + sigma: 0.3, + }, + pooling: "useModel", + documentTemplateMaxBytes: 500, + binaryQuantized: false, + }, + }, + assertion: (input, output) => { + assert.deepEqual(input, output); + }, + }; + case "ollama": + return { + input: { + default: { + source, + url: "http://localhost:11434/api/embeddings", + apiKey: "", + model: "nomic-embed-text", + documentTemplate: "blabla", + distribution: { + mean: 0.7, + sigma: 0.3, + }, + dimensions: 512, + documentTemplateMaxBytes: 500, + binaryQuantized: false, + }, + }, + assertion: (input, output) => { + assert.deepEqual(input, output); + }, + }; + case "userProvided": + return { + input: { + default: { + source, + dimensions: 1, + distribution: { + mean: 0.7, + sigma: 0.3, + }, + binaryQuantized: false, + }, + }, + assertion: (input, output) => { + assert.deepEqual(input, output); + }, + }; + case "rest": + return { + input: { + default: { + source, + url: "https://api.openai.com/v1/embeddings", + apiKey: "", + dimensions: 1536, + documentTemplate: + "A movie titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}", + distribution: { + mean: 0.7, + sigma: 0.3, + }, + request: { + model: "text-embedding-3-small", + input: ["{{text}}", "{{..}}"], + }, + response: { + data: [ + { + embedding: "{{embedding}}", + }, + "{{..}}", + ], + }, + headers: { + "Custom-Header": "CustomValue", + }, + documentTemplateMaxBytes: 500, + binaryQuantized: false, + }, + }, + assertion: (input, output) => { + assert.deepEqual(input, output); + }, + }; + case "composite": + return { + input: { + default: { + source, + searchEmbedder: { + source: "huggingFace", + model: + "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", + pooling: "useModel", + }, + indexingEmbedder: { + source: "huggingFace", + model: + "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", + documentTemplate: "{{doc.title}}", + pooling: "useModel", + documentTemplateMaxBytes: 500, + }, + }, + }, + assertion: (input, output) => { + assert.deepEqual(input, output); + }, + }; + default: + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + assert.fail(`untested source ${source}`); + } + })(), + ]; + }), + + searchCutoffMs: [ + [ + undefined, + { + input: 100, + assertion: (input, output) => { + assert.strictEqual(input, output); + }, + }, + ], + ], + + localizedAttributes: [ + [ + undefined, + { + input: [{ attributePatterns: ["title"], locales: ["eng"] }], + assertion: (input, output) => { + assert.deepEqual(input, output); + }, + }, + ], + ], + + facetSearch: [ + [ + undefined, + { + input: true, + assertion: (input, output) => { + assert.strictEqual(input, output); + }, + }, + ], + ], + + prefixSearch: ObjectKeys({ + indexingTime: null, + disabled: null, + }).map((v) => [ + v, + { + input: v, + assertion: (input, output) => { + assert.strictEqual(input, output); + }, + }, + ]), +} satisfies MappedSettings as Record< + string, + [ + text: string | undefined, + inputAndAssertion: InputAndAssertion, + ][] +>; + +afterAll(async () => { + const task = await index.delete().waitTask(); + assert.isTaskSuccessful(task); }); -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getSettings route`, async () => { - const route = `indexes/${index.uid}/settings`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.index(index.uid).getSettings()).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); +describe.for(Object.entries(mappedSettings))("%s", ([key, mappedSetting]) => { + const castKey = key as keyof MappedSettings; + const capitalizedKey = (castKey.charAt(0).toUpperCase() + + key.slice(1)) as Capitalize; + + // Union of functions results in intersection of their parameters + // https://github.com/microsoft/TypeScript/issues/30581 + + const getSetting = index.setting[`get${capitalizedKey}`].bind( + index, + ) as () => Promise; + + const updateSetting = index.setting[`update${capitalizedKey}`].bind( + index, + ) as ( + v: SingleUpdatableSettings[keyof SingleUpdatableSettings], + ) => EnqueuedTaskPromise; + + const resetSetting = index.setting[`reset${capitalizedKey}`].bind(index); + + mappedSetting = mappedSetting.map(([a, b]) => [ + a === undefined ? "" : ` with ${a}`, + b, + ]); + + test.for(mappedSetting)( + "single update and get methods%s", + async ([, { input, assertion }]) => { + const task = await updateSetting(input).waitTask(); + assert.isTaskSuccessful(task); + + const taskSetting = task.details?.[castKey]; + assert.isDefined(taskSetting); + assertion(input, taskSetting); + + const setting = await getSetting(); + assertion(input, setting); + }, + ); + + test("single reset method", async () => { + const task = await resetSetting().waitTask(); + assert.includeDeepMembers([null, ["*"]], [task.details?.[castKey]]); + assert.isTaskSuccessful(task); }); - test(`updateSettings route`, async () => { - const route = `indexes/${index.uid}/settings`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).updateSettings({}), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); + test.for(mappedSetting)( + `${index.updateSettings.name} and ${index.getSettings.name} methods%s`, + async ([, { input, assertion }]) => { + const task = await index.updateSettings({ [castKey]: input }).waitTask(); + assert.isTaskSuccessful(task); + + const taskSetting = task.details?.[castKey]; + assert.isDefined(taskSetting); + assertion(input, taskSetting); + + const settings = await index.getSettings(); + assert.isDefined(settings[castKey]); + assertion(input, settings[castKey]); + }, + ); + + test(`reset with ${index.updateSettings.name} method`, async () => { + const task = await index.updateSettings({ [castKey]: null }).waitTask(); + assert.includeDeepMembers([null, ["*"]], [task.details?.[castKey]]); + assert.isTaskSuccessful(task); }); +}); - test(`resetSettings route`, async () => { - const route = `indexes/${index.uid}/settings`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).resetSettings(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); +test(`${index.resetSettings.name} method`, async () => { + const task = await index.resetSettings().waitTask(); + assert.isTaskSuccessful(task); + assert.deepEqual(task.details, { + dictionary: null, + displayedAttributes: ["*"], + distinctAttribute: null, + embedders: null, + facetSearch: null, + faceting: null, + filterableAttributes: null, + localizedAttributes: null, + nonSeparatorTokens: null, + pagination: null, + prefixSearch: null, + proximityPrecision: null, + rankingRules: null, + searchCutoffMs: null, + searchableAttributes: ["*"], + separatorTokens: null, + sortableAttributes: null, + stopWords: null, + synonyms: null, + typoTolerance: null, + } satisfies Required); }); diff --git a/tests/utils/meilisearch-test-utils.ts b/tests/utils/meilisearch-test-utils.ts index e9faf9510..e7f8d7460 100644 --- a/tests/utils/meilisearch-test-utils.ts +++ b/tests/utils/meilisearch-test-utils.ts @@ -1,6 +1,6 @@ import { assert as vitestAssert } from "vitest"; import { MeiliSearch, Index } from "../../src/index.js"; -import type { Config } from "../../src/types/index.js"; +import type { Config, Task } from "../../src/types/index.js"; // testing const MASTER_KEY = "masterKey"; @@ -127,6 +127,10 @@ const source = { "expected value to not resolve", ); }, + isTaskSuccessful(task: Task) { + vitestAssert.isNull(task.error); + vitestAssert.strictEqual(task.status, "succeeded"); + }, }; export const assert: typeof vitestAssert & typeof source = Object.assign( vitestAssert, @@ -244,7 +248,12 @@ export type Book = { author: string; }; +function ObjectKeys(o: { [TKey in T]: null }): T[] { + return Object.keys(o) as T[]; +} + export { + ObjectKeys, clearAllIndexes, config, masterClient, From f6dbc992828b7ff360f375d8214573a45e313004 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Thu, 24 Apr 2025 23:39:22 +0300 Subject: [PATCH 10/18] Refactor settings tests --- src/meilisearch.ts | 22 ++ src/types/experimental-features.ts | 14 + src/types/index.ts | 1 + tests/dictionary.test.ts | 111 ------- tests/displayed_attributes.test.ts | 198 ------------ tests/distinct_attribute.test.ts | 189 ------------ tests/embedders.test.ts | 439 --------------------------- tests/facet_search_settings.test.ts | 171 ----------- tests/faceting.test.ts | 202 ------------ tests/filterable_attributes.test.ts | 216 ------------- tests/localized_attributes.test.ts | 226 -------------- tests/non_separator_tokens.test.ts | 122 -------- tests/pagination.test.ts | 202 ------------ tests/prefix_search_settings.test.ts | 174 ----------- tests/proximity_precision.test.ts | 122 -------- tests/ranking_rules.test.ts | 190 ------------ tests/search_cutoff_ms.test.ts | 219 ------------- tests/searchable_attributes.test.ts | 201 ------------ tests/separator_tokens.test.ts | 119 -------- tests/settings.test.ts | 157 ++++------ tests/sortable_attributes.test.ts | 203 ------------- tests/stop_words.test.ts | 181 ----------- tests/synonyms.test.ts | 180 ----------- tests/typo_tolerance.test.ts | 198 ------------ 24 files changed, 97 insertions(+), 3960 deletions(-) create mode 100644 src/types/experimental-features.ts delete mode 100644 tests/dictionary.test.ts delete mode 100644 tests/displayed_attributes.test.ts delete mode 100644 tests/distinct_attribute.test.ts delete mode 100644 tests/embedders.test.ts delete mode 100644 tests/facet_search_settings.test.ts delete mode 100644 tests/faceting.test.ts delete mode 100644 tests/filterable_attributes.test.ts delete mode 100644 tests/localized_attributes.test.ts delete mode 100644 tests/non_separator_tokens.test.ts delete mode 100644 tests/pagination.test.ts delete mode 100644 tests/prefix_search_settings.test.ts delete mode 100644 tests/proximity_precision.test.ts delete mode 100644 tests/ranking_rules.test.ts delete mode 100644 tests/search_cutoff_ms.test.ts delete mode 100644 tests/searchable_attributes.test.ts delete mode 100644 tests/separator_tokens.test.ts delete mode 100644 tests/sortable_attributes.test.ts delete mode 100644 tests/stop_words.test.ts delete mode 100644 tests/synonyms.test.ts delete mode 100644 tests/typo_tolerance.test.ts diff --git a/src/meilisearch.ts b/src/meilisearch.ts index 25f1c4e8d..018e02a0f 100644 --- a/src/meilisearch.ts +++ b/src/meilisearch.ts @@ -28,6 +28,7 @@ import type { ExtraRequestInit, Network, RecordAny, + RuntimeTogglableFeatures, } from "./types/index.js"; import { ErrorStatusCode } from "./types/index.js"; import { HttpRequests } from "./http-requests.js"; @@ -454,4 +455,25 @@ export class MeiliSearch { path: "snapshots", }); } + + /// + /// EXPERIMENTAL-FEATURES + /// + + /** {@link https://www.meilisearch.com/docs/reference/api/experimental_features#get-all-experimental-features} */ + async getExperimentalFeatures(): Promise { + return await this.httpRequest.get({ + path: "experimental-features", + }); + } + + /** {@link https://www.meilisearch.com/docs/reference/api/experimental_features#configure-experimental-features} */ + async updateExperimentalFeatures( + runtimeTogglableFeatures: RuntimeTogglableFeatures, + ): Promise { + return await this.httpRequest.patch({ + path: "experimental-features", + body: runtimeTogglableFeatures, + }); + } } diff --git a/src/types/experimental-features.ts b/src/types/experimental-features.ts new file mode 100644 index 000000000..c81720d16 --- /dev/null +++ b/src/types/experimental-features.ts @@ -0,0 +1,14 @@ +/** + * {@link https://www.meilisearch.com/docs/reference/api/experimental_features#experimental-features-object} + * + * @see `meilisearch::routes::features::RuntimeTogglableFeatures` + */ +export type RuntimeTogglableFeatures = { + metrics?: boolean | null; + logsRoute?: boolean | null; + editDocumentsByFunction?: boolean | null; + containsFilter?: boolean | null; + network?: boolean | null; + getTaskDocumentsRoute?: boolean | null; + compositeEmbedders?: boolean | null; +}; diff --git a/src/types/index.ts b/src/types/index.ts index 8cdc810f9..8b0d1a3e7 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,3 +1,4 @@ +export * from "./experimental-features.js"; export * from "./settings.js"; export * from "./task_and_batch.js"; export * from "./token.js"; diff --git a/tests/dictionary.test.ts b/tests/dictionary.test.ts deleted file mode 100644 index aa0e6f927..000000000 --- a/tests/dictionary.test.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { afterAll, expect, test, describe, beforeEach } from "vitest"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on dictionary", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default dictionary`, async () => { - const client = await getClient(permission); - const response = await client.index(index.uid).setting.getDictionary(); - - expect(response).toEqual([]); - }); - - test(`${permission} key: Update dictionary`, async () => { - const client = await getClient(permission); - const newDictionary = ["J. K.", "J. R. R."]; - await client - .index(index.uid) - .setting.updateDictionary(newDictionary) - .waitTask(); - - const response = await client.index(index.uid).setting.getDictionary(); - - expect(response).toEqual(newDictionary); - }); - - test(`${permission} key: Update dictionary with null value`, async () => { - const client = await getClient(permission); - const newDictionary = null; - await client - .index(index.uid) - .setting.updateDictionary(newDictionary) - .waitTask(); - - const response = await client.index(index.uid).setting.getDictionary(); - - expect(response).toEqual([]); - }); - - test(`${permission} key: Reset dictionary`, async () => { - const client = await getClient(permission); - await client.index(index.uid).setting.resetDictionary().waitTask(); - - const response = await client.index(index.uid).setting.getDictionary(); - - expect(response).toEqual([]); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getDictionary route`, async () => { - const route = `indexes/${index.uid}/settings/dictionary`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getDictionary(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateDictionary route`, async () => { - const route = `indexes/${index.uid}/settings/dictionary`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateDictionary([]), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetDictionary route`, async () => { - const route = `indexes/${index.uid}/settings/dictionary`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetDictionary(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/displayed_attributes.test.ts b/tests/displayed_attributes.test.ts deleted file mode 100644 index 6e2847474..000000000 --- a/tests/displayed_attributes.test.ts +++ /dev/null @@ -1,198 +0,0 @@ -import { afterAll, expect, test, describe, beforeEach } from "vitest"; -import { ErrorStatusCode } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on displayed attributes", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("Master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default displayed attributes`, async () => { - const client = await getClient(permission); - - const response = await client - .index(index.uid) - .setting.getDisplayedAttributes(); - expect(response).toEqual(["*"]); - }); - - test(`${permission} key: Update displayed attributes`, async () => { - const client = await getClient(permission); - const newDisplayedAttribute = ["title"]; - await client - .index(index.uid) - .setting.updateDisplayedAttributes(newDisplayedAttribute) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getDisplayedAttributes(); - - expect(response).toEqual(newDisplayedAttribute); - }); - - test(`${permission} key: Update displayed attributes at null`, async () => { - const client = await getClient(permission); - - await client - .index(index.uid) - .setting.updateDisplayedAttributes(null) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getDisplayedAttributes(); - - expect(response).toEqual(["*"]); - }); - - test(`${permission} key: Reset displayed attributes`, async () => { - const client = await getClient(permission); - - await client - .index(index.uid) - .setting.resetDisplayedAttributes() - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getDisplayedAttributes(); - - expect(response).toEqual(["*"]); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on displayed attributes", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get displayed attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getDisplayedAttributes(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update displayed attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateDisplayedAttributes([]), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset displayed attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetDisplayedAttributes(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])( - "Test on displayed attributes", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get displayed attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getDisplayedAttributes(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update displayed attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateDisplayedAttributes([]), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset displayed attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetDisplayedAttributes(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getDisplayedAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/displayed-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getDisplayedAttributes(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateDisplayedAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/displayed-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateDisplayedAttributes([]), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetDisplayedAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/displayed-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetDisplayedAttributes(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/distinct_attribute.test.ts b/tests/distinct_attribute.test.ts deleted file mode 100644 index 11db3d43d..000000000 --- a/tests/distinct_attribute.test.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { afterAll, expect, test, describe, beforeEach } from "vitest"; -import { ErrorStatusCode } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on distinct attribute", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("master"); - - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default distinct attribute`, async () => { - const client = await getClient(permission); - const response = await client - .index(index.uid) - .setting.getDistinctAttribute(); - expect(response).toEqual(null); - }); - - test(`${permission} key: Update distinct attribute`, async () => { - const client = await getClient(permission); - const newDistinctAttribute = "title"; - await client - .index(index.uid) - .setting.updateDistinctAttribute(newDistinctAttribute) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getDistinctAttribute(); - - expect(response).toEqual(newDistinctAttribute); - }); - - test(`${permission} key: Update distinct attribute at undefined`, async () => { - const client = await getClient(permission); - await client - .index(index.uid) - .setting.updateDistinctAttribute(null) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getDistinctAttribute(); - - expect(response).toEqual(null); - }); - - test(`${permission} key: Reset distinct attribute`, async () => { - const client = await getClient(permission); - await client.index(index.uid).setting.resetDistinctAttribute().waitTask(); - - const response = await client - .index(index.uid) - .setting.getDistinctAttribute(); - - expect(response).toEqual(null); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on distinct attribute", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - }); - - test(`${permission} key: try to get distinct attribute and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getDistinctAttribute(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update distinct attribute and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateDistinctAttribute("title"), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset distinct attribute and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetDistinctAttribute(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])( - "Test on distinct attribute", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - }); - - test(`${permission} key: try to get distinct attribute and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getDistinctAttribute(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update distinct attribute and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateDistinctAttribute("title"), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset distinct attribute and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetDistinctAttribute(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getDistinctAttribute route`, async () => { - const route = `indexes/${index.uid}/settings/distinct-attribute`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getDistinctAttribute(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateDistinctAttribute route`, async () => { - const route = `indexes/${index.uid}/settings/distinct-attribute`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateDistinctAttribute("a"), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetDistinctAttribute route`, async () => { - const route = `indexes/${index.uid}/settings/distinct-attribute`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetDistinctAttribute(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/embedders.test.ts b/tests/embedders.test.ts deleted file mode 100644 index f7ec3053b..000000000 --- a/tests/embedders.test.ts +++ /dev/null @@ -1,439 +0,0 @@ -import { afterAll, expect, test, describe, beforeEach } from "vitest"; -import type { SingleUpdatableSettings } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - getKey, - HOST, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -const datasetSimilarSearch = [ - { - title: "Shazam!", - release_year: 2019, - id: "287947", - _vectors: { manual: [0.8, 0.4, -0.5] }, - }, - { - title: "Captain Marvel", - release_year: 2019, - id: "299537", - _vectors: { manual: [0.6, 0.8, -0.2] }, - }, - { - title: "Escape Room", - release_year: 2019, - id: "522681", - _vectors: { manual: [0.1, 0.6, 0.8] }, - }, - { - title: "How to Train Your Dragon: The Hidden World", - release_year: 2019, - id: "166428", - _vectors: { manual: [0.7, 0.7, -0.4] }, - }, - { - title: "All Quiet on the Western Front", - release_year: 1930, - id: "143", - _vectors: { manual: [-0.5, 0.3, 0.85] }, - }, -]; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on embedders", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient(permission); - - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: Get default embedders`, async () => { - const client = await getClient(permission); - const response = await client.index(index.uid).setting.getEmbedders(); - - expect(response).toEqual({}); - }); - - test(`${permission} key: Update embedders with 'userProvided' source`, async () => { - const client = await getClient(permission); - const newEmbedder: SingleUpdatableSettings["embedders"] = { - default: { - source: "userProvided", - dimensions: 1, - distribution: { - mean: 0.7, - sigma: 0.3, - }, - binaryQuantized: false, - }, - }; - await client - .index(index.uid) - .setting.updateEmbedders(newEmbedder) - .waitTask(); - - const response = await client.index(index.uid).setting.getEmbedders(); - - expect(response).toEqual(newEmbedder); - expect(response).not.toHaveProperty("documentTemplateMaxBytes"); - }); - - test(`${permission} key: Update embedders with 'openAi' source`, async () => { - const client = await getClient(permission); - const newEmbedder: SingleUpdatableSettings["embedders"] = { - default: { - source: "openAi", - apiKey: "", - model: "text-embedding-3-small", - documentTemplate: - "A movie titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}", - dimensions: 1536, - distribution: { - mean: 0.7, - sigma: 0.3, - }, - url: "https://api.openai.com/v1/embeddings", - documentTemplateMaxBytes: 500, - binaryQuantized: false, - }, - }; - await client - .index(index.uid) - .setting.updateEmbedders(newEmbedder) - .waitTask(); - - const response = await client.index(index.uid).setting.getEmbedders(); - - expect(response).toEqual({ - default: { - ...newEmbedder.default, - apiKey: " { - const client = await getClient(permission); - const newEmbedder: SingleUpdatableSettings["embedders"] = { - default: { - source: "huggingFace", - model: "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", - documentTemplate: - "A movie titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}", - distribution: { - mean: 0.7, - sigma: 0.3, - }, - pooling: "useModel", - documentTemplateMaxBytes: 500, - binaryQuantized: false, - }, - }; - await client - .index(index.uid) - .setting.updateEmbedders(newEmbedder) - .waitTask({ timeout: 60_000 }); - - const response = await client.index(index.uid).setting.getEmbedders(); - - expect(response).toEqual(newEmbedder); - }); - - test(`${permission} key: Update embedders with 'rest' source`, async () => { - const client = await getClient(permission); - const newEmbedder: SingleUpdatableSettings["embedders"] = { - default: { - source: "rest", - url: "https://api.openai.com/v1/embeddings", - apiKey: "", - dimensions: 1536, - documentTemplate: - "A movie titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}", - distribution: { - mean: 0.7, - sigma: 0.3, - }, - request: { - model: "text-embedding-3-small", - input: ["{{text}}", "{{..}}"], - }, - response: { - data: [ - { - embedding: "{{embedding}}", - }, - "{{..}}", - ], - }, - headers: { - "Custom-Header": "CustomValue", - }, - documentTemplateMaxBytes: 500, - binaryQuantized: false, - }, - }; - await client - .index(index.uid) - .setting.updateEmbedders(newEmbedder) - .waitTask(); - - const response = await client.index(index.uid).setting.getEmbedders(); - - expect(response).toEqual({ - default: { - ...newEmbedder.default, - apiKey: " { - const client = await getClient(permission); - const newEmbedder: SingleUpdatableSettings["embedders"] = { - default: { - source: "ollama", - url: "http://localhost:11434/api/embeddings", - apiKey: "", - model: "nomic-embed-text", - documentTemplate: "blabla", - distribution: { - mean: 0.7, - sigma: 0.3, - }, - dimensions: 512, - documentTemplateMaxBytes: 500, - binaryQuantized: false, - }, - }; - await client - .index(index.uid) - .setting.updateEmbedders(newEmbedder) - .waitTask(); - - const response = await client.index(index.uid).setting.getEmbedders(); - - expect(response).toEqual({ - default: { - ...newEmbedder.default, - apiKey: " { - const client = await getClient(permission); - - const newEmbedder: SingleUpdatableSettings["embedders"] = { - image: { - source: "userProvided", - dimensions: 512, - }, - }; - await client - .index(index.uid) - .setting.updateEmbedders(newEmbedder) - .waitTask(); - - const response = await client.index(index.uid).setting.getEmbedders(); - - expect(response).toEqual(newEmbedder); - }); - - test(`${permission} key: Update embedders with composite embedder`, async () => { - const adminKey = await getKey("Admin"); - - // first enable the network endpoint. - await fetch(`${HOST}/experimental-features`, { - body: JSON.stringify({ compositeEmbedders: true }), - headers: { - Authorization: `Bearer ${adminKey}`, - "Content-Type": "application/json", - }, - method: "PATCH", - }); - - const client = await getClient(permission); - const embedders: SingleUpdatableSettings["embedders"] = { - default: { - source: "composite", - searchEmbedder: { - source: "huggingFace", - model: - "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", - pooling: "useModel", - }, - indexingEmbedder: { - source: "huggingFace", - model: - "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", - documentTemplate: "{{doc.title}}", - pooling: "useModel", - documentTemplateMaxBytes: 500, - }, - }, - }; - - const task = await client - .index(index.uid) - .setting.updateEmbedders(embedders) - .waitTask(); - const response = await client.index(index.uid).setting.getEmbedders(); - - const processedTask = await client.tasks.getTask(task.uid); - expect(processedTask.status).toEqual("succeeded"); - expect(response).toEqual(embedders); - }); - - test(`${permission} key: Reset embedders`, async () => { - const client = await getClient(permission); - await client.index(index.uid).setting.resetEmbedders().waitTask(); - - const response = await client.index(index.uid).setting.getEmbedders(); - - expect(response).toEqual({}); - }); - - test(`${permission} key: search (POST) with vectors`, async () => { - const client = await getClient(permission); - - await client - .index(index.uid) - .setting.updateEmbedders({ - default: { - source: "userProvided", - dimensions: 1, - }, - }) - .waitTask(); - - const response = await client.index(index.uid).search("", { - vector: [1], - hybrid: { - embedder: "default", - semanticRatio: 1.0, - }, - }); - - expect(response).toHaveProperty("hits"); - expect(response).toHaveProperty("semanticHitCount"); - // Those fields are no longer returned by the search response - // We want to ensure that they don't appear in it anymore - expect(response).not.toHaveProperty("vector"); - expect(response).not.toHaveProperty("_semanticScore"); - }); - - test(`${permission} key: search (GET) with vectors`, async () => { - const client = await getClient(permission); - - await client - .index(index.uid) - .setting.updateEmbedders({ - default: { - source: "userProvided", - dimensions: 1, - }, - }) - .waitTask(); - - const response = await client.index(index.uid).searchGet("", { - vector: [1], - hybridEmbedder: "default", - hybridSemanticRatio: 1.0, - }); - - expect(response).toHaveProperty("hits"); - expect(response).toHaveProperty("semanticHitCount"); - // Those fields are no longer returned by the search response - // We want to ensure that they don't appear in it anymore - expect(response).not.toHaveProperty("vector"); - expect(response).not.toHaveProperty("_semanticScore"); - }); - - test(`${permission} key: search for similar documents`, async () => { - const client = await getClient(permission); - - const newEmbedder: SingleUpdatableSettings["embedders"] = { - manual: { - source: "userProvided", - dimensions: 3, - }, - }; - await client - .index(index.uid) - .setting.updateEmbedders(newEmbedder) - .waitTask(); - - await client - .index(index.uid) - .addDocuments(datasetSimilarSearch) - .waitTask(); - - const response = await client.index(index.uid).searchSimilarDocuments({ - embedder: "manual", - id: "143", - }); - - expect(response).toHaveProperty("hits"); - expect(response.hits.length).toEqual(4); - expect(response).toHaveProperty("offset", 0); - expect(response).toHaveProperty("limit", 20); - expect(response).toHaveProperty("estimatedTotalHits", 4); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getEmbedders route`, async () => { - const route = `indexes/${index.uid}/settings/embedders`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getEmbedders(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateEmbedders route`, async () => { - const route = `indexes/${index.uid}/settings/embedders`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateEmbedders({}), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetEmbedders route`, async () => { - const route = `indexes/${index.uid}/settings/embedders`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetEmbedders(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/facet_search_settings.test.ts b/tests/facet_search_settings.test.ts deleted file mode 100644 index 6d3b2ad5a..000000000 --- a/tests/facet_search_settings.test.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { afterAll, expect, test, describe, beforeEach } from "vitest"; -import { ErrorStatusCode } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on facet search settings", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("Master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get facetSearch settings on empty index`, async () => { - const client = await getClient(permission); - - const response = await client.index(index.uid).setting.getFacetSearch(); - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Set facetSearch settings with dedicated endpoint on empty index`, async () => { - const client = await getClient(permission); - - await client.index(index.uid).setting.updateFacetSearch(false).waitTask(); - - const updatedSettings = await client - .index(index.uid) - .setting.getFacetSearch(); - expect(updatedSettings).toBe(false); - }); - - test(`${permission} key: Reset facetSearch settings on an empty index`, async () => { - const client = await getClient(permission); - - await client.index(index.uid).setting.resetFacetSearch().waitTask(); - - const response = await client.index(index.uid).setting.getFacetSearch(); - expect(response).toMatchSnapshot(); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on facet search settings", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get facet search settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getFacetSearch(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update facet search settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateFacetSearch(false), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset facet search settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetFacetSearch(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])( - "Test on facet search settings", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get facet search settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getFacetSearch(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update facet search settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateFacetSearch(false), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset facet search settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetFacetSearch(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getFacetSearch route`, async () => { - const route = `indexes/${index.uid}/settings/facet-search`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getFacetSearch(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateFacetSearch route`, async () => { - const route = `indexes/${index.uid}/settings/facet-search`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateFacetSearch(false), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetFacetSearch route`, async () => { - const route = `indexes/${index.uid}/settings/facet-search`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetFacetSearch(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/faceting.test.ts b/tests/faceting.test.ts deleted file mode 100644 index ccde334be..000000000 --- a/tests/faceting.test.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { - expect, - test, - describe, - beforeEach, - afterAll, - beforeAll, -} from "vitest"; -import { ErrorStatusCode, type FacetingSettings } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on faceting", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default faceting object`, async () => { - const client = await getClient(permission); - - const response = await client.index(index.uid).setting.getFaceting(); - - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Update faceting settings`, async () => { - const client = await getClient(permission); - const newFaceting: FacetingSettings = { - maxValuesPerFacet: 12, - sortFacetValuesBy: { test: "count" }, - }; - await client - .index(index.uid) - .setting.updateFaceting(newFaceting) - .waitTask(); - - const response = await client.index(index.uid).setting.getFaceting(); - - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Update faceting at null`, async () => { - const client = await getClient(permission); - await client - .index(index.uid) - .setting.updateFaceting({ maxValuesPerFacet: null }) - .waitTask(); - - const response = await client.index(index.uid).setting.getFaceting(); - - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Reset faceting`, async () => { - const client = await getClient(permission); - await client - .index(index.uid) - .setting.updateFaceting({ maxValuesPerFacet: 12 }) - .waitTask(); - - await client.index(index.uid).setting.resetFaceting().waitTask(); - - const response = await client.index(index.uid).setting.getFaceting(); - - expect(response).toMatchSnapshot(); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on faceting", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get faceting and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getFaceting(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update faceting and be denied`, async () => { - const client = await getClient(permission); - await expect( - client - .index(index.uid) - .setting.updateFaceting({ maxValuesPerFacet: 13 }), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset faceting and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetFaceting(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])("Test on faceting", ({ permission }) => { - beforeAll(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get faceting and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getFaceting(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update faceting and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateFaceting({ maxValuesPerFacet: 13 }), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset faceting and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetFaceting(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); -}); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getFaceting route`, async () => { - const route = `indexes/${index.uid}/settings/faceting`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getFaceting(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateFaceting route`, async () => { - const route = `indexes/${index.uid}/settings/faceting`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client - .index(index.uid) - .setting.updateFaceting({ maxValuesPerFacet: undefined }), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetFaceting route`, async () => { - const route = `indexes/${index.uid}/settings/faceting`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetFaceting(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/filterable_attributes.test.ts b/tests/filterable_attributes.test.ts deleted file mode 100644 index c2ad29c55..000000000 --- a/tests/filterable_attributes.test.ts +++ /dev/null @@ -1,216 +0,0 @@ -import { expect, test, describe, beforeEach, afterAll } from "vitest"; -import { ErrorStatusCode, type SingleUpdatableSettings } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on searchable attributes", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default attributes for filtering`, async () => { - const client = await getClient(permission); - const response = await client - .index(index.uid) - .setting.getFilterableAttributes(); - - expect(response?.sort()).toEqual([]); - }); - - test(`${permission} key: Update attributes for filtering`, async () => { - const client = await getClient(permission); - const newFilterableAttributes = ["genre"]; - await client - .index(index.uid) - .setting.updateFilterableAttributes(newFilterableAttributes) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getFilterableAttributes(); - expect(response).toEqual(newFilterableAttributes); - }); - - test(`${permission} key: Update attributes for filtering at null`, async () => { - const client = await getClient(permission); - await client - .index(index.uid) - .setting.updateFilterableAttributes(null) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getFilterableAttributes(); - - expect(response?.sort()).toEqual([]); - }); - - test(`${permission} key: Update attributes with granular attribute syntax`, async () => { - const client = await getClient(permission); - const newFilterableAttributes: SingleUpdatableSettings["filterableAttributes"] = - [ - "author", - { - attributePatterns: ["genre"], - features: { - facetSearch: true, - filter: { equality: true, comparison: false }, - }, - }, - ]; - await client - .index(index.uid) - .setting.updateFilterableAttributes(newFilterableAttributes) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getFilterableAttributes(); - expect(response).toEqual(newFilterableAttributes); - }); - - test(`${permission} key: Reset attributes for filtering`, async () => { - const client = await getClient(permission); - await client - .index(index.uid) - .setting.resetFilterableAttributes() - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getFilterableAttributes(); - - expect(response?.sort()).toEqual([]); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on attributes for filtering", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get attributes for filtering and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getFilterableAttributes(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update attributes for filtering and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateFilterableAttributes([]), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset attributes for filtering and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetFilterableAttributes(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])( - "Test on attributes for filtering", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get attributes for filtering and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getFilterableAttributes(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update attributes for filtering and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateFilterableAttributes([]), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset attributes for filtering and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetFilterableAttributes(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getFilterableAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/filterable-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getFilterableAttributes(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateFilterableAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/filterable-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateFilterableAttributes([]), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetFilterableAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/filterable-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetFilterableAttributes(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/localized_attributes.test.ts b/tests/localized_attributes.test.ts deleted file mode 100644 index ffd3245f3..000000000 --- a/tests/localized_attributes.test.ts +++ /dev/null @@ -1,226 +0,0 @@ -import { - afterAll, - beforeAll, - beforeEach, - describe, - expect, - test, -} from "vitest"; -import { ErrorStatusCode, type SingleUpdatableSettings } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -const DEFAULT_LOCALIZED_ATTRIBUTES = null; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on localizedAttributes", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("Master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default localizedAttributes settings`, async () => { - const client = await getClient(permission); - const response = await client - .index(index.uid) - .setting.getLocalizedAttributes(); - - expect(response).toEqual(DEFAULT_LOCALIZED_ATTRIBUTES); - }); - - test(`${permission} key: Update localizedAttributes to valid value`, async () => { - const client = await getClient(permission); - const newLocalizedAttributes: SingleUpdatableSettings["localizedAttributes"] = - [{ attributePatterns: ["title"], locales: ["eng"] }]; - await client - .index(index.uid) - .setting.updateLocalizedAttributes(newLocalizedAttributes) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getLocalizedAttributes(); - - expect(response).toEqual(newLocalizedAttributes); - }); - - test(`${permission} key: Update localizedAttributes to null`, async () => { - const client = await getClient(permission); - const newLocalizedAttributes = null; - await client - .index(index.uid) - .setting.updateLocalizedAttributes(newLocalizedAttributes) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getLocalizedAttributes(); - - expect(response).toEqual(DEFAULT_LOCALIZED_ATTRIBUTES); - }); - - test(`${permission} key: Update localizedAttributes with invalid value`, async () => { - const client = await getClient(permission); - const newLocalizedAttributes = - "hello" as unknown as SingleUpdatableSettings["localizedAttributes"]; // bad localizedAttributes value - - await expect( - client - .index(index.uid) - .setting.updateLocalizedAttributes(newLocalizedAttributes), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INVALID_SETTINGS_LOCALIZED_ATTRIBUTES, - ); - }); - - test(`${permission} key: Reset localizedAttributes`, async () => { - const client = await getClient(permission); - const newLocalizedAttributes: SingleUpdatableSettings["localizedAttributes"] = - []; - await client - .index(index.uid) - .setting.updateLocalizedAttributes(newLocalizedAttributes) - .waitTask(); - await client - .index(index.uid) - .setting.resetLocalizedAttributes() - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getLocalizedAttributes(); - - expect(response).toEqual(DEFAULT_LOCALIZED_ATTRIBUTES); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on localizedAttributes", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get localizedAttributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getLocalizedAttributes(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update localizedAttributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateLocalizedAttributes([]), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset localizedAttributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetLocalizedAttributes(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])( - "Test on localizedAttributes", - ({ permission }) => { - beforeAll(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get localizedAttributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getLocalizedAttributes(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update localizedAttributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateLocalizedAttributes([]), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset localizedAttributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetLocalizedAttributes(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getLocalizedAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/localized-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getLocalizedAttributes(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateLocalizedAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/localized-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateLocalizedAttributes(null), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetLocalizedAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/localized-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetLocalizedAttributes(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/non_separator_tokens.test.ts b/tests/non_separator_tokens.test.ts deleted file mode 100644 index 9279693ad..000000000 --- a/tests/non_separator_tokens.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { expect, test, describe, beforeEach, afterAll } from "vitest"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on non separator tokens", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default non separator tokens`, async () => { - const client = await getClient(permission); - const response = await client - .index(index.uid) - .setting.getNonSeparatorTokens(); - - expect(response).toEqual([]); - }); - - test(`${permission} key: Update non separator tokens`, async () => { - const client = await getClient(permission); - const newNonSeparatorTokens = ["&sep", "/", "|"]; - await client - .index(index.uid) - .setting.updateNonSeparatorTokens(newNonSeparatorTokens) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getNonSeparatorTokens(); - - expect(response).toEqual(newNonSeparatorTokens); - }); - - test(`${permission} key: Update non separator tokens with null value`, async () => { - const client = await getClient(permission); - const newNonSeparatorTokens = null; - await client - .index(index.uid) - .setting.updateNonSeparatorTokens(newNonSeparatorTokens) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getNonSeparatorTokens(); - - expect(response).toEqual([]); - }); - - test(`${permission} key: Reset NonSeparator tokens`, async () => { - const client = await getClient(permission); - await client - .index(index.uid) - .setting.resetNonSeparatorTokens() - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getNonSeparatorTokens(); - - expect(response).toEqual([]); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getNonSeparatorTokens route`, async () => { - const route = `indexes/${index.uid}/settings/non-separator-tokens`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getNonSeparatorTokens(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateNonSeparatorTokens route`, async () => { - const route = `indexes/${index.uid}/settings/non-separator-tokens`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateNonSeparatorTokens([]), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetNonSeparatorTokens route`, async () => { - const route = `indexes/${index.uid}/settings/non-separator-tokens`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetNonSeparatorTokens(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/pagination.test.ts b/tests/pagination.test.ts deleted file mode 100644 index 25280f509..000000000 --- a/tests/pagination.test.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { - expect, - test, - describe, - beforeEach, - afterAll, - beforeAll, -} from "vitest"; -import { ErrorStatusCode } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on pagination", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("Master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default pagination settings`, async () => { - const client = await getClient(permission); - const response = await client.index(index.uid).setting.getPagination(); - - expect(response).toEqual({ maxTotalHits: 1000 }); - }); - - test(`${permission} key: Update pagination`, async () => { - const client = await getClient(permission); - const newPagination = { - maxTotalHits: 100, - }; - await client - .index(index.uid) - .setting.updatePagination(newPagination) - .waitTask(); - - const response = await client.index(index.uid).setting.getPagination(); - - expect(response).toEqual(newPagination); - }); - - test(`${permission} key: Update pagination at null`, async () => { - const client = await getClient(permission); - const newPagination = { - maxTotalHits: null, - }; - await client - .index(index.uid) - .setting.updatePagination(newPagination) - .waitTask(); - - const response = await client.index(index.uid).setting.getPagination(); - - expect(response).toEqual({ maxTotalHits: 1000 }); - }); - - test(`${permission} key: Reset pagination`, async () => { - const client = await getClient(permission); - const newPagination = { - maxTotalHits: 100, - }; - await client - .index(index.uid) - .setting.updatePagination(newPagination) - .waitTask(); - await client.index(index.uid).setting.resetPagination().waitTask(); - - const response = await client.index(index.uid).setting.getPagination(); - - expect(response).toEqual({ maxTotalHits: 1000 }); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on pagination", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get pagination and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getPagination(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update pagination and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updatePagination({ maxTotalHits: 10 }), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset pagination and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetPagination(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])( - "Test on pagination", - ({ permission }) => { - beforeAll(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get pagination and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getPagination(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update pagination and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updatePagination({ maxTotalHits: 10 }), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset pagination and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetPagination(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getPagination route`, async () => { - const route = `indexes/${index.uid}/settings/pagination`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getPagination(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updatePagination route`, async () => { - const route = `indexes/${index.uid}/settings/pagination`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updatePagination({ maxTotalHits: null }), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetPagination route`, async () => { - const route = `indexes/${index.uid}/settings/pagination`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetPagination(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/prefix_search_settings.test.ts b/tests/prefix_search_settings.test.ts deleted file mode 100644 index 6453b7fae..000000000 --- a/tests/prefix_search_settings.test.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { afterAll, expect, test, describe, beforeEach } from "vitest"; -import { ErrorStatusCode } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on prefix search settings", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("Master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get prefixSearch settings on empty index`, async () => { - const client = await getClient(permission); - - const response = await client.index(index.uid).setting.getPrefixSearch(); - expect(response).toMatchSnapshot(); - }); - - test(`${permission} key: Set prefixSearch settings with dedicated endpoint on empty index`, async () => { - const client = await getClient(permission); - - await client - .index(index.uid) - .setting.updatePrefixSearch("disabled") - .waitTask(); - - const updatedSettings = await client - .index(index.uid) - .setting.getPrefixSearch(); - expect(updatedSettings).toBe("disabled"); - }); - - test(`${permission} key: Reset prefixSearch settings on an empty index`, async () => { - const client = await getClient(permission); - - await client.index(index.uid).setting.resetPrefixSearch().waitTask(); - - const response = await client.index(index.uid).setting.getPrefixSearch(); - expect(response).toMatchSnapshot(); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on prefix search settings", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get prefix search settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getPrefixSearch(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update prefix search settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updatePrefixSearch("disabled"), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset prefix search settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetPrefixSearch(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])( - "Test on prefix search settings", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get prefix search settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getPrefixSearch(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update prefix search settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updatePrefixSearch("disabled"), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset prefix search settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetPrefixSearch(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getPrefixSearch route`, async () => { - const route = `indexes/${index.uid}/settings/prefix-search`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getPrefixSearch(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updatePrefixSearch route`, async () => { - const route = `indexes/${index.uid}/settings/prefix-search`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updatePrefixSearch("disabled"), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetPrefixSearch route`, async () => { - const route = `indexes/${index.uid}/settings/prefix-search`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetPrefixSearch(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/proximity_precision.test.ts b/tests/proximity_precision.test.ts deleted file mode 100644 index e76b88b4a..000000000 --- a/tests/proximity_precision.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { afterAll, describe, test, beforeEach, expect } from "vitest"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on proximity precision", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default proximity precision`, async () => { - const client = await getClient(permission); - const response = await client - .index(index.uid) - .setting.getProximityPrecision(); - - expect(response).toEqual("byWord"); - }); - - test(`${permission} key: Update proximity precision with 'byAttribute' value`, async () => { - const client = await getClient(permission); - const newProximityPrecision = "byAttribute"; - await client - .index(index.uid) - .setting.updateProximityPrecision(newProximityPrecision) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getProximityPrecision(); - - expect(response).toEqual(newProximityPrecision); - }); - - test(`${permission} key: Update proximity precision with 'byWord' value`, async () => { - const client = await getClient(permission); - const newProximityPrecision = "byWord"; - await client - .index(index.uid) - .setting.updateProximityPrecision(newProximityPrecision) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getProximityPrecision(); - - expect(response).toEqual(newProximityPrecision); - }); - - test(`${permission} key: Reset proximity precision`, async () => { - const client = await getClient(permission); - await client - .index(index.uid) - .setting.resetProximityPrecision() - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getProximityPrecision(); - - expect(response).toEqual("byWord"); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getProximityPrecision route`, async () => { - const route = `indexes/${index.uid}/settings/proximity-precision`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getProximityPrecision(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateProximityPrecision route`, async () => { - const route = `indexes/${index.uid}/settings/proximity-precision`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateProximityPrecision("byAttribute"), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetProximityPrecision route`, async () => { - const route = `indexes/${index.uid}/settings/proximity-precision`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetProximityPrecision(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/ranking_rules.test.ts b/tests/ranking_rules.test.ts deleted file mode 100644 index 8da726f7a..000000000 --- a/tests/ranking_rules.test.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { expect, test, describe, beforeEach, afterAll } from "vitest"; -import { ErrorStatusCode, type RankingRuleView } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -const defaultRankingRules = [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness", -]; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on ranking rules", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default ranking rules`, async () => { - const client = await getClient(permission); - const response = await client.index(index.uid).setting.getRankingRules(); - expect(response).toEqual(defaultRankingRules); - }); - - test(`${permission} key: Update ranking rules`, async () => { - const client = await getClient(permission); - const newRankingRules: RankingRuleView[] = [ - "title:asc", - "typo", - "description:desc", - ]; - await client - .index(index.uid) - .setting.updateRankingRules(newRankingRules) - .waitTask(); - - const response = await client.index(index.uid).setting.getRankingRules(); - - expect(response).toEqual(newRankingRules); - }); - - test(`${permission} key: Update ranking rules at null`, async () => { - const client = await getClient(permission); - await client.index(index.uid).setting.updateRankingRules(null).waitTask(); - - const response = await client.index(index.uid).setting.getRankingRules(); - - expect(response).toEqual(defaultRankingRules); - }); - - test(`${permission} key: Reset ranking rules`, async () => { - const client = await getClient(permission); - await client.index(index.uid).setting.resetRankingRules().waitTask(); - - const response = await client.index(index.uid).setting.getRankingRules(); - - expect(response).toEqual(defaultRankingRules); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on ranking rules", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - }); - - test(`${permission} key: try to get ranking rules and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getRankingRules(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update ranking rules and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateRankingRules([]), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset ranking rules and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetRankingRules(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])( - "Test on ranking rules", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - }); - - test(`${permission} key: try to get ranking rules and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getRankingRules(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update ranking rules and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateRankingRules([]), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset ranking rules and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetRankingRules(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getRankingRules route`, async () => { - const route = `indexes/${index.uid}/settings/ranking-rules`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getRankingRules(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateRankingRules route`, async () => { - const route = `indexes/${index.uid}/settings/ranking-rules`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateRankingRules([]), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetRankingRules route`, async () => { - const route = `indexes/${index.uid}/settings/ranking-rules`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetRankingRules(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/search_cutoff_ms.test.ts b/tests/search_cutoff_ms.test.ts deleted file mode 100644 index 45792a57a..000000000 --- a/tests/search_cutoff_ms.test.ts +++ /dev/null @@ -1,219 +0,0 @@ -import { - afterAll, - beforeAll, - beforeEach, - describe, - expect, - test, -} from "vitest"; -import { ErrorStatusCode, type SingleUpdatableSettings } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -const DEFAULT_SEARCHCUTOFF_MS = null; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on searchCutoffMs", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("Master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default searchCutoffMs settings`, async () => { - const client = await getClient(permission); - const response = await client - .index(index.uid) - .setting.getSearchCutoffMs(); - - expect(response).toEqual(DEFAULT_SEARCHCUTOFF_MS); - }); - - test(`${permission} key: Update searchCutoffMs to valid value`, async () => { - const client = await getClient(permission); - const newSearchCutoffMs = 100; - await client - .index(index.uid) - .setting.updateSearchCutoffMs(newSearchCutoffMs) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getSearchCutoffMs(); - - expect(response).toEqual(newSearchCutoffMs); - }); - - test(`${permission} key: Update searchCutoffMs to null`, async () => { - const client = await getClient(permission); - const newSearchCutoffMs = null; - await client - .index(index.uid) - .setting.updateSearchCutoffMs(newSearchCutoffMs) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getSearchCutoffMs(); - - expect(response).toEqual(DEFAULT_SEARCHCUTOFF_MS); - }); - - test(`${permission} key: Update searchCutoffMs with invalid value`, async () => { - const client = await getClient(permission); - const newSearchCutoffMs = - "hello" as unknown as SingleUpdatableSettings["searchCutoffMs"]; // bad searchCutoffMs value - - await expect( - client.index(index.uid).setting.updateSearchCutoffMs(newSearchCutoffMs), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INVALID_SETTINGS_SEARCH_CUTOFF_MS, - ); - }); - - test(`${permission} key: Reset searchCutoffMs`, async () => { - const client = await getClient(permission); - const newSearchCutoffMs = 100; - await client - .index(index.uid) - .setting.updateSearchCutoffMs(newSearchCutoffMs) - .waitTask(); - await client.index(index.uid).setting.resetSearchCutoffMs().waitTask(); - - const response = await client - .index(index.uid) - .setting.getSearchCutoffMs(); - - expect(response).toEqual(DEFAULT_SEARCHCUTOFF_MS); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on searchCutoffMs", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get searchCutoffMs and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getSearchCutoffMs(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update searchCutoffMs and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateSearchCutoffMs(100), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset searchCutoffMs and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetSearchCutoffMs(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])( - "Test on searchCutoffMs", - ({ permission }) => { - beforeAll(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get searchCutoffMs and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getSearchCutoffMs(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update searchCutoffMs and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateSearchCutoffMs(100), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset searchCutoffMs and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetSearchCutoffMs(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getSearchCutoffMs route`, async () => { - const route = `indexes/${index.uid}/settings/search-cutoff-ms`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getSearchCutoffMs(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateSearchCutoffMs route`, async () => { - const route = `indexes/${index.uid}/settings/search-cutoff-ms`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateSearchCutoffMs(null), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetSearchCutoffMs route`, async () => { - const route = `indexes/${index.uid}/settings/search-cutoff-ms`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetSearchCutoffMs(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/searchable_attributes.test.ts b/tests/searchable_attributes.test.ts deleted file mode 100644 index 0fd890532..000000000 --- a/tests/searchable_attributes.test.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { - afterAll, - beforeAll, - beforeEach, - describe, - expect, - test, -} from "vitest"; -import { ErrorStatusCode } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on searchable attributes", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default searchable attributes`, async () => { - const client = await getClient(permission); - - const response = await client - .index(index.uid) - .setting.getSearchableAttributes(); - - expect(response).toEqual(["*"]); - }); - - test(`${permission} key: Update searchable attributes`, async () => { - const client = await getClient(permission); - const newSearchableAttributes = ["title"]; - await client - .index(index.uid) - .setting.updateSearchableAttributes(newSearchableAttributes) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getSearchableAttributes(); - - expect(response).toEqual(newSearchableAttributes); - }); - - test(`${permission} key: Update searchable attributes at null`, async () => { - const client = await getClient(permission); - await client - .index(index.uid) - .setting.updateSearchableAttributes(null) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getSearchableAttributes(); - - expect(response).toEqual(["*"]); - }); - - test(`${permission} key: Reset searchable attributes`, async () => { - const client = await getClient(permission); - await client - .index(index.uid) - .setting.resetSearchableAttributes() - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getSearchableAttributes(); - - expect(response).toEqual(["*"]); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on searchable attributes", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get searchable attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getSearchableAttributes(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update searchable attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateSearchableAttributes([]), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset searchable attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetSearchableAttributes(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])( - "Test on searchable attributes", - ({ permission }) => { - beforeAll(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get searchable attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getSearchableAttributes(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update searchable attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateSearchableAttributes([]), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset searchable attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetSearchableAttributes(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getSearchableAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/searchable-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getSearchableAttributes(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateSearchableAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/searchable-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateSearchableAttributes([]), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetSearchableAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/searchable-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetSearchableAttributes(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/separator_tokens.test.ts b/tests/separator_tokens.test.ts deleted file mode 100644 index 875869a89..000000000 --- a/tests/separator_tokens.test.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { afterAll, beforeEach, describe, expect, test } from "vitest"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on separator tokens", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default separator tokens`, async () => { - const client = await getClient(permission); - const response = await client - .index(index.uid) - .setting.getSeparatorTokens(); - - expect(response).toEqual([]); - }); - - test(`${permission} key: Update separator tokens`, async () => { - const client = await getClient(permission); - const newSeparatorTokens = ["&sep", "/", "|"]; - await client - .index(index.uid) - .setting.updateSeparatorTokens(newSeparatorTokens) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getSeparatorTokens(); - - expect(response).toEqual(newSeparatorTokens); - }); - - test(`${permission} key: Update separator tokens with null value`, async () => { - const client = await getClient(permission); - const newSeparatorTokens = null; - await client - .index(index.uid) - .setting.updateSeparatorTokens(newSeparatorTokens) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getSeparatorTokens(); - - expect(response).toEqual([]); - }); - - test(`${permission} key: Reset separator tokens`, async () => { - const client = await getClient(permission); - await client.index(index.uid).setting.resetSeparatorTokens().waitTask(); - - const response = await client - .index(index.uid) - .setting.getSeparatorTokens(); - - expect(response).toEqual([]); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getSeparatorTokens route`, async () => { - const route = `indexes/${index.uid}/settings/separator-tokens`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getSeparatorTokens(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateSeparatorTokens route`, async () => { - const route = `indexes/${index.uid}/settings/separator-tokens`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateSeparatorTokens([]), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetSeparatorTokens route`, async () => { - const route = `indexes/${index.uid}/settings/separator-tokens`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetSeparatorTokens(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/settings.test.ts b/tests/settings.test.ts index a841f30d3..e0d9ac7e4 100644 --- a/tests/settings.test.ts +++ b/tests/settings.test.ts @@ -1,4 +1,4 @@ -import { test, describe, afterAll } from "vitest"; +import { test, describe, afterAll, beforeAll } from "vitest"; import type { EnqueuedTaskPromise, FacetValuesSort, @@ -303,133 +303,76 @@ const mappedSettings = { }).map((source) => { return [ source, - (() => { - switch (source) { - case "openAi": - return { - input: { - default: { + { + input: { + [source]: (() => { + switch (source) { + case "openAi": + return { source, apiKey: "", model: "text-embedding-3-small", documentTemplate: "A movie titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}", dimensions: 1536, - distribution: { - mean: 0.7, - sigma: 0.3, - }, + distribution: { mean: 0.7, sigma: 0.3 }, url: "https://api.openai.com/v1/embeddings", documentTemplateMaxBytes: 500, binaryQuantized: false, - }, - }, - assertion: (input, output) => { - assert.deepEqual(input, output); - }, - }; - case "huggingFace": - return { - input: { - default: { + }; + case "huggingFace": + return { source, model: "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", documentTemplate: "A movie titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}", - distribution: { - mean: 0.7, - sigma: 0.3, - }, + distribution: { mean: 0.7, sigma: 0.3 }, pooling: "useModel", documentTemplateMaxBytes: 500, binaryQuantized: false, - }, - }, - assertion: (input, output) => { - assert.deepEqual(input, output); - }, - }; - case "ollama": - return { - input: { - default: { + }; + case "ollama": + return { source, url: "http://localhost:11434/api/embeddings", apiKey: "", model: "nomic-embed-text", documentTemplate: "blabla", - distribution: { - mean: 0.7, - sigma: 0.3, - }, + distribution: { mean: 0.7, sigma: 0.3 }, dimensions: 512, documentTemplateMaxBytes: 500, binaryQuantized: false, - }, - }, - assertion: (input, output) => { - assert.deepEqual(input, output); - }, - }; - case "userProvided": - return { - input: { - default: { + }; + case "userProvided": + return { source, dimensions: 1, - distribution: { - mean: 0.7, - sigma: 0.3, - }, + distribution: { mean: 0.7, sigma: 0.3 }, binaryQuantized: false, - }, - }, - assertion: (input, output) => { - assert.deepEqual(input, output); - }, - }; - case "rest": - return { - input: { - default: { + }; + case "rest": + return { source, url: "https://api.openai.com/v1/embeddings", apiKey: "", dimensions: 1536, documentTemplate: "A movie titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}", - distribution: { - mean: 0.7, - sigma: 0.3, - }, + distribution: { mean: 0.7, sigma: 0.3 }, request: { model: "text-embedding-3-small", input: ["{{text}}", "{{..}}"], }, response: { - data: [ - { - embedding: "{{embedding}}", - }, - "{{..}}", - ], - }, - headers: { - "Custom-Header": "CustomValue", + data: [{ embedding: "{{embedding}}" }, "{{..}}"], }, + headers: { "Custom-Header": "CustomValue" }, documentTemplateMaxBytes: 500, binaryQuantized: false, - }, - }, - assertion: (input, output) => { - assert.deepEqual(input, output); - }, - }; - case "composite": - return { - input: { - default: { + }; + case "composite": + return { source, searchEmbedder: { source: "huggingFace", @@ -445,17 +388,32 @@ const mappedSettings = { pooling: "useModel", documentTemplateMaxBytes: 500, }, - }, - }, - assertion: (input, output) => { - assert.deepEqual(input, output); - }, - }; - default: - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - assert.fail(`untested source ${source}`); - } - })(), + }; + default: + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + assert.fail(`untested embedder source ${source}`); + } + })(), + }, + assertion: (input, output) => { + const inputEmbeddingSettings = input?.[source]; + const outputEmbeddingSettings = output?.[source]; + assert( + inputEmbeddingSettings != null && outputEmbeddingSettings != null, + ); + + const { apiKey: inputApiKey, ...restOfInputEmbeddingSettings } = + inputEmbeddingSettings; + const { apiKey: outputApiKey, ...restOfOutputEmbeddingSettings } = + outputEmbeddingSettings; + + assert.deepEqual( + restOfInputEmbeddingSettings, + restOfOutputEmbeddingSettings, + ); + assert(typeof inputApiKey === typeof outputApiKey); + }, + }, ]; }), @@ -515,7 +473,12 @@ const mappedSettings = { ][] >; +beforeAll(async () => { + await ms.updateExperimentalFeatures({ compositeEmbedders: true }); +}); + afterAll(async () => { + await ms.updateExperimentalFeatures({ compositeEmbedders: false }); const task = await index.delete().waitTask(); assert.isTaskSuccessful(task); }); diff --git a/tests/sortable_attributes.test.ts b/tests/sortable_attributes.test.ts deleted file mode 100644 index fda20e7ee..000000000 --- a/tests/sortable_attributes.test.ts +++ /dev/null @@ -1,203 +0,0 @@ -import { - afterAll, - beforeAll, - beforeEach, - describe, - expect, - test, -} from "vitest"; -import { ErrorStatusCode } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on sortable attributes", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default sortable attributes`, async () => { - const client = await getClient(permission); - - const response = await client - .index(index.uid) - .setting.getSortableAttributes(); - - expect(response).toEqual([]); - }); - - test(`${permission} key: Update sortable attributes`, async () => { - const client = await getClient(permission); - const newSortableAttributes = ["title"]; - await client - .index(index.uid) - .setting.updateSortableAttributes(newSortableAttributes) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getSortableAttributes(); - expect(response).toEqual(newSortableAttributes); - }); - - test(`${permission} key: Update sortable attributes at null`, async () => { - const client = await getClient(permission); - await client - .index(index.uid) - .setting.updateSortableAttributes(null) - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getSortableAttributes(); - - expect(response).toEqual([]); - }); - - test(`${permission} key: Reset sortable attributes`, async () => { - const client = await getClient(permission); - await client - .index(index.uid) - .setting.resetSortableAttributes() - .waitTask(); - - const response = await client - .index(index.uid) - .setting.getSortableAttributes(); - - expect(response).toEqual([]); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on sortable attributes", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get sortable attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getSortableAttributes(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update sortable attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateSortableAttributes([]), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset sortable attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetSortableAttributes(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])( - "Test on sortable attributes", - ({ permission }) => { - beforeAll(async () => { - const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - }); - - test(`${permission} key: try to get sortable attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getSortableAttributes(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update sortable attributes and be denied`, async () => { - const client = await getClient(permission); - const resetSortable: string[] = []; - await expect( - client.index(index.uid).setting.updateSortableAttributes(resetSortable), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset sortable attributes and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetSortableAttributes(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getSortableAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/sortable-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getSortableAttributes(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateSortableAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/sortable-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateSortableAttributes([]), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetSortableAttributes route`, async () => { - const route = `indexes/${index.uid}/settings/sortable-attributes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetSortableAttributes(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/stop_words.test.ts b/tests/stop_words.test.ts deleted file mode 100644 index 3e718a581..000000000 --- a/tests/stop_words.test.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { afterAll, beforeEach, describe, expect, test } from "vitest"; -import { ErrorStatusCode } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on stop words", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default stop words`, async () => { - const client = await getClient(permission); - const response = await client.index(index.uid).setting.getStopWords(); - - expect(response).toEqual([]); - }); - - test(`${permission} key: Update stop words`, async () => { - const client = await getClient(permission); - const newStopWords = ["the"]; - await client - .index(index.uid) - .setting.updateStopWords(newStopWords) - .waitTask(); - - const response = await client.index(index.uid).setting.getStopWords(); - - expect(response).toEqual(newStopWords); - }); - - test(`${permission} key: Update stop words with null value`, async () => { - const client = await getClient(permission); - const newStopWords = null; - await client - .index(index.uid) - .setting.updateStopWords(newStopWords) - .waitTask(); - - const response = await client.index(index.uid).setting.getStopWords(); - - expect(response).toEqual([]); - }); - - test(`${permission} key: Reset stop words`, async () => { - const client = await getClient(permission); - await client.index(index.uid).setting.resetStopWords().waitTask(); - - const response = await client.index(index.uid).setting.getStopWords(); - - expect(response).toEqual([]); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on stop words", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - }); - - test(`${permission} key: try to get stop words and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getStopWords(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update stop words and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateStopWords([]), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset stop words and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetStopWords(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])( - "Test on stop words", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - }); - - test(`${permission} key: try to get stop words and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getStopWords(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update stop words and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateStopWords([]), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset stop words and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetStopWords(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getStopWords route`, async () => { - const route = `indexes/${index.uid}/settings/stop-words`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getStopWords(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateStopWords route`, async () => { - const route = `indexes/${index.uid}/settings/stop-words`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateStopWords([]), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetStopWords route`, async () => { - const route = `indexes/${index.uid}/settings/stop-words`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetStopWords(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/synonyms.test.ts b/tests/synonyms.test.ts deleted file mode 100644 index b5eed8b6a..000000000 --- a/tests/synonyms.test.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { afterAll, beforeEach, describe, expect, test } from "vitest"; -import { ErrorStatusCode } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on synonyms", - ({ permission }) => { - beforeEach(async () => { - const client = await getClient("Master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default synonyms`, async () => { - const client = await getClient(permission); - const response = await client.index(index.uid).setting.getSynonyms(); - - expect(response).toEqual({}); - }); - - test(`${permission} key: Update synonyms`, async () => { - const client = await getClient(permission); - const newSynonyms = { - hp: ["harry potter"], - }; - await client - .index(index.uid) - .setting.updateSynonyms(newSynonyms) - .waitTask(); - - const response = await client.index(index.uid).setting.getSynonyms(); - - expect(response).toEqual(newSynonyms); - }); - - test(`${permission} key: Update synonyms with null value`, async () => { - const client = await getClient(permission); - const newSynonyms = null; - await client - .index(index.uid) - .setting.updateSynonyms(newSynonyms) - .waitTask(); - - const response = await client.index(index.uid).setting.getSynonyms(); - - expect(response).toEqual({}); - }); - - test(`${permission} key: Reset synonyms`, async () => { - const client = await getClient(permission); - await client.index(index.uid).setting.resetSynonyms().waitTask(); - - const response = await client.index(index.uid).setting.getSynonyms(); - - expect(response).toEqual({}); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on synonyms", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - }); - - test(`${permission} key: try to get synonyms and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getSynonyms(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update synonyms and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateSynonyms({}), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset synonyms and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetSynonyms(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])("Test on synonyms", ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - }); - - test(`${permission} key: try to get synonyms and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getSynonyms(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update synonyms and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateSynonyms({}), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset synonyms and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetSynonyms(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); -}); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`getSynonyms route`, async () => { - const route = `indexes/${index.uid}/settings/synonyms`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getSynonyms(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateSynonyms route`, async () => { - const route = `indexes/${index.uid}/settings/synonyms`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateSynonyms({}), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`resetSynonyms route`, async () => { - const route = `indexes/${index.uid}/settings/synonyms`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetSynonyms(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); diff --git a/tests/typo_tolerance.test.ts b/tests/typo_tolerance.test.ts deleted file mode 100644 index 6329991a8..000000000 --- a/tests/typo_tolerance.test.ts +++ /dev/null @@ -1,198 +0,0 @@ -import { afterAll, beforeEach, describe, expect, test } from "vitest"; -import { ErrorStatusCode } from "../src/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, - dataset, -} from "./utils/meilisearch-test-utils.js"; - -const index = { - uid: "movies_test", -}; - -const defaultTypoTolerance = { - enabled: true, - minWordSizeForTypos: { - oneTypo: 5, - twoTypos: 9, - }, - disableOnWords: [], - disableOnAttributes: [], -}; - -afterAll(() => { - return clearAllIndexes(config); -}); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Tests on typo tolerance", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - const client = await getClient("master"); - await client.index(index.uid).addDocuments(dataset).waitTask(); - }); - - test(`${permission} key: Get default typo tolerance settings`, async () => { - const client = await getClient(permission); - const response = await client.index(index.uid).setting.getTypoTolerance(); - expect(response).toEqual(defaultTypoTolerance); - }); - - test(`${permission} key: Update typo tolerance settings`, async () => { - const client = await getClient(permission); - const newTypoTolerance = { - enabled: false, - minWordSizeForTypos: { - oneTypo: 1, - twoTypos: 2, - }, - disableOnWords: ["title"], - disableOnAttributes: ["hello"], - }; - await client - .index(index.uid) - .setting.updateTypoTolerance(newTypoTolerance) - .waitTask(); - - const response = await client.index(index.uid).setting.getTypoTolerance(); - - expect(response).toEqual(newTypoTolerance); - }); - - test(`${permission} key: Update typo tolerance using null as value`, async () => { - const client = await getClient(permission); - await client - .index(index.uid) - .setting.updateTypoTolerance(null) - .waitTask(); - - const response = await client.index(index.uid).setting.getTypoTolerance(); - - expect(response).toEqual(defaultTypoTolerance); - }); - - test(`${permission} key: Reset typo tolerance settings`, async () => { - const client = await getClient(permission); - await client.index(index.uid).setting.resetTypoTolerance().waitTask(); - - const response = await client.index(index.uid).setting.getTypoTolerance(); - - expect(response).toEqual(defaultTypoTolerance); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Tests on typo tolerance", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - }); - - test(`${permission} key: try to get typo tolerance settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getTypoTolerance(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to update typo tolerance settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateTypoTolerance({}), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to reset typo tolerance settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetTypoTolerance(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }, -); - -describe.each([{ permission: "No" }])( - "Tests on typo tolerance", - ({ permission }) => { - beforeEach(async () => { - await clearAllIndexes(config); - }); - - test(`${permission} key: try to get typo tolerance settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.getTypoTolerance(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update typo tolerance settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.updateTypoTolerance({}), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to reset typo tolerance settings and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(index.uid).setting.resetTypoTolerance(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }, -); - -describe.each([ - { host: BAD_HOST, trailing: false }, - { host: `${BAD_HOST}/api`, trailing: false }, - { host: `${BAD_HOST}/trailing/`, trailing: true }, -])("Tests on url construction", ({ host, trailing }) => { - test(`get typo tolerance route`, async () => { - const route = `indexes/${index.uid}/settings/typo-tolerance`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.getTypoTolerance(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`update typo tolerance route`, async () => { - const route = `indexes/${index.uid}/settings/typo-tolerance`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.updateTypoTolerance({}), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`reset typo tolerance route`, async () => { - const route = `indexes/${index.uid}/settings/typo-tolerance`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect( - client.index(index.uid).setting.resetTypoTolerance(), - ).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); -}); From 9e9fd85575adaab302b76de5ff7164cc96bd8cd6 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Fri, 25 Apr 2025 09:26:35 +0300 Subject: [PATCH 11/18] Minor changes --- tests/settings.test.ts | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/tests/settings.test.ts b/tests/settings.test.ts index e0d9ac7e4..51a07c1eb 100644 --- a/tests/settings.test.ts +++ b/tests/settings.test.ts @@ -39,7 +39,7 @@ const mappedSettings = { [ undefined, { - input: ["uno", "dos"], + input: ["augustus", "nero"], assertion: (input, output) => { assert.isNotNull(input); assert.isNotNull(output); @@ -53,7 +53,7 @@ const mappedSettings = { [ undefined, { - input: ["tres", "cuatro"], + input: ["charlemagne", "ferdinand"], assertion: (input, output) => { assert.isNotNull(input); assert.isNotNull(output); @@ -68,9 +68,7 @@ const mappedSettings = { undefined, { input: [ - // pattern - "genre", - // granular + "modèleZéro", { attributePatterns: ["modèleUn", "modèleDeux"], features: { @@ -92,7 +90,7 @@ const mappedSettings = { [ undefined, { - input: ["cinco", "seis"], + input: ["madsMikkelsen", "nikolajCosterWaldau"], assertion: (input, output) => { assert.isNotNull(input); assert.isNotNull(output); @@ -129,7 +127,7 @@ const mappedSettings = { [ undefined, { - input: ["siete", "ocho"], + input: ["hideakiAnno", "hayaoMiyazaki"], assertion: (input, output) => { assert.isNotNull(input); assert.isNotNull(output); @@ -143,7 +141,7 @@ const mappedSettings = { [ undefined, { - input: ["nueve", "diez"], + input: ["nile", "amazonRiver"], assertion: (input, output) => { assert.isNotNull(input); assert.isNotNull(output); @@ -171,7 +169,7 @@ const mappedSettings = { [ undefined, { - input: ["suge", "bucle"], + input: ["mountEverest", "k2"], assertion: (input, output) => { assert.isNotNull(input); assert.isNotNull(output); @@ -200,7 +198,7 @@ const mappedSettings = { [ undefined, { - input: "trece", + input: "benjaminFranklin", assertion: (input, output) => { assert.strictEqual(input, output); }, @@ -246,10 +244,7 @@ const mappedSettings = { ...restOutput } = output; - assert(dow1 != null); - assert(dow2 != null); - assert(doa1 != null); - assert(doa2 != null); + assert(dow1 != null && dow2 != null && doa1 != null && doa2 != null); assert.sameMembers(dow1, dow2); assert.sameMembers(doa1, doa2); From 7b836443cb9eebe031e7926d8b45824de7ff99c0 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Fri, 25 Apr 2025 13:49:12 +0300 Subject: [PATCH 12/18] Improve tests --- tests/settings.test.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/settings.test.ts b/tests/settings.test.ts index 51a07c1eb..d76a0092c 100644 --- a/tests/settings.test.ts +++ b/tests/settings.test.ts @@ -470,12 +470,14 @@ const mappedSettings = { beforeAll(async () => { await ms.updateExperimentalFeatures({ compositeEmbedders: true }); + const task = await ms.createIndex(INDEX_UID).waitTask(); + assert.isTaskSuccessful(task); }); afterAll(async () => { - await ms.updateExperimentalFeatures({ compositeEmbedders: false }); const task = await index.delete().waitTask(); assert.isTaskSuccessful(task); + await ms.updateExperimentalFeatures({ compositeEmbedders: false }); }); describe.for(Object.entries(mappedSettings))("%s", ([key, mappedSetting]) => { @@ -506,8 +508,9 @@ describe.for(Object.entries(mappedSettings))("%s", ([key, mappedSetting]) => { test.for(mappedSetting)( "single update and get methods%s", async ([, { input, assertion }]) => { - const task = await updateSetting(input).waitTask(); + const task = await updateSetting(input).waitTask({ timeout: 30_000 }); assert.isTaskSuccessful(task); + assert.strictEqual(task.type, "settingsUpdate"); const taskSetting = task.details?.[castKey]; assert.isDefined(taskSetting); @@ -522,13 +525,17 @@ describe.for(Object.entries(mappedSettings))("%s", ([key, mappedSetting]) => { const task = await resetSetting().waitTask(); assert.includeDeepMembers([null, ["*"]], [task.details?.[castKey]]); assert.isTaskSuccessful(task); + assert.strictEqual(task.type, "settingsUpdate"); }); test.for(mappedSetting)( `${index.updateSettings.name} and ${index.getSettings.name} methods%s`, async ([, { input, assertion }]) => { - const task = await index.updateSettings({ [castKey]: input }).waitTask(); + const task = await index + .updateSettings({ [castKey]: input }) + .waitTask({ timeout: 30_000 }); assert.isTaskSuccessful(task); + assert.strictEqual(task.type, "settingsUpdate"); const taskSetting = task.details?.[castKey]; assert.isDefined(taskSetting); @@ -544,11 +551,13 @@ describe.for(Object.entries(mappedSettings))("%s", ([key, mappedSetting]) => { const task = await index.updateSettings({ [castKey]: null }).waitTask(); assert.includeDeepMembers([null, ["*"]], [task.details?.[castKey]]); assert.isTaskSuccessful(task); + assert.strictEqual(task.type, "settingsUpdate"); }); }); test(`${index.resetSettings.name} method`, async () => { const task = await index.resetSettings().waitTask(); + assert.isTaskSuccessful(task); assert.deepEqual(task.details, { dictionary: null, @@ -572,4 +581,5 @@ test(`${index.resetSettings.name} method`, async () => { synonyms: null, typoTolerance: null, } satisfies Required); + assert.strictEqual(task.type, "settingsUpdate"); }); From 9a954779387c948905cd9a7b48369bfd27cf79d0 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Mon, 19 May 2025 15:49:04 +0300 Subject: [PATCH 13/18] Use randomUUID instead of fixed UUID --- tests/settings.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/settings.test.ts b/tests/settings.test.ts index d76a0092c..2d0932634 100644 --- a/tests/settings.test.ts +++ b/tests/settings.test.ts @@ -1,3 +1,4 @@ +import { randomUUID } from "node:crypto"; import { test, describe, afterAll, beforeAll } from "vitest"; import type { EnqueuedTaskPromise, @@ -15,7 +16,7 @@ import { ObjectKeys, } from "./utils/meilisearch-test-utils.js"; -const INDEX_UID = "e16993ea-0cd2-4a29-9365-b99778a92c74"; +const INDEX_UID = randomUUID(); const ms = await getClient("Master"); const index = ms.index(INDEX_UID); From 4bda5ad5fc1d6c6ce97b07dec43dde9c82a3d950 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Tue, 23 Sep 2025 21:12:03 +0300 Subject: [PATCH 14/18] Fix type issue, temporarily fix test error --- src/types/types.ts | 14 -------------- tests/settings.test.ts | 27 ++++++++++++++------------- 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/src/types/types.ts b/src/types/types.ts index 951b59614..d7e6c3a52 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -584,20 +584,6 @@ export type ChatCompletionRequest = { stream: boolean; }; -export type ChatSettings = { - description: string; - documentTemplate: string; - documentTemplateMaxBytes: number; - searchParameters: SearchParams; -}; - -export type ChatSettingsPayload = { - description?: string; - documentTemplate?: string; - documentTemplateMaxBytes?: number; - searchParameters?: Partial; -}; - /* ** Keys */ diff --git a/tests/settings.test.ts b/tests/settings.test.ts index e21427ab8..04ad6c00b 100644 --- a/tests/settings.test.ts +++ b/tests/settings.test.ts @@ -9,7 +9,6 @@ import type { RankingRuleView, EmbedderSource, UpdatableSettings, - VectorStoreBackend, } from "../src/index.js"; import { assert, @@ -488,18 +487,20 @@ const mappedSettings = { ], ], - vectorStore: objectKeys({ - stable: null, - experimental: null, - }).map((v) => [ - v, - { - input: v, - assertion: (input, output) => { - assert.strictEqual(input, output); - }, - }, - ]), + vectorStore: [], + // TODO: For some reason this gives back 405 Not Allowed + // vectorStore: objectKeys({ + // stable: null, + // experimental: null, + // }).map((v) => [ + // v, + // { + // input: v, + // assertion: (input, output) => { + // assert.strictEqual(input, output); + // }, + // }, + // ]), } satisfies MappedSettings as Record< string, [ From 32d171c624118a9174126b9703e0e50f35280426 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Tue, 23 Sep 2025 21:14:52 +0300 Subject: [PATCH 15/18] Fix experimental settings test --- tests/experimental-features.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/experimental-features.test.ts b/tests/experimental-features.test.ts index 5823ac858..04d84d608 100644 --- a/tests/experimental-features.test.ts +++ b/tests/experimental-features.test.ts @@ -15,6 +15,7 @@ afterAll(async () => { metrics: false, multimodal: false, network: false, + vectorStoreSetting: false, } satisfies { [TKey in keyof RuntimeTogglableFeatures]-?: false }); }); @@ -29,6 +30,7 @@ test(`${ms.updateExperimentalFeatures.name} and ${ms.getExperimentalFeatures.nam metrics: true, multimodal: true, network: true, + vectorStoreSetting: true, }; const updateResponse = await ms.updateExperimentalFeatures(features); From 596691443e53f0a0924fc097ff78b2cb5e9bf08f Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Tue, 23 Sep 2025 21:25:59 +0300 Subject: [PATCH 16/18] Fix test --- src/indexes.ts | 2 +- src/types/settings.ts | 10 ++++------ src/types/shared.ts | 1 + tests/settings.test.ts | 27 +++++++++++++-------------- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/indexes.ts b/src/indexes.ts index 32e008d8e..408bbc126 100644 --- a/src/indexes.ts +++ b/src/indexes.ts @@ -91,7 +91,7 @@ export class Index { facetSearch: "put", prefixSearch: "put", chat: "patch", - vectorStore: "put", + vectorStore: "patch", }, ); } diff --git a/src/types/settings.ts b/src/types/settings.ts index cc0c82697..8a5c4339e 100644 --- a/src/types/settings.ts +++ b/src/types/settings.ts @@ -1,4 +1,7 @@ -import type { PascalToCamelCase } from "./shared.js"; +import type { + PascalToCamelCase, + NonNullableDeepRecordValues, +} from "./shared.js"; import type { RecordAny, SearchParams } from "./types.js"; /** @see `milli::filterable_attributes_rules::FilterFeatures` */ @@ -22,11 +25,6 @@ export type FilterableAttributesPatterns = { /** @see `milli::filterable_attributes_rules::FilterableAttributesRule` */ export type FilterableAttributesRule = string | FilterableAttributesPatterns; -/** Deeply map every property of a record to itself excluding null. */ -type NonNullableDeepRecordValues = { - [TKey in keyof T]: Exclude, null>; -}; - /** Map properties of a record to be optional and nullable. */ type PartialAndNullable = { [P in keyof T]?: T[P] | null }; diff --git a/src/types/shared.ts b/src/types/shared.ts index 42c558785..793339ace 100644 --- a/src/types/shared.ts +++ b/src/types/shared.ts @@ -8,6 +8,7 @@ export type CursorResults = { total: number; }; +/** Deeply map every property of a record to itself excluding null. */ export type NonNullableDeepRecordValues = { // eslint-disable-next-line @typescript-eslint/no-explicit-any [P in keyof T]: T[P] extends any[] diff --git a/tests/settings.test.ts b/tests/settings.test.ts index 04ad6c00b..e21427ab8 100644 --- a/tests/settings.test.ts +++ b/tests/settings.test.ts @@ -9,6 +9,7 @@ import type { RankingRuleView, EmbedderSource, UpdatableSettings, + VectorStoreBackend, } from "../src/index.js"; import { assert, @@ -487,20 +488,18 @@ const mappedSettings = { ], ], - vectorStore: [], - // TODO: For some reason this gives back 405 Not Allowed - // vectorStore: objectKeys({ - // stable: null, - // experimental: null, - // }).map((v) => [ - // v, - // { - // input: v, - // assertion: (input, output) => { - // assert.strictEqual(input, output); - // }, - // }, - // ]), + vectorStore: objectKeys({ + stable: null, + experimental: null, + }).map((v) => [ + v, + { + input: v, + assertion: (input, output) => { + assert.strictEqual(input, output); + }, + }, + ]), } satisfies MappedSettings as Record< string, [ From ceb2db683fa57be2cbc34aff6a8c63fc1e998cd9 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Thu, 25 Sep 2025 10:38:50 +0300 Subject: [PATCH 17/18] Adjustments, docs --- .code-samples.meilisearch.yaml | 168 ++++++++++++++--------------- README.md | 2 +- src/indexes.ts | 8 +- src/settings.ts | 30 +++--- src/types/settings.ts | 6 +- src/types/shared.ts | 3 + tests/documents.test.ts | 8 +- tests/env/node/getting_started.cjs | 2 +- tests/search.test.ts | 2 +- tests/settings.test.ts | 86 +++++++-------- tests/token.test.ts | 2 +- tests/typed_search.test.ts | 2 +- 12 files changed, 157 insertions(+), 162 deletions(-) diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 79efd24cf..e17a5ddf0 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -4,7 +4,7 @@ # You can read more on https://github.com/meilisearch/documentation/tree/master/.vuepress/code-samples --- synonyms_guide_1: |- - client.index('movies').setting.updateSynonyms({ + client.index('movies').settings.updateSynonyms({ 'great': ['fantastic'], 'fantastic': ['great'] }) @@ -12,13 +12,13 @@ date_guide_index_1: |- const games = require('./games.json') client.index('games').addDocuments(games).then((res) => console.log(res)) date_guide_filterable_attributes_1: |- - client.index('games').setting.updateFilterableAttributes(['release_timestamp']) + client.index('games').settings.updateFilterableAttributes(['release_timestamp']) date_guide_filter_1: |- client.index('games').search('', { filter: 'release_timestamp >= 1514761200 AND release_timestamp < 1672527600' }) date_guide_sortable_attributes_1: |- - client.index('games').setting.updateSortableAttributes(['release_timestamp']) + client.index('games').settings.updateSortableAttributes(['release_timestamp']) date_guide_sort_1: |- client.index('games').search('', { sort: ['release_timestamp:desc'], @@ -205,25 +205,25 @@ update_settings_1: |- reset_settings_1: |- client.index('movies').resetSettings() get_synonyms_1: |- - client.index('movies').setting.getSynonyms() + client.index('movies').settings.getSynonyms() update_synonyms_1: |- - client.index('movies').setting.updateSynonyms({ + client.index('movies').settings.updateSynonyms({ wolverine: ['xmen', 'logan'], logan: ['wolverine', 'xmen'], wow: ['world of warcraft'] }) reset_synonyms_1: |- - client.index('movies').setting.resetSynonyms() + client.index('movies').settings.resetSynonyms() get_stop_words_1: |- - client.index('movies').setting.getStopWords() + client.index('movies').settings.getStopWords() update_stop_words_1: |- - client.index('movies').setting.updateStopWords(['of', 'the', 'to']) + client.index('movies').settings.updateStopWords(['of', 'the', 'to']) reset_stop_words_1: |- - client.index('movies').setting.resetStopWords() + client.index('movies').settings.resetStopWords() get_ranking_rules_1: |- - client.index('movies').setting.getRankingRules() + client.index('movies').settings.getRankingRules() update_ranking_rules_1: |- - client.index('movies').setting.updateRankingRules([ + client.index('movies').settings.updateRankingRules([ 'words', 'typo', 'proximity', @@ -234,38 +234,38 @@ update_ranking_rules_1: |- 'rank:desc' ]) reset_ranking_rules_1: |- - client.index('movies').setting.resetRankingRules() + client.index('movies').settings.resetRankingRules() get_distinct_attribute_1: |- - client.index('shoes').setting.getDistinctAttribute() + client.index('shoes').settings.getDistinctAttribute() update_distinct_attribute_1: |- - client.index('shoes').setting.updateDistinctAttribute('skuid') + client.index('shoes').settings.updateDistinctAttribute('skuid') reset_distinct_attribute_1: |- - client.index('shoes').setting.resetDistinctAttribute() + client.index('shoes').settings.resetDistinctAttribute() get_searchable_attributes_1: |- - client.index('movies').setting.getSearchableAttributes() + client.index('movies').settings.getSearchableAttributes() update_searchable_attributes_1: |- - client.index('movies').setting.updateSearchableAttributes([ + client.index('movies').settings.updateSearchableAttributes([ 'title', 'overview', 'genres' ]) reset_searchable_attributes_1: |- - client.index('movies').setting.resetSearchableAttributes() + client.index('movies').settings.resetSearchableAttributes() get_displayed_attributes_1: |- - client.index('movies').setting.getDisplayedAttributes() + client.index('movies').settings.getDisplayedAttributes() update_displayed_attributes_1: |- - client.index('movies').setting.updateDisplayedAttributes([ + client.index('movies').settings.updateDisplayedAttributes([ 'title', 'overview', 'genres', 'release_date' ]) reset_displayed_attributes_1: |- - client.index('movies').setting.resetDisplayedAttributes() + client.index('movies').settings.resetDisplayedAttributes() get_typo_tolerance_1: |- - client.index('books').setting.getTypoTolerance() + client.index('books').settings.getTypoTolerance() update_typo_tolerance_1: |- - client.index('books').setting.updateTypoTolerance({ + client.index('books').settings.updateTypoTolerance({ minWordSizeForTypos: { oneTypo: 4, twoTypos: 10 @@ -275,7 +275,7 @@ update_typo_tolerance_1: |- ] }) reset_typo_tolerance_1: |- - client.index('books').setting.resetTypoTolerance() + client.index('books').settings.resetTypoTolerance() get_index_stats_1: |- client.index('movies').getStats() get_indexes_stats_1: |- @@ -285,16 +285,16 @@ get_health_1: |- get_version_1: |- client.getVersion() distinct_attribute_guide_1: |- - client.index('jackets').setting.updateDistinctAttribute('product_id') + client.index('jackets').settings.updateDistinctAttribute('product_id') field_properties_guide_searchable_1: |- - client.index('movies').setting.updateSearchableAttributes([ + client.index('movies').settings.updateSearchableAttributes([ 'title', 'overview', 'genres', ] ) field_properties_guide_displayed_1: |- - client.index('movies').setting.updateDisplayedAttributes([ + client.index('movies').settings.updateDisplayedAttributes([ 'title', 'overview', 'genres', @@ -380,26 +380,26 @@ search_parameter_guide_attributes_to_search_on_1: |- attributesToSearchOn: ['overview'] }) typo_tolerance_guide_1: |- - client.index('movies').setting.updateTypoTolerance({ + client.index('movies').settings.updateTypoTolerance({ enabled: false }) typo_tolerance_guide_2: |- - client.index('movies').setting.updateTypoTolerance({ + client.index('movies').settings.updateTypoTolerance({ disableOnAttributes: ['title'] }) typo_tolerance_guide_3: |- - client.index('movies').setting.updateTypoTolerance({ + client.index('movies').settings.updateTypoTolerance({ disableOnWords: ['shrek'] }) typo_tolerance_guide_4: |- - client.index('movies').setting.updateTypoTolerance({ + client.index('movies').settings.updateTypoTolerance({ minWordSizeForTypos: { oneTypo: 4, twoTypos: 10 } }) typo_tolerance_guide_5: |- - client.index('movies').updateTypoTolerance({ + client.index('movies').settings.updateTypoTolerance({ disableOnNumbers: true }) add_movies_json_1: |- @@ -445,7 +445,7 @@ getting_started_add_documents: |- getting_started_search: |- client.index('movies').search('botman').then((res) => console.log(res)) getting_started_update_ranking_rules: |- - client.index('movies').setting.updateRankingRules([ + client.index('movies').settings.updateRankingRules([ 'exactness', 'words', 'typo', @@ -456,20 +456,20 @@ getting_started_update_ranking_rules: |- 'rank:desc' ]) getting_started_update_searchable_attributes: |- - client.index('movies').setting.updateSearchableAttributes([ + client.index('movies').settings.updateSearchableAttributes([ 'title' ]) getting_started_update_stop_words: |- - client.index('movies').setting.updateStopWords(['the']) + client.index('movies').settings.updateStopWords(['the']) getting_started_check_task_status: |- client.tasks.getTask(0) getting_started_synonyms: |- - client.index('movies').setting.updateSynonyms({ + client.index('movies').settings.updateSynonyms({ winnie: ['piglet'], piglet: ['winnie'] }) getting_started_update_displayed_attributes: |- - client.index('movies').setting.updateDisplayedAttributes([ + client.index('movies').settings.updateDisplayedAttributes([ 'title', 'overview', 'poster' @@ -493,14 +493,14 @@ getting_started_sorting: |- filter: 'mass < 200' }) getting_started_faceting: |- - client.index('movies').setting.updateFaceting({ + client.index('movies').settings.updateFaceting({ maxValuesPerFacet: 2, sortFacetValuesBy: { '*': 'count' } }) getting_started_typo_tolerance: |- - client.index('movies').setting.updateTypoTolerance({ + client.index('movies').settings.updateTypoTolerance({ minWordSizeForTypos: { oneTypo: 4 } @@ -508,12 +508,12 @@ getting_started_typo_tolerance: |- getting_started_filtering: |- client.index('meteorites').search('', { filter: 'mass < 200' }) getting_started_pagination: |- - client.index('movies').setting.updatePagination({ maxTotalHits: 500 }) + client.index('movies').settings.updatePagination({ maxTotalHits: 500 }) get_filterable_attributes_1: |- - client.index('movies').setting.getFilterableAttributes() + client.index('movies').settings.getFilterableAttributes() update_filterable_attributes_1: |- client.index('movies') - .setting.updateFilterableAttributes([ + .settings.updateFilterableAttributes([ "genres", { attributePatterns: ["genre"], @@ -524,10 +524,10 @@ update_filterable_attributes_1: |- } ]) reset_filterable_attributes_1: |- - client.index('movies').setting.resetFilterableAttributes() + client.index('movies').settings.resetFilterableAttributes() filtering_update_settings_1: |- client.index('movies') - .setting.updateFilterableAttributes([ + .settings.updateFilterableAttributes([ 'director', 'genres' ]) @@ -537,7 +537,7 @@ faceted_search_walkthrough_filter_1: |- filter: [['genres = Horror', 'genres = Mystery'], 'director = "Jordan Peele"'] }) faceted_search_update_settings_1: |- - client.index('movie_ratings').setting.updateFilterableAttributes(['genres', 'rating', 'language']) + client.index('movie_ratings').settings.updateFilterableAttributes(['genres', 'rating', 'language']) faceted_search_1: |- client.index('books').search('classic', { facets: ['genres', 'rating', 'language'] }) post_dump_1: |- @@ -548,12 +548,12 @@ phrase_search_1: |- client.index('movies') .search('"african american" horror') sorting_guide_update_sortable_attributes_1: |- - client.index('books').setting.updateSortableAttributes([ + client.index('books').settings.updateSortableAttributes([ 'author', 'price' ]) sorting_guide_update_ranking_rules_1: |- - client.index('books').setting.updateRankingRules([ + client.index('books').settings.updateRankingRules([ 'words', 'sort', 'typo', @@ -574,25 +574,25 @@ sorting_guide_sort_nested_1: |- 'sort': ['rating.users:asc'], }) get_sortable_attributes_1: |- - client.index('books').setting.getSortableAttributes() + client.index('books').settings.getSortableAttributes() update_sortable_attributes_1: |- client.index('books') - .setting.updateSortableAttributes([ + .settings.updateSortableAttributes([ 'price', 'author' ]) reset_sortable_attributes_1: |- - client.index('books').setting.resetSortableAttributes() + client.index('books').settings.resetSortableAttributes() get_pagination_settings_1: |- - client.index('books').setting.getPagination() + client.index('books').settings.getPagination() update_pagination_settings_1: |- client.index('books').updateSettings({ pagination: { maxTotalHits: 100 }}) reset_pagination_settings_1: |- - client.index('books').setting.resetPagination() + client.index('books').settings.resetPagination() get_faceting_settings_1: |- - client.index('books').setting.getFaceting() + client.index('books').settings.getFaceting() update_faceting_settings_1: |- - client.index('books').setting.updateFaceting({ + client.index('books').settings.updateFaceting({ maxValuesPerFacet: 2 sortFacetValuesBy: { '*': 'alpha', @@ -600,46 +600,46 @@ update_faceting_settings_1: |- } }) reset_faceting_settings_1: |- - client.index('books').setting.resetFaceting() + client.index('books').settings.resetFaceting() get_dictionary_1: |- - client.index('books').setting.getDictionary() + client.index('books').settings.getDictionary() update_dictionary_1: |- - client.index('books').setting.updateDictionary(['J. R. R.', 'W. E. B.']) + client.index('books').settings.updateDictionary(['J. R. R.', 'W. E. B.']) reset_dictionary_1: |- - client.index('books').setting.resetDictionary() + client.index('books').settings.resetDictionary() search_parameter_guide_sort_1: |- client.index('books').search('science fiction', { sort: ['price:asc'], }) get_separator_tokens_1: |- - client.index('books').setting.getSeparatorTokens() + client.index('books').settings.getSeparatorTokens() update_separator_tokens_1: |- - client.index('books').setting.updateSeparatorTokens(['|', '…']) + client.index('books').settings.updateSeparatorTokens(['|', '…']) reset_separator_tokens_1: |- - client.index('books').setting.resetSeparatorTokens() + client.index('books').settings.resetSeparatorTokens() get_non_separator_tokens_1: |- - client.index('books').setting.getNonSeparatorTokens() + client.index('books').settings.getNonSeparatorTokens() update_non_separator_tokens_1: |- - client.index('books').setting.updateNonSeparatorTokens(['@', '#']) + client.index('books').settings.updateNonSeparatorTokens(['@', '#']) reset_non_separator_tokens_1: |- - client.index('books').setting.resetNonSeparatorTokens() + client.index('books').settings.resetNonSeparatorTokens() get_proximity_precision_settings_1: |- - client.index('books').setting.getProximityPrecision() + client.index('books').settings.getProximityPrecision() update_proximity_precision_settings_1: |- - client.index('books').setting.updateProximityPrecision('byAttribute') + client.index('books').settings.updateProximityPrecision('byAttribute') reset_proximity_precision_settings_1: |- - client.index('books').setting.resetProximityPrecision() + client.index('books').settings.resetProximityPrecision() get_search_cutoff_1: |- - client.index('movies').setting.getSearchCutoffMs() + client.index('movies').settings.getSearchCutoffMs() update_search_cutoff_1: |- - client.index('movies').setting.updateSearchCutoffMs(150) + client.index('movies').settings.updateSearchCutoffMs(150) reset_search_cutoff_1: |- - client.index('movies').setting.resetSearchCutoffMs() + client.index('movies').settings.resetSearchCutoffMs() search_parameter_guide_facet_stats_1: |- client.index('movie_ratings').search('Batman', { facets: ['genres', 'rating'] }) geosearch_guide_filter_settings_1: |- client.index('restaurants') - .setting.updateFilterableAttributes([ + .settings.updateFilterableAttributes([ '_geo' ]) geosearch_guide_filter_usage_1: |- @@ -655,7 +655,7 @@ geosearch_guide_filter_usage_3: |- filter: ['_geoBoundingBox([45.494181, 9.214024], [45.449484, 9.179175])'], }) geosearch_guide_sort_settings_1: |- - client.index('restaurants').setting.updateSortableAttributes([ + client.index('restaurants').settings.updateSortableAttributes([ '_geo' ]) geosearch_guide_sort_usage_1: |- @@ -729,7 +729,7 @@ facet_search_1: |- filter: 'rating > 3' }) facet_search_2: |- - client.index('books').setting.updateFaceting({ + client.index('books').settings.updateFaceting({ sortFacetValuesBy: { genres: 'count' } @@ -770,7 +770,7 @@ search_parameter_guide_matching_strategy_3: |- search_parameter_reference_distinct_1: |- client.index('INDEX_NAME').search('QUERY TERMS', { distinct: 'ATTRIBUTE_A' }) distinct_attribute_guide_filterable_1: |- - client.index('products').setting.updateFilterableAttributes(['product_id', 'sku', 'url']) + client.index('products').settings.updateFilterableAttributes(['product_id', 'sku', 'url']) distinct_attribute_guide_distinct_parameter_1: |- client.index('products').search('white shirt', { distinct: 'sku' }) multi_search_federated_1: |- @@ -790,32 +790,32 @@ multi_search_federated_1: |- search_parameter_reference_locales_1: |- client.index('INDEX_NAME').search('QUERY TEXT IN JAPANESE', { locales: ['jpn'] }) get_localized_attribute_settings_1: |- - client.index('INDEX_NAME').setting.getLocalizedAttributes() + client.index('INDEX_NAME').settings.getLocalizedAttributes() update_localized_attribute_settings_1: |- - client.index('INDEX_NAME').setting.updateLocalizedAttributes([ + client.index('INDEX_NAME').settings.updateLocalizedAttributes([ { attributePatterns: ['*_ja'], locales: ['jpn'] }, ]) reset_localized_attribute_settings_1: |- - client.index('INDEX_NAME').setting.resetLocalizedAttributes() + client.index('INDEX_NAME').settings.resetLocalizedAttributes() get_facet_search_settings_1: |- - client.index('INDEX_NAME').setting.getFacetSearch(); + client.index('INDEX_NAME').settings.getFacetSearch(); update_facet_search_settings_1: |- - client.index('INDEX_NAME').setting.updateFacetSearch(false); + client.index('INDEX_NAME').settings.updateFacetSearch(false); reset_facet_search_settings_1: |- - client.index('INDEX_NAME').setting.resetFacetSearch(); + client.index('INDEX_NAME').settings.resetFacetSearch(); get_prefix_search_settings_1: |- - client.index('INDEX_NAME').setting.getPrefixSearch(); + client.index('INDEX_NAME').settings.getPrefixSearch(); update_prefix_search_settings_1: |- - client.index('INDEX_NAME').setting.updatePrefixSearch('disabled'); + client.index('INDEX_NAME').settings.updatePrefixSearch('disabled'); reset_prefix_search_settings_1: |- - client.index('INDEX_NAME').setting.resetPrefixSearch(); + client.index('INDEX_NAME').settings.resetPrefixSearch(); get_all_batches_1: |- client.batches.getBatches(); get_batch_1: |- client.batches.getBatch(BATCH_UID); # Vector search update_embedders_1: |- - client.index('INDEX_NAME').setting.updateEmbedders({ + client.index('INDEX_NAME').settings.updateEmbedders({ default: { source: 'openAi', apiKey: 'OPEN_AI_API_KEY', diff --git a/README.md b/README.md index 5b929f063..2f024679f 100644 --- a/README.md +++ b/README.md @@ -261,7 +261,7 @@ await index.search( To enable filtering, you must first add your attributes to the [`filterableAttributes` index setting](https://www.meilisearch.com/docs/reference/api/settings#filterable-attributes). ```js -await index.setting.updateFilterableAttributes([ +await index.settings.updateFilterableAttributes([ 'id', 'genres' ]) diff --git a/src/indexes.ts b/src/indexes.ts index 408bbc126..4a6403914 100644 --- a/src/indexes.ts +++ b/src/indexes.ts @@ -65,7 +65,7 @@ export class Index { this.tasks, ); - this.#setting = makeSettingFns( + this.#settings = makeSettingFns( this.httpRequest, this.#httpRequestsWithTask, `indexes/${uid}/settings`, @@ -573,14 +573,14 @@ export class Index { }); } - readonly #setting: SettingFns; + readonly #settings: SettingFns; /** * Contains the get, update and reset functions for every individual setting. * * @see {@link https://www.meilisearch.com/docs/reference/api/settings} */ - get setting() { - return this.#setting; + get settings() { + return this.#settings; } } diff --git a/src/settings.ts b/src/settings.ts index 841c119ec..beac9baf0 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,27 +1,23 @@ import type { HttpRequests } from "./http-requests.js"; import type { HttpRequestsWithEnqueuedTaskPromise } from "./task.js"; -import type { - EnqueuedTaskPromise, - SingleUpdatableSettings, - RecordAny, -} from "./types/index.js"; +import type { EnqueuedTaskPromise, Setting, RecordAny } from "./types/index.js"; /** Each setting property mapped to their REST method required for updates. */ type MakeSettingsRecord = { - [TKey in keyof SingleUpdatableSettings]: "put" | "patch"; + [TKey in keyof Setting]: "put" | "patch"; }; /** Each setting property mapped to its get, update and reset functions. */ export type SettingFns = { - [TKey in keyof SingleUpdatableSettings as `get${Capitalize}`]: () => Promise< - SingleUpdatableSettings[TKey] + [TKey in keyof Setting as `get${Capitalize}`]: () => Promise< + Setting[TKey] >; } & { - [TKey in keyof SingleUpdatableSettings as `update${Capitalize}`]: ( - body: SingleUpdatableSettings[TKey], + [TKey in keyof Setting as `update${Capitalize}`]: ( + body: Setting[TKey], ) => EnqueuedTaskPromise; } & { - [TKey in keyof SingleUpdatableSettings as `reset${Capitalize}`]: () => EnqueuedTaskPromise; + [TKey in keyof Setting as `reset${Capitalize}`]: () => EnqueuedTaskPromise; }; function capitalize(str: string): string { @@ -32,7 +28,13 @@ function camelToKebabCase(str: string): string { return str.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`); } -/** Returns an object containing all the setting functions. */ +/** + * Returns an object containing all the setting functions. + * + * @remarks + * This is similar to how it's done in the Meilisearch source code via + * `meilisearch::routes::indexes::settings::make_setting_routes`. + */ export function makeSettingFns( httpRequest: HttpRequests, httpRequestsWithTask: HttpRequestsWithEnqueuedTaskPromise, @@ -46,13 +48,13 @@ export function makeSettingFns( const path = `${basePath}/${camelToKebabCase(name)}`; settingFns[`get${uppercaseName}`] = async function (): Promise< - SingleUpdatableSettings[keyof typeof opts] + Setting[keyof typeof opts] > { return await httpRequest.get({ path }); }; settingFns[`update${uppercaseName}`] = function ( - body: SingleUpdatableSettings[keyof typeof opts], + body: Setting[keyof typeof opts], ): EnqueuedTaskPromise { return httpRequestsWithTask[method]({ path, body }); }; diff --git a/src/types/settings.ts b/src/types/settings.ts index 8a5c4339e..0c9988d41 100644 --- a/src/types/settings.ts +++ b/src/types/settings.ts @@ -1,6 +1,7 @@ import type { PascalToCamelCase, NonNullableDeepRecordValues, + PartialAndNullable, } from "./shared.js"; import type { RecordAny, SearchParams } from "./types.js"; @@ -25,9 +26,6 @@ export type FilterableAttributesPatterns = { /** @see `milli::filterable_attributes_rules::FilterableAttributesRule` */ export type FilterableAttributesRule = string | FilterableAttributesPatterns; -/** Map properties of a record to be optional and nullable. */ -type PartialAndNullable = { [P in keyof T]?: T[P] | null }; - /** * {@link https://www.meilisearch.com/docs/reference/api/settings#proximity-precision} * @@ -258,7 +256,7 @@ export type UpdatableSettings = PartialAndNullable<{ * A version of {@link UpdatableSettings}, the first layer of properties of which * is used to update or get individual settings. */ -export type SingleUpdatableSettings = Required; +export type Setting = Required; /** * {@link https://www.meilisearch.com/docs/reference/api/settings#body} diff --git a/src/types/shared.ts b/src/types/shared.ts index 793339ace..a8aa0cdfb 100644 --- a/src/types/shared.ts +++ b/src/types/shared.ts @@ -8,6 +8,9 @@ export type CursorResults = { total: number; }; +/** Map properties of a record to be optional and nullable. */ +export type PartialAndNullable = { [P in keyof T]?: T[P] | null }; + /** Deeply map every property of a record to itself excluding null. */ export type NonNullableDeepRecordValues = { // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/tests/documents.test.ts b/tests/documents.test.ts index 860ad3000..ae7895616 100644 --- a/tests/documents.test.ts +++ b/tests/documents.test.ts @@ -142,7 +142,7 @@ describe("Documents tests", () => { await client .index(indexPk.uid) - .setting.updateFilterableAttributes(["id"]) + .settings.updateFilterableAttributes(["id"]) .waitTask(); await client.index(indexPk.uid).addDocuments(dataset).waitTask(); @@ -493,7 +493,7 @@ describe("Documents tests", () => { const client = await getClient(permission); await client .index(indexPk.uid) - .setting.updateFilterableAttributes(["id"]); + .settings.updateFilterableAttributes(["id"]); await client.index(indexPk.uid).addDocuments(dataset).waitTask(); const resolvedTask = await client @@ -511,7 +511,7 @@ describe("Documents tests", () => { const client = await getClient(permission); await client .index(indexPk.uid) - .setting.updateFilterableAttributes(["id"]); + .settings.updateFilterableAttributes(["id"]); await client.index(indexPk.uid).addDocuments(dataset).waitTask(); const resolvedTask = await client @@ -685,7 +685,7 @@ describe("Documents tests", () => { const client = await getClient(permission); const index = client.index<(typeof dataset)[number]>(indexPk.uid); - await index.setting.updateFilterableAttributes(["id"]).waitTask(); + await index.settings.updateFilterableAttributes(["id"]).waitTask(); await ( await getClient("Master") diff --git a/tests/env/node/getting_started.cjs b/tests/env/node/getting_started.cjs index 43fbf90ce..f94fc164e 100644 --- a/tests/env/node/getting_started.cjs +++ b/tests/env/node/getting_started.cjs @@ -19,7 +19,7 @@ const { MeiliSearch } = require('../../../dist/cjs/index.cjs') ] // If the index 'movies' does not exist, MeiliSearch creates it when you first add the documents. - await index.setting.updateFilterableAttributes([ + await index.settings.updateFilterableAttributes([ 'director', 'genres', 'id' diff --git a/tests/search.test.ts b/tests/search.test.ts index 6052aadff..07debf8a8 100644 --- a/tests/search.test.ts +++ b/tests/search.test.ts @@ -1214,7 +1214,7 @@ describe.each([ await masterClient .index(index.uid) - .setting.updateLocalizedAttributes([ + .settings.updateLocalizedAttributes([ { attributePatterns: ["title", "comment"], locales: ["fra", "eng"] }, ]) .waitTask(); diff --git a/tests/settings.test.ts b/tests/settings.test.ts index e21427ab8..5d826acb6 100644 --- a/tests/settings.test.ts +++ b/tests/settings.test.ts @@ -3,13 +3,15 @@ import { test, describe, afterAll, beforeAll } from "vitest"; import type { EnqueuedTaskPromise, FacetValuesSort, - SingleUpdatableSettings, + Setting, PrefixSearchSettings, ProximityPrecisionView, RankingRuleView, EmbedderSource, UpdatableSettings, VectorStoreBackend, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + Task, } from "../src/index.js"; import { assert, @@ -21,25 +23,33 @@ const INDEX_UID = randomUUID(); const ms = await getClient("Master"); const index = ms.index(INDEX_UID); -type InputAndAssertion = { - input: SingleUpdatableSettings[T]; - assertion: ( - input: SingleUpdatableSettings[T], - output: SingleUpdatableSettings[T], - ) => void; +type InputAndAssertion = { + input: Setting[T]; + assertion: (input: Setting[T], output: Setting[T]) => void; }; type MappedSettings = { - [TKey in keyof SingleUpdatableSettings]: [ - text: string | undefined, + [TKey in keyof Setting]: [ inputAndAssertion: InputAndAssertion, + text?: string | undefined, ][]; }; +/** + * Each setting mapped to an array of {@link InputAndAssertion}, which will have + * the following happen: + * + * 1. Feeds {@link InputAndAssertion.input} to `update` method and then feeds this + * input and the resulting {@link Task.details} setting value as output to + * {@link InputAndAssertion.assertion} to do any necessary assertions on the + * two values. + * 2. Calls the setting `get` method and feeds it as output to the aforementioned + * assertion method together with the input for the same reason. + * 3. Does the same things with the global consolidated settings method. + */ const mappedSettings = { displayedAttributes: [ [ - undefined, { input: ["augustus", "nero"], assertion: (input, output) => { @@ -53,7 +63,6 @@ const mappedSettings = { searchableAttributes: [ [ - undefined, { input: ["charlemagne", "ferdinand"], assertion: (input, output) => { @@ -67,7 +76,6 @@ const mappedSettings = { filterableAttributes: [ [ - undefined, { input: [ "modèleZéro", @@ -90,7 +98,6 @@ const mappedSettings = { sortableAttributes: [ [ - undefined, { input: ["madsMikkelsen", "nikolajCosterWaldau"], assertion: (input, output) => { @@ -104,7 +111,6 @@ const mappedSettings = { rankingRules: [ [ - undefined, { input: objectKeys({ words: null, @@ -127,7 +133,6 @@ const mappedSettings = { stopWords: [ [ - undefined, { input: ["hideakiAnno", "hayaoMiyazaki"], assertion: (input, output) => { @@ -141,7 +146,6 @@ const mappedSettings = { nonSeparatorTokens: [ [ - undefined, { input: ["nile", "amazonRiver"], assertion: (input, output) => { @@ -155,7 +159,6 @@ const mappedSettings = { separatorTokens: [ [ - undefined, { input: ["once", "doce"], assertion: (input, output) => { @@ -169,7 +172,6 @@ const mappedSettings = { dictionary: [ [ - undefined, { input: ["mountEverest", "k2"], assertion: (input, output) => { @@ -183,7 +185,6 @@ const mappedSettings = { synonyms: [ [ - undefined, { input: { language: ["speech", "tongue", "lingo"], @@ -198,7 +199,6 @@ const mappedSettings = { distinctAttribute: [ [ - undefined, { input: "benjaminFranklin", assertion: (input, output) => { @@ -212,18 +212,17 @@ const mappedSettings = { byWord: null, byAttribute: null, }).map((v) => [ - v, { input: v, assertion: (input, output) => { assert.strictEqual(input, output); }, }, + v, ]), typoTolerance: [ [ - undefined, { input: { enabled: true, @@ -262,7 +261,6 @@ const mappedSettings = { alpha: null, count: null, }).map((v) => [ - `${v} facet value sort`, { input: { maxValuesPerFacet: 42, sortFacetValuesBy: { random_field: v } }, assertion: (input, output) => { @@ -277,11 +275,11 @@ const mappedSettings = { assert.deepEqual(input, output); }, }, + `${v} facet value sort`, ]), pagination: [ [ - undefined, { input: { maxTotalHits: 42 }, assertion: (input, output) => { @@ -300,7 +298,6 @@ const mappedSettings = { composite: null, }).map((source) => { return [ - source, { input: { [source]: (() => { @@ -409,12 +406,12 @@ const mappedSettings = { assert(typeof inputApiKey === typeof outputApiKey); }, }, + source, ]; }), searchCutoffMs: [ [ - undefined, { input: 100, assertion: (input, output) => { @@ -426,7 +423,6 @@ const mappedSettings = { localizedAttributes: [ [ - undefined, { input: [{ attributePatterns: ["title"], locales: ["eng"] }], assertion: (input, output) => { @@ -438,7 +434,6 @@ const mappedSettings = { facetSearch: [ [ - undefined, { input: true, assertion: (input, output) => { @@ -452,18 +447,17 @@ const mappedSettings = { indexingTime: null, disabled: null, }).map((v) => [ - v, { input: v, assertion: (input, output) => { assert.strictEqual(input, output); }, }, + v, ]), chat: [ [ - undefined, { input: { description: @@ -492,19 +486,19 @@ const mappedSettings = { stable: null, experimental: null, }).map((v) => [ - v, { input: v, assertion: (input, output) => { assert.strictEqual(input, output); }, }, + v, ]), } satisfies MappedSettings as Record< string, [ - text: string | undefined, - inputAndAssertion: InputAndAssertion, + inputAndAssertion: InputAndAssertion, + text?: string | undefined, ][] >; @@ -536,26 +530,24 @@ describe.for(Object.entries(mappedSettings))("%s", ([key, mappedSetting]) => { // Union of functions results in intersection of their parameters // https://github.com/microsoft/TypeScript/issues/30581 - const getSetting = index.setting[`get${capitalizedKey}`].bind( - index, - ) as () => Promise; + const getSetting = index.settings[`get${capitalizedKey}`] as () => Promise< + Setting[keyof Setting] + >; - const updateSetting = index.setting[`update${capitalizedKey}`].bind( - index, - ) as ( - v: SingleUpdatableSettings[keyof SingleUpdatableSettings], + const updateSetting = index.settings[`update${capitalizedKey}`] as ( + v: Setting[keyof Setting], ) => EnqueuedTaskPromise; - const resetSetting = index.setting[`reset${capitalizedKey}`].bind(index); + const resetSetting = index.settings[`reset${capitalizedKey}`]; mappedSetting = mappedSetting.map(([a, b]) => [ - a === undefined ? "" : ` with ${a}`, - b, + a, + b === undefined ? "" : ` with ${b}`, ]); test.for(mappedSetting)( - "single update and get methods%s", - async ([, { input, assertion }]) => { + "update and get methods%s", + async ([{ input, assertion }]) => { const task = await updateSetting(input).waitTask({ timeout: 30_000 }); assert.isTaskSuccessful(task); assert.strictEqual(task.type, "settingsUpdate"); @@ -569,7 +561,7 @@ describe.for(Object.entries(mappedSettings))("%s", ([key, mappedSetting]) => { }, ); - test("single reset method", async () => { + test("reset method", async () => { const task = await resetSetting().waitTask(); assert.includeDeepMembers([null, ["*"]], [task.details?.[castKey]]); assert.isTaskSuccessful(task); @@ -578,7 +570,7 @@ describe.for(Object.entries(mappedSettings))("%s", ([key, mappedSetting]) => { test.for(mappedSetting)( `${index.updateSettings.name} and ${index.getSettings.name} methods%s`, - async ([, { input, assertion }]) => { + async ([{ input, assertion }]) => { const task = await index .updateSettings({ [castKey]: input }) .waitTask({ timeout: 30_000 }); diff --git a/tests/token.test.ts b/tests/token.test.ts index e2b25f301..c0c72e7ca 100644 --- a/tests/token.test.ts +++ b/tests/token.test.ts @@ -299,7 +299,7 @@ describe.each([{ permission: "Admin" }])( const masterClient = await getClient("master"); await masterClient .index(UID) - .setting.updateFilterableAttributes(["id"]) + .settings.updateFilterableAttributes(["id"]) .waitTask(); const client = await getClient(permission); const apiKey = await getKey(permission); diff --git a/tests/typed_search.test.ts b/tests/typed_search.test.ts index 89794c561..ab2919e95 100644 --- a/tests/typed_search.test.ts +++ b/tests/typed_search.test.ts @@ -119,7 +119,7 @@ describe.each([ const newFilterableAttributes = ["genre", "title"]; await client .index(index.uid) - .setting.updateFilterableAttributes(newFilterableAttributes) + .settings.updateFilterableAttributes(newFilterableAttributes) .waitTask(); await client.index(index.uid).addDocuments(dataset).waitTask(); From 77b07974faf0c785f7b4d9b669ef9629c15c8f6d Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Thu, 25 Sep 2025 11:21:01 +0300 Subject: [PATCH 18/18] Adjustments --- tests/settings.test.ts | 12 +++++++++--- tests/utils/meilisearch-test-utils.ts | 5 +++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/settings.test.ts b/tests/settings.test.ts index 5d826acb6..8d059fc35 100644 --- a/tests/settings.test.ts +++ b/tests/settings.test.ts @@ -270,7 +270,13 @@ const mappedSettings = { assert(output.sortFacetValuesBy != null); const star = output.sortFacetValuesBy["*"]; delete output.sortFacetValuesBy["*"]; - assert.oneOf(star, ["alpha", undefined]); + assert.oneOf(star, [ + ...objectKeys({ + alpha: null, + count: null, + }), + undefined, + ]); assert.deepEqual(input, output); }, @@ -548,7 +554,7 @@ describe.for(Object.entries(mappedSettings))("%s", ([key, mappedSetting]) => { test.for(mappedSetting)( "update and get methods%s", async ([{ input, assertion }]) => { - const task = await updateSetting(input).waitTask({ timeout: 30_000 }); + const task = await updateSetting(input).waitTask({ timeout: 60_000 }); assert.isTaskSuccessful(task); assert.strictEqual(task.type, "settingsUpdate"); @@ -573,7 +579,7 @@ describe.for(Object.entries(mappedSettings))("%s", ([key, mappedSetting]) => { async ([{ input, assertion }]) => { const task = await index .updateSettings({ [castKey]: input }) - .waitTask({ timeout: 30_000 }); + .waitTask({ timeout: 60_000 }); assert.isTaskSuccessful(task); assert.strictEqual(task.type, "settingsUpdate"); diff --git a/tests/utils/meilisearch-test-utils.ts b/tests/utils/meilisearch-test-utils.ts index 234e502d5..7861dfd02 100644 --- a/tests/utils/meilisearch-test-utils.ts +++ b/tests/utils/meilisearch-test-utils.ts @@ -344,6 +344,11 @@ export type Book = { author: string; }; +/** + * This function is meant to transform a union of types into a tuple of the same + * types. This is not possible otherwise in a safe manner. + * {@link https://stackoverflow.com/questions/55127004/how-to-transform-union-type-to-tuple-type} + */ function objectKeys(o: { [TKey in T]: null }): T[] { return Object.keys(o) as T[]; }