From 54c81f40f360dd4819f95a8a440babd1e8c62336 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Sun, 6 Apr 2025 23:45:18 +0300 Subject: [PATCH 01/20] Refactor indexes --- src/indexes.ts | 90 --------------------- src/meilisearch.ts | 157 ++++++++++-------------------------- src/types/index.ts | 1 + src/types/indexes.ts | 47 +++++++++++ src/types/shared.ts | 6 +- src/types/task_and_batch.ts | 15 ++-- src/types/types.ts | 19 ----- tests/client.test.ts | 8 +- 8 files changed, 102 insertions(+), 241 deletions(-) create mode 100644 src/types/indexes.ts diff --git a/src/indexes.ts b/src/indexes.ts index 7c4938a4d..6e59ba496 100644 --- a/src/indexes.ts +++ b/src/indexes.ts @@ -12,8 +12,6 @@ import type { SearchParams, Filter, SearchRequestGET, - IndexObject, - IndexOptions, IndexStats, DocumentsQuery, DocumentQuery, @@ -61,8 +59,6 @@ import { export class Index { uid: string; primaryKey: string | undefined; - createdAt: Date | undefined; - updatedAt: Date | undefined; httpRequest: HttpRequests; tasks: TaskClient; readonly #httpRequestsWithTask: HttpRequestsWithEnqueuedTaskPromise; @@ -187,92 +183,6 @@ export class Index { }); } - /// - /// INDEX - /// - - /** - * Get index information. - * - * @returns Promise containing index information - */ - async getRawInfo(): Promise { - const res = await this.httpRequest.get({ - path: `indexes/${this.uid}`, - }); - this.primaryKey = res.primaryKey; - this.updatedAt = new Date(res.updatedAt); - this.createdAt = new Date(res.createdAt); - return res; - } - - /** - * Fetch and update Index information. - * - * @returns Promise to the current Index object with updated information - */ - async fetchInfo(): Promise { - await this.getRawInfo(); - return this; - } - - /** - * Get Primary Key. - * - * @returns Promise containing the Primary Key of the index - */ - async fetchPrimaryKey(): Promise { - this.primaryKey = (await this.getRawInfo()).primaryKey; - return this.primaryKey; - } - - /** - * Create an index. - * - * @param uid - Unique identifier of the Index - * @param options - Index options - * @param config - Request configuration options - * @returns Newly created Index object - */ - static create( - uid: string, - options: IndexOptions = {}, - config: Config, - ): EnqueuedTaskPromise { - const httpRequests = new HttpRequests(config); - return getHttpRequestsWithEnqueuedTaskPromise( - httpRequests, - new TaskClient(httpRequests), - ).post({ - path: "indexes", - body: { ...options, uid }, - }); - } - - /** - * Update an index. - * - * @param data - Data to update - * @returns Promise to the current Index object with updated information - */ - update(data?: IndexOptions): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.patch({ - path: `indexes/${this.uid}`, - body: data, - }); - } - - /** - * Delete an index. - * - * @returns Promise which resolves when index is deleted successfully - */ - delete(): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}`, - }); - } - /// /// STATS /// diff --git a/src/meilisearch.ts b/src/meilisearch.ts index 25f1c4e8d..f7da93c5d 100644 --- a/src/meilisearch.ts +++ b/src/meilisearch.ts @@ -9,18 +9,14 @@ import { Index } from "./indexes.js"; import type { KeyCreation, Config, - IndexOptions, - IndexObject, Key, Health, Stats, Version, KeyUpdate, - IndexesQuery, - IndexesResults, KeysQuery, KeysResults, - IndexSwap, + SwapIndexesPayload, MultiSearchParams, FederatedMultiSearchParams, MultiSearchResponseOrSearchResponse, @@ -28,8 +24,12 @@ import type { ExtraRequestInit, Network, RecordAny, + IndexViewList, + ListIndexes, + IndexView, + IndexCreateRequest, + UpdateIndexRequest, } from "./types/index.js"; -import { ErrorStatusCode } from "./types/index.js"; import { HttpRequests } from "./http-requests.js"; import { getHttpRequestsWithEnqueuedTaskPromise, @@ -37,7 +37,6 @@ import { type HttpRequestsWithEnqueuedTaskPromise, } from "./task.js"; import { BatchClient } from "./batch.js"; -import type { MeiliSearchApiError } from "./errors/index.js"; export class MeiliSearch { config: Config; @@ -77,135 +76,61 @@ export class MeiliSearch { } /** - * Return an Index instance + * Get an {@link Index} instance. * - * @param indexUid - The index UID - * @returns Instance of Index + * @param indexUid - The UID of the index + * @returns An instance of {@link Index} */ index(indexUid: string): Index { return new Index(this.config, indexUid); } - /** - * Gather information about an index by calling MeiliSearch and return an - * Index instance with the gathered information - * - * @param indexUid - The index UID - * @returns Promise returning Index instance - */ - async getIndex( - indexUid: string, - ): Promise> { - return new Index(this.config, indexUid).fetchInfo(); - } - - /** - * Gather information about an index by calling MeiliSearch and return the raw - * JSON response - * - * @param indexUid - The index UID - * @returns Promise returning index information - */ - async getRawIndex(indexUid: string): Promise { - return new Index(this.config, indexUid).getRawInfo(); - } - - /** - * Get all the indexes as Index instances. - * - * @param parameters - Parameters to browse the indexes - * @returns Promise returning array of raw index information - */ - async getIndexes( - parameters?: IndexesQuery, - ): Promise> { - const rawIndexes = await this.getRawIndexes(parameters); - const indexes: Index[] = rawIndexes.results.map( - (index) => new Index(this.config, index.uid, index.primaryKey), - ); - return { ...rawIndexes, results: indexes }; + /** {@link https://www.meilisearch.com/docs/reference/api/indexes#get-one-index} */ + async getIndex(indexUid: string): Promise { + return await this.httpRequest.get({ + path: `indexes/${indexUid}`, + }); } - /** - * Get all the indexes in their raw value (no Index instances). - * - * @param parameters - Parameters to browse the indexes - * @returns Promise returning array of raw index information - */ - async getRawIndexes( - parameters?: IndexesQuery, - ): Promise> { - return await this.httpRequest.get>({ + /** {@link https://www.meilisearch.com/docs/reference/api/indexes#list-all-indexes} */ + async getIndexes(listIndexes?: ListIndexes): Promise { + return await this.httpRequest.get({ path: "indexes", - params: parameters, + params: listIndexes, }); } - /** - * Create a new index - * - * @param uid - The index UID - * @param options - Index options - * @returns Promise returning Index instance - */ - createIndex(uid: string, options?: IndexOptions): EnqueuedTaskPromise { - return Index.create(uid, options, this.config); - } - - /** - * Update an index - * - * @param uid - The index UID - * @param options - Index options to update - * @returns Promise returning Index instance after updating - */ - updateIndex(uid: string, options?: IndexOptions): EnqueuedTaskPromise { - return new Index(this.config, uid).update(options); + /** {@link https://www.meilisearch.com/docs/reference/api/indexes#create-an-index} */ + createIndex(indexCreateRequest: IndexCreateRequest): EnqueuedTaskPromise { + return this.#httpRequestsWithTask.post({ + path: "indexes", + body: indexCreateRequest, + }); } - /** - * Delete an index - * - * @param uid - The index UID - * @returns Promise which resolves when index is deleted successfully - */ - deleteIndex(uid: string): EnqueuedTaskPromise { - return new Index(this.config, uid).delete(); + /** {@link https://www.meilisearch.com/docs/reference/api/indexes#update-an-index} */ + updateIndex( + indexUid: string, + updateIndexRequest: UpdateIndexRequest, + ): EnqueuedTaskPromise { + return this.#httpRequestsWithTask.patch({ + path: `indexes/${indexUid}`, + body: updateIndexRequest, + }); } - /** - * Deletes an index if it already exists. - * - * @param uid - The index UID - * @returns Promise which resolves to true when index exists and is deleted - * successfully, otherwise false if it does not exist - */ - async deleteIndexIfExists(uid: string): Promise { - try { - await this.deleteIndex(uid); - return true; - } catch (e) { - if ( - (e as MeiliSearchApiError)?.cause?.code === - ErrorStatusCode.INDEX_NOT_FOUND - ) { - return false; - } - - throw e; - } + /** {@link https://www.meilisearch.com/docs/reference/api/indexes#delete-an-index} */ + deleteIndex(indexUid: string): EnqueuedTaskPromise { + return this.#httpRequestsWithTask.delete({ + path: `indexes/${indexUid}`, + }); } - /** - * Swaps a list of index tuples. - * - * @param params - List of indexes tuples to swap. - * @returns Promise returning object of the enqueued task - */ - swapIndexes(params: IndexSwap[]): EnqueuedTaskPromise { + /** {@link https://www.meilisearch.com/docs/reference/api/indexes#swap-indexes} */ + swapIndexes(swapIndexesPayloads: SwapIndexesPayload[]): EnqueuedTaskPromise { return this.#httpRequestsWithTask.post({ path: "/swap-indexes", - body: params, + body: swapIndexesPayloads, }); } diff --git a/src/types/index.ts b/src/types/index.ts index 2a13bc669..a68fb0bc5 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,3 +1,4 @@ +export * from "./indexes.js"; export * from "./task_and_batch.js"; export * from "./token.js"; export * from "./types.js"; diff --git a/src/types/indexes.ts b/src/types/indexes.ts new file mode 100644 index 000000000..9a7640729 --- /dev/null +++ b/src/types/indexes.ts @@ -0,0 +1,47 @@ +import type { PaginationView } from "./shared.js"; + +/** + * {@link https://www.meilisearch.com/docs/reference/api/indexes#query-parameters} + * + * @see `meilisearch::routes::indexes::ListIndexes` + */ +export type ListIndexes = { + offset?: number; + limit?: number; +}; + +/** + * {@link https://www.meilisearch.com/docs/reference/api/indexes#index-object} + * + * @see `meilisearch::routes::indexes::IndexView` + */ +export type IndexView = { + uid: string; + createdAt: string; + updatedAt: string; + primaryKey: string | null; +}; + +/** {@link https://www.meilisearch.com/docs/reference/api/indexes#response} */ +export type IndexViewList = PaginationView; + +/** + * {@link https://www.meilisearch.com/docs/reference/api/indexes#body-1} + * + * @see `meilisearch::routes::indexes::UpdateIndexRequest` + */ +export type UpdateIndexRequest = { primaryKey?: string | null }; + +/** + * {@link https://www.meilisearch.com/docs/reference/api/indexes#body} + * + * @see `meilisearch::routes::indexes::IndexCreateRequest` + */ +export type IndexCreateRequest = UpdateIndexRequest & { uid: string }; + +/** + * {@link https://www.meilisearch.com/docs/reference/api/indexes#body-2} + * + * @see `meilisearch::routes::swap_indexes::SwapIndexesPayload` + */ +export type SwapIndexesPayload = { indexes: [string, string] }; diff --git a/src/types/shared.ts b/src/types/shared.ts index d475d6948..4d0932f54 100644 --- a/src/types/shared.ts +++ b/src/types/shared.ts @@ -1,10 +1,10 @@ import type { RecordAny } from "./types.js"; -export type CursorResults = { +/** @see `meilisearch::routes::PaginationView` */ +export type PaginationView = { results: T[]; + offset: number; limit: number; - from: number; - next: number; total: number; }; diff --git a/src/types/task_and_batch.ts b/src/types/task_and_batch.ts index 9c8c5d4d6..eb9a8c828 100644 --- a/src/types/task_and_batch.ts +++ b/src/types/task_and_batch.ts @@ -1,6 +1,6 @@ -import type { Settings } from "./types.js"; -import type { CursorResults } from "./shared.js"; -import type { MeiliSearchErrorResponse } from "./types.js"; +import type { Settings, MeiliSearchErrorResponse } from "./types.js"; +import type { PaginationView } from "./shared.js"; +import type { SwapIndexesPayload } from "./indexes.js"; /** Options for awaiting {@link EnqueuedTask}. */ export type WaitOptions = { @@ -93,9 +93,6 @@ export type EnqueuedTask = { /** Either a number or an {@link EnqueuedTask}. */ export type TaskUidOrEnqueuedTask = EnqueuedTask["taskUid"] | EnqueuedTask; -/** {@link https://www.meilisearch.com/docs/reference/api/tasks#indexswap} */ -export type IndexSwap = { indexes: [string, string] }; - /** {@link https://www.meilisearch.com/docs/reference/api/tasks#details} */ export type TaskDetails = Settings & { receivedDocuments?: number; @@ -111,7 +108,7 @@ export type TaskDetails = Settings & { dumpUid?: string | null; context?: Record | null; function?: string; - swaps?: IndexSwap[]; + swaps?: SwapIndexesPayload[]; }; /** @@ -147,7 +144,7 @@ export type EnqueuedTaskPromise = Promise & { * * @see `meilisearch::routes::tasks::AllTasks` at {@link https://github.com/meilisearch/meilisearch} */ -export type TasksResults = CursorResults; +export type TasksResults = PaginationView; /** {@link https://www.meilisearch.com/docs/reference/api/batches#steps} */ type BatchProgressStep = { @@ -190,4 +187,4 @@ export type Batch = { * * @see `meilisearch::routes::batches::AllBatches` at {@link https://github.com/meilisearch/meilisearch} */ -export type BatchesResults = CursorResults; +export type BatchesResults = PaginationView; diff --git a/src/types/types.ts b/src/types/types.ts index 9b1640f14..fc09ea57f 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -130,25 +130,6 @@ export type ResourceResults = Pagination & { total: number; }; -/// -/// Indexes -/// - -export type IndexOptions = { - primaryKey?: string; -}; - -export type IndexObject = { - uid: string; - primaryKey?: string; - createdAt: string; - updatedAt: string; -}; - -export type IndexesQuery = ResourceQuery & {}; - -export type IndexesResults = ResourceResults & {}; - /* * SEARCH PARAMETERS */ diff --git a/tests/client.test.ts b/tests/client.test.ts index c1b5b5926..6a95e23c2 100644 --- a/tests/client.test.ts +++ b/tests/client.test.ts @@ -8,7 +8,7 @@ import { type MockInstance, beforeAll, } from "vitest"; -import type { Health, Version, Stats, IndexSwap } from "../src/index.js"; +import type { Health, Version, Stats, SwapIndexesPayload } from "../src/index.js"; import { ErrorStatusCode, MeiliSearchRequestError } from "../src/index.js"; import { PACKAGE_VERSION } from "../src/package-version.js"; import { @@ -519,7 +519,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .index(index2.uid) .addDocuments([{ id: 1, title: "index_2" }]) .waitTask(); - const swaps: IndexSwap[] = [{ indexes: [index.uid, index2.uid] }]; + const swaps: SwapIndexesPayload[] = [{ indexes: [index.uid, index2.uid] }]; const resolvedTask = await client.swapIndexes(swaps).waitTask(); const docIndex1 = await client.index(index.uid).getDocument(1); @@ -539,7 +539,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( .addDocuments([{ id: 1, title: "index_2" }]) .waitTask(); - const swaps: IndexSwap[] = [ + const swaps: SwapIndexesPayload[] = [ { indexes: ["does_not_exist", index2.uid] }, ]; @@ -556,7 +556,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( test(`${permission} key: Swap two one index with itself`, async () => { const client = await getClient(permission); - const swaps: IndexSwap[] = [{ indexes: [index.uid, index.uid] }]; + const swaps: SwapIndexesPayload[] = [{ indexes: [index.uid, index.uid] }]; await expect(client.swapIndexes(swaps)).rejects.toHaveProperty( "cause.code", From 3e3b746d31ac9a7d7b2cf10f33bb8d1ecddb6239 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Tue, 8 Apr 2025 18:22:25 +0300 Subject: [PATCH 02/20] Fix tests, misc --- playgrounds/javascript/src/meilisearch.ts | 2 +- src/meilisearch.ts | 24 +- src/types/task_and_batch.ts | 8 +- tests/batch.test.ts | 6 +- tests/client.test.ts | 366 +------------- tests/displayed_attributes.test.ts | 4 +- tests/documents.test.ts | 21 +- tests/embedders.test.ts | 2 +- tests/env/typescript-browser/src/index.ts | 6 +- tests/env/typescript-node/src/index.ts | 9 +- tests/facet_search.test.ts | 2 +- tests/facet_search_settings.test.ts | 4 +- tests/faceting.test.ts | 6 +- tests/filterable_attributes.test.ts | 4 +- tests/get_search.test.ts | 6 +- tests/index.test.ts | 591 +++------------------- tests/keys.test.ts | 2 +- tests/localized_attributes.test.ts | 4 +- tests/pagination.test.ts | 4 +- tests/prefix_search_settings.test.ts | 4 +- tests/search.test.ts | 16 +- tests/search_cutoff_ms.test.ts | 4 +- tests/searchable_attributes.test.ts | 4 +- tests/sortable_attributes.test.ts | 6 +- tests/task.test.ts | 4 +- tests/token.test.ts | 2 +- tests/typed_search.test.ts | 8 +- tests/utils/meilisearch-test-utils.ts | 6 +- tests/wait_for_task.test.ts | 2 +- 29 files changed, 166 insertions(+), 961 deletions(-) diff --git a/playgrounds/javascript/src/meilisearch.ts b/playgrounds/javascript/src/meilisearch.ts index 0f1818486..63a7c62d5 100644 --- a/playgrounds/javascript/src/meilisearch.ts +++ b/playgrounds/javascript/src/meilisearch.ts @@ -12,7 +12,7 @@ const index = client.index<{ id: number; title: string; genres: string[] }>( export async function addDocuments(): Promise { await client.deleteIndexIfExists(indexUid); - await client.createIndex(indexUid).waitTask(); + await client.createIndex({ uid: indexUid }).waitTask(); await index .addDocuments([ diff --git a/src/meilisearch.ts b/src/meilisearch.ts index f7da93c5d..951d6951e 100644 --- a/src/meilisearch.ts +++ b/src/meilisearch.ts @@ -37,6 +37,7 @@ import { type HttpRequestsWithEnqueuedTaskPromise, } from "./task.js"; import { BatchClient } from "./batch.js"; +import type { MeiliSearchApiError } from "./errors/meilisearch-api-error.js"; export class MeiliSearch { config: Config; @@ -111,7 +112,7 @@ export class MeiliSearch { /** {@link https://www.meilisearch.com/docs/reference/api/indexes#update-an-index} */ updateIndex( indexUid: string, - updateIndexRequest: UpdateIndexRequest, + updateIndexRequest?: UpdateIndexRequest, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.patch({ path: `indexes/${indexUid}`, @@ -126,6 +127,27 @@ export class MeiliSearch { }); } + /** + * Deletes an index. In case it does not exist, this function will not throw. + * Otherwise it's the same as {@link MeiliSearch.deleteIndex}. + * + * @param uid - The UID of the index + * @returns A promise that resolves to false if index does not exist, + * otherwise to true. + */ + async deleteIndexIfExists(uid: string): Promise { + try { + await this.deleteIndex(uid); + return true; + } catch (error) { + if ((error as MeiliSearchApiError)?.cause?.code === "index_not_found") { + return false; + } + + throw error; + } + } + /** {@link https://www.meilisearch.com/docs/reference/api/indexes#swap-indexes} */ swapIndexes(swapIndexesPayloads: SwapIndexesPayload[]): EnqueuedTaskPromise { return this.#httpRequestsWithTask.post({ diff --git a/src/types/task_and_batch.ts b/src/types/task_and_batch.ts index eb9a8c828..0ef561478 100644 --- a/src/types/task_and_batch.ts +++ b/src/types/task_and_batch.ts @@ -144,7 +144,13 @@ export type EnqueuedTaskPromise = Promise & { * * @see `meilisearch::routes::tasks::AllTasks` at {@link https://github.com/meilisearch/meilisearch} */ -export type TasksResults = PaginationView; +export type TasksResults = { + results: Task[]; + total: number; + limit: number; + from: number | null; + next: number | null; +}; /** {@link https://www.meilisearch.com/docs/reference/api/batches#steps} */ type BatchProgressStep = { diff --git a/tests/batch.test.ts b/tests/batch.test.ts index 42a1e95f9..c5f07c3bd 100644 --- a/tests/batch.test.ts +++ b/tests/batch.test.ts @@ -5,9 +5,7 @@ import { clearAllIndexes, } from "./utils/meilisearch-test-utils.js"; -const index = { - uid: "batch-test", -}; +const index = { uid: "batch-test" }; afterAll(() => { return clearAllIndexes(config); @@ -18,7 +16,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( ({ permission }) => { beforeEach(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex(index).waitTask(); }); test(`${permission} key: Get all batches`, async () => { diff --git a/tests/client.test.ts b/tests/client.test.ts index 6a95e23c2..e26baed2a 100644 --- a/tests/client.test.ts +++ b/tests/client.test.ts @@ -8,7 +8,7 @@ import { type MockInstance, beforeAll, } from "vitest"; -import type { Health, Version, Stats, SwapIndexesPayload } from "../src/index.js"; +import type { Health, Version, Stats } from "../src/index.js"; import { ErrorStatusCode, MeiliSearchRequestError } from "../src/index.js"; import { PACKAGE_VERSION } from "../src/package-version.js"; import { @@ -22,22 +22,6 @@ import { assert, } from "./utils/meilisearch-test-utils.js"; -const indexNoPk = { - uid: "movies_test", -}; -const indexPk = { - uid: "movies_test2", - primaryKey: "id", -}; - -const index = { - uid: "movies_test", -}; - -const index2 = { - uid: "movies_test2", -}; - afterAll(() => { return clearAllIndexes(config); }); @@ -257,7 +241,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( expect(health).toBe(true); - await client.createIndex("test").waitTask(); + await client.createIndex({ uid: "test" }).waitTask(); const { results } = await client.getIndexes(); @@ -278,13 +262,13 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( expect(health).toBe(true); - await client.createIndex("test").waitTask(); + await client.createIndex({ uid: "test" }).waitTask(); const { results } = await client.getIndexes(); expect(results.length).toBe(1); - const index = await client.getIndex("test"); + const index = client.index("test"); await index.addDocuments([{ id: 1, title: "index_2" }]).waitTask(); @@ -367,204 +351,6 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( }); }); - describe("Test on indexes methods", () => { - test(`${permission} key: create with no primary key`, async () => { - const client = await getClient(permission); - await client.createIndex(indexNoPk.uid).waitTask(); - - const newIndex = await client.getIndex(indexNoPk.uid); - expect(newIndex).toHaveProperty("uid", indexNoPk.uid); - expect(newIndex).toHaveProperty("primaryKey", null); - - const rawIndex = await client.index(indexNoPk.uid).getRawInfo(); - expect(rawIndex).toHaveProperty("uid", indexNoPk.uid); - expect(rawIndex).toHaveProperty("primaryKey", null); - expect(rawIndex).toHaveProperty("createdAt", expect.any(String)); - expect(rawIndex).toHaveProperty("updatedAt", expect.any(String)); - - const response = await client.getIndex(indexNoPk.uid); - expect(response.primaryKey).toBe(null); - expect(response.uid).toBe(indexNoPk.uid); - }); - - test(`${permission} key: create with primary key`, async () => { - const client = await getClient(permission); - await client - .createIndex(indexPk.uid, { - primaryKey: indexPk.primaryKey, - }) - .waitTask(); - - const newIndex = await client.getIndex(indexPk.uid); - - expect(newIndex).toHaveProperty("uid", indexPk.uid); - expect(newIndex).toHaveProperty("primaryKey", indexPk.primaryKey); - - const rawIndex = await client.index(indexPk.uid).getRawInfo(); - expect(rawIndex).toHaveProperty("primaryKey", indexPk.primaryKey); - expect(rawIndex).toHaveProperty("createdAt", expect.any(String)); - expect(rawIndex).toHaveProperty("updatedAt", expect.any(String)); - - const response = await client.getIndex(indexPk.uid); - expect(response.primaryKey).toBe(indexPk.primaryKey); - expect(response.uid).toBe(indexPk.uid); - }); - - test(`${permission} key: get all indexes when not empty`, async () => { - const client = await getClient(permission); - - await client.createIndex(indexPk.uid).waitTask(); - - const { results } = await client.getRawIndexes(); - const indexes = results.map((index) => index.uid); - expect(indexes).toEqual(expect.arrayContaining([indexPk.uid])); - expect(indexes.length).toEqual(1); - }); - - test(`${permission} key: Get index that exists`, async () => { - const client = await getClient(permission); - - await client.createIndex(indexPk.uid).waitTask(); - - const response = await client.getIndex(indexPk.uid); - - expect(response).toHaveProperty("uid", indexPk.uid); - }); - - test(`${permission} key: Get index that does not exist`, async () => { - const client = await getClient(permission); - - await expect(client.getIndex("does_not_exist")).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INDEX_NOT_FOUND, - ); - }); - - test(`${permission} key: update primary key`, async () => { - const client = await getClient(permission); - await client.createIndex(indexPk.uid).waitTask(); - await client - .updateIndex(indexPk.uid, { - primaryKey: "newPrimaryKey", - }) - .waitTask(); - - const index = await client.getIndex(indexPk.uid); - - expect(index).toHaveProperty("uid", indexPk.uid); - expect(index).toHaveProperty("primaryKey", "newPrimaryKey"); - }); - - test(`${permission} key: update primary key that already exists`, async () => { - const client = await getClient(permission); - await client - .createIndex(indexPk.uid, { - primaryKey: indexPk.primaryKey, - }) - .waitTask(); - await client - .updateIndex(indexPk.uid, { - primaryKey: "newPrimaryKey", - }) - .waitTask(); - - const index = await client.getIndex(indexPk.uid); - - expect(index).toHaveProperty("uid", indexPk.uid); - expect(index).toHaveProperty("primaryKey", "newPrimaryKey"); - }); - - test(`${permission} key: delete index`, async () => { - const client = await getClient(permission); - await client.createIndex(indexNoPk.uid).waitTask(); - - await client.deleteIndex(indexNoPk.uid).waitTask(); - const { results } = await client.getIndexes(); - - expect(results).toHaveLength(0); - }); - - test(`${permission} key: create index with already existing uid should fail`, async () => { - const client = await getClient(permission); - await client.createIndex(indexPk.uid).waitTask(); - - const task = await client.createIndex(indexPk.uid).waitTask(); - - expect(task.status).toBe("failed"); - }); - - test(`${permission} key: delete index with uid that does not exist should fail`, async () => { - const client = await getClient(permission); - const index = client.index(indexNoPk.uid); - const task = await index.delete().waitTask(); - - expect(task.status).toEqual("failed"); - }); - - test(`${permission} key: fetch deleted index should fail`, async () => { - const client = await getClient(permission); - const index = client.index(indexPk.uid); - await expect(index.getRawInfo()).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INDEX_NOT_FOUND, - ); - }); - - test(`${permission} key: Swap two indexes`, async () => { - const client = await getClient(permission); - await client - .index(index.uid) - .addDocuments([{ id: 1, title: `index_1` }]); - await client - .index(index2.uid) - .addDocuments([{ id: 1, title: "index_2" }]) - .waitTask(); - const swaps: SwapIndexesPayload[] = [{ indexes: [index.uid, index2.uid] }]; - - const resolvedTask = await client.swapIndexes(swaps).waitTask(); - const docIndex1 = await client.index(index.uid).getDocument(1); - const docIndex2 = await client.index(index2.uid).getDocument(1); - - expect(docIndex1.title).toEqual("index_2"); - expect(docIndex2.title).toEqual("index_1"); - expect(resolvedTask.type).toEqual("indexSwap"); - expect(resolvedTask.details!.swaps).toEqual(swaps); - }); - - test(`${permission} key: Swap two indexes with one that does not exist`, async () => { - const client = await getClient(permission); - - await client - .index(index2.uid) - .addDocuments([{ id: 1, title: "index_2" }]) - .waitTask(); - - const swaps: SwapIndexesPayload[] = [ - { indexes: ["does_not_exist", index2.uid] }, - ]; - - const resolvedTask = await client.swapIndexes(swaps).waitTask(); - - expect(resolvedTask.type).toEqual("indexSwap"); - expect(resolvedTask.error?.code).toEqual( - ErrorStatusCode.INDEX_NOT_FOUND, - ); - expect(resolvedTask.details!.swaps).toEqual(swaps); - }); - - // Should be fixed by rc1 - test(`${permission} key: Swap two one index with itself`, async () => { - const client = await getClient(permission); - - const swaps: SwapIndexesPayload[] = [{ indexes: [index.uid, index.uid] }]; - - await expect(client.swapIndexes(swaps)).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INVALID_SWAP_DUPLICATE_INDEX_FOUND, - ); - }); - }); - describe("Test on base routes", () => { test(`${permission} key: get health`, async () => { const client = await getClient(permission); @@ -614,50 +400,6 @@ describe.each([{ permission: "Search" }])( return clearAllIndexes(config); }); - describe("Test on indexes methods", () => { - test(`${permission} key: try to get all indexes and be denied`, async () => { - const client = await getClient(permission); - await expect(client.getIndexes()).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INVALID_API_KEY, - ); - }); - - test(`${permission} key: try to create Index with primary key and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.createIndex(indexPk.uid, { - primaryKey: indexPk.primaryKey, - }), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - - test(`${permission} key: try to create Index with NO primary key and be denied`, async () => { - const client = await getClient(permission); - await expect(client.createIndex(indexNoPk.uid)).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INVALID_API_KEY, - ); - }); - - test(`${permission} key: try to delete index and be denied`, async () => { - const client = await getClient(permission); - await expect(client.deleteIndex(indexPk.uid)).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INVALID_API_KEY, - ); - }); - - test(`${permission} key: try to update index and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.updateIndex(indexPk.uid, { - primaryKey: indexPk.primaryKey, - }), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); - }); - describe("Test on misc client methods", () => { test(`${permission} key: get health`, async () => { const client = await getClient(permission); @@ -694,56 +436,6 @@ describe.each([{ permission: "No" }])( return clearAllIndexes(config); }); - describe("Test on indexes methods", () => { - test(`${permission} key: try to get all indexes and be denied`, async () => { - const client = await getClient(permission); - await expect(client.getIndexes()).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to create Index with primary key and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.createIndex(indexPk.uid, { - primaryKey: indexPk.primaryKey, - }), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to create Index with NO primary key and be denied`, async () => { - const client = await getClient(permission); - await expect(client.createIndex(indexNoPk.uid)).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to delete index and be denied`, async () => { - const client = await getClient(permission); - await expect(client.deleteIndex(indexPk.uid)).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - - test(`${permission} key: try to update index and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.updateIndex(indexPk.uid, { - primaryKey: indexPk.primaryKey, - }), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }); - describe("Test on misc client methods", () => { test(`${permission} key: get health`, async () => { const client = await getClient(permission); @@ -778,56 +470,6 @@ describe.each([ { host: `${BAD_HOST}/api`, trailing: false }, { host: `${BAD_HOST}/trailing/`, trailing: true }, ])("Tests on url construction", ({ host, trailing }) => { - test(`getIndex route`, async () => { - const route = `indexes/${indexPk.uid}`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.getIndex(indexPk.uid)).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`createIndex route`, async () => { - const route = `indexes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.createIndex(indexPk.uid)).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`updateIndex route`, async () => { - const route = `indexes/${indexPk.uid}`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.updateIndex(indexPk.uid)).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`deleteIndex route`, async () => { - const route = `indexes/${indexPk.uid}`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.deleteIndex(indexPk.uid)).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - - test(`get indexes route`, async () => { - const route = `indexes`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.getIndexes()).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); - test(`getKeys route`, async () => { const route = `keys`; const client = new MeiliSearch({ host }); diff --git a/tests/displayed_attributes.test.ts b/tests/displayed_attributes.test.ts index b2779437d..389cf22b1 100644 --- a/tests/displayed_attributes.test.ts +++ b/tests/displayed_attributes.test.ts @@ -74,7 +74,7 @@ describe.each([{ permission: "Search" }])( beforeEach(async () => { await clearAllIndexes(config); const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get displayed attributes and be denied`, async () => { @@ -106,7 +106,7 @@ describe.each([{ permission: "No" }])( beforeEach(async () => { await clearAllIndexes(config); const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get displayed attributes and be denied`, async () => { diff --git a/tests/documents.test.ts b/tests/documents.test.ts index 786ca2b97..add7aa1c6 100644 --- a/tests/documents.test.ts +++ b/tests/documents.test.ts @@ -32,9 +32,10 @@ describe("Documents tests", () => { beforeEach(async () => { await clearAllIndexes(config); const client = await getClient("Master"); - await client.createIndex(indexNoPk.uid).waitTask(); + await client.createIndex({ uid: indexNoPk.uid }).waitTask(); await client - .createIndex(indexPk.uid, { + .createIndex({ + uid: indexPk.uid, primaryKey: indexPk.primaryKey, }) .waitTask(); @@ -398,7 +399,7 @@ describe("Documents tests", () => { }; await client.index(indexNoPk.uid).addDocuments([doc]).waitTask(); - const index = await client.index(indexNoPk.uid).fetchInfo(); + const index = await client.getIndex(indexNoPk.uid); expect(index).toHaveProperty("primaryKey", "_id"); }); @@ -411,7 +412,7 @@ describe("Documents tests", () => { }; await client.index(indexNoPk.uid).addDocuments([doc]).waitTask(); - const index = await client.index(indexNoPk.uid).fetchInfo(); + const index = await client.getIndex(indexNoPk.uid); expect(index).toHaveProperty("primaryKey", "findmeid"); }); @@ -427,7 +428,7 @@ describe("Documents tests", () => { .index(indexNoPk.uid) .addDocuments([doc]) .waitTask(); - const index = await client.index(indexNoPk.uid).fetchInfo(); + const index = await client.getIndex(indexNoPk.uid); expect(task.error?.code).toEqual( "index_primary_key_multiple_candidates_found", @@ -445,7 +446,7 @@ describe("Documents tests", () => { .index(indexNoPk.uid) .addDocuments([doc]) .waitTask(); - const index = await client.index(indexNoPk.uid).fetchInfo(); + const index = await client.getIndex(indexNoPk.uid); expect(task.error?.code).toEqual( "index_primary_key_no_candidate_found", @@ -547,7 +548,7 @@ describe("Documents tests", () => { test(`${permission} key: Delete some documents should trigger error with a hint on a MeilisearchApiError`, async () => { const client = await getClient(permission); - await client.createIndex(indexPk.uid).waitTask(); + await client.createIndex({ uid: indexPk.uid }).waitTask(); await assert.rejects( client.index(indexPk.uid).deleteDocuments({ filter: "" }), @@ -615,14 +616,14 @@ describe("Documents tests", () => { }, ]; const pkIndex = "update_pk"; - await client.createIndex(pkIndex).waitTask(); + await client.createIndex({ uid: pkIndex }).waitTask(); await client .index(pkIndex) .addDocuments(docs, { primaryKey: "unique" }) .waitTask(); - const response = await client.index(pkIndex).getRawInfo(); + const response = await client.getIndex(pkIndex); expect(response).toHaveProperty("uid", pkIndex); expect(response).toHaveProperty("primaryKey", "unique"); }); @@ -658,7 +659,7 @@ describe("Documents tests", () => { ]) .waitTask(); - const index = await client.index(indexNoPk.uid).getRawInfo(); + const index = await client.getIndex(indexNoPk.uid); expect(index.uid).toEqual(indexNoPk.uid); expect(index.primaryKey).toEqual(null); diff --git a/tests/embedders.test.ts b/tests/embedders.test.ts index b41c60eb2..197089c94 100644 --- a/tests/embedders.test.ts +++ b/tests/embedders.test.ts @@ -56,7 +56,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( await clearAllIndexes(config); const client = await getClient(permission); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: Get default embedders`, async () => { diff --git a/tests/env/typescript-browser/src/index.ts b/tests/env/typescript-browser/src/index.ts index 67ec1d0a2..83d588357 100644 --- a/tests/env/typescript-browser/src/index.ts +++ b/tests/env/typescript-browser/src/index.ts @@ -1,4 +1,4 @@ -import { MeiliSearch, type IndexObject } from '../../../../src/index.js' +import { MeiliSearch } from '../../../../src/index.js' import { generateTenantToken } from '../../../../src/token.js' const config = { @@ -14,9 +14,9 @@ function greeter(person: string) { } ;(async () => { - const indexes = await client.getRawIndexes() + const indexes = await client.getIndexes() console.log({ indexes }, 'hello') - const uids = indexes.results.map((index: IndexObject) => index.uid) + const uids = indexes.results.map((index) => index.uid) document.body.innerHTML = `${greeter( user )} this is the list of all your indexes: \n ${uids.join(', ')}` diff --git a/tests/env/typescript-node/src/index.ts b/tests/env/typescript-node/src/index.ts index 495723c13..c8c3539d8 100644 --- a/tests/env/typescript-node/src/index.ts +++ b/tests/env/typescript-node/src/index.ts @@ -2,7 +2,6 @@ import { MeiliSearch, } from '../../../../src/index.js' import type { - IndexObject, SearchResponse, Hits, Hit, @@ -29,11 +28,11 @@ const indexUid = "movies" ;(async () => { await client.deleteIndex(indexUid).waitTask() - await client.createIndex(indexUid).waitTask() + await client.createIndex({uid:indexUid}).waitTask() const index = client.index(indexUid) - const indexes = await client.getRawIndexes() - indexes.results.map((index: IndexObject) => { + const indexes = await client.getIndexes() + indexes.results.map((index) => { console.log(index.uid) // console.log(index.something) -> ERROR }) @@ -44,7 +43,7 @@ const indexUid = "movies" attributesToHighlight: ['title'], // test: true -> ERROR Test does not exist on type SearchParams } - indexes.results.map((index: IndexObject) => index.uid) + indexes.results.map((index) => index.uid) const res: SearchResponse = await index.search( 'avenger', searchParams diff --git a/tests/facet_search.test.ts b/tests/facet_search.test.ts index 53e9b1f34..1936b6413 100644 --- a/tests/facet_search.test.ts +++ b/tests/facet_search.test.ts @@ -41,7 +41,7 @@ describe.each([ await clearAllIndexes(config); const client = await getClient("Master"); const newFilterableAttributes = ["genres", "title"]; - await client.createIndex(index.uid); + await client.createIndex({ uid: index.uid }); await client.index(index.uid).updateSettings({ filterableAttributes: newFilterableAttributes, }); diff --git a/tests/facet_search_settings.test.ts b/tests/facet_search_settings.test.ts index d1bb67dbe..f79a5b80c 100644 --- a/tests/facet_search_settings.test.ts +++ b/tests/facet_search_settings.test.ts @@ -59,7 +59,7 @@ describe.each([{ permission: "Search" }])( beforeEach(async () => { await clearAllIndexes(config); const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get facet search settings and be denied`, async () => { @@ -91,7 +91,7 @@ describe.each([{ permission: "No" }])( beforeEach(async () => { await clearAllIndexes(config); const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get facet search settings and be denied`, async () => { diff --git a/tests/faceting.test.ts b/tests/faceting.test.ts index dc942b810..471fe8c28 100644 --- a/tests/faceting.test.ts +++ b/tests/faceting.test.ts @@ -30,7 +30,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( beforeEach(async () => { await clearAllIndexes(config); const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); await client.index(index.uid).addDocuments(dataset).waitTask(); }); @@ -89,7 +89,7 @@ describe.each([{ permission: "Search" }])( ({ permission }) => { beforeEach(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get faceting and be denied`, async () => { @@ -118,7 +118,7 @@ describe.each([{ permission: "Search" }])( describe.each([{ permission: "No" }])("Test on faceting", ({ permission }) => { beforeAll(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get faceting and be denied`, async () => { diff --git a/tests/filterable_attributes.test.ts b/tests/filterable_attributes.test.ts index 79325ddff..791a2e46b 100644 --- a/tests/filterable_attributes.test.ts +++ b/tests/filterable_attributes.test.ts @@ -69,7 +69,7 @@ describe.each([{ permission: "Search" }])( ({ permission }) => { beforeEach(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get attributes for filtering and be denied`, async () => { @@ -100,7 +100,7 @@ describe.each([{ permission: "No" }])( ({ permission }) => { beforeEach(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get attributes for filtering and be denied`, async () => { diff --git a/tests/get_search.test.ts b/tests/get_search.test.ts index 3a6771b1d..02a242a6f 100644 --- a/tests/get_search.test.ts +++ b/tests/get_search.test.ts @@ -84,8 +84,8 @@ describe.each([ beforeAll(async () => { await clearAllIndexes(config); const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); - await client.createIndex(emptyIndex.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); + await client.createIndex({ uid: emptyIndex.uid }).waitTask(); const newFilterableAttributes = ["genre", "title", "id", "author"]; await client @@ -546,7 +546,7 @@ describe.each([ test(`${permission} key: Try to search on deleted index and fail`, async () => { const client = await getClient(permission); const masterClient = await getClient("Master"); - await masterClient.index(index.uid).delete().waitTask(); + await masterClient.deleteIndex(index.uid).waitTask(); await expect( client.index(index.uid).searchGet("prince"), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INDEX_NOT_FOUND); diff --git a/tests/index.test.ts b/tests/index.test.ts index faea55881..da2b83b10 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -1,544 +1,83 @@ -import { expect, test, describe, beforeEach, afterAll } from "vitest"; -import { ErrorStatusCode } from "../src/types/index.js"; -import { - clearAllIndexes, - config, - BAD_HOST, - MeiliSearch, - getClient, -} from "./utils/meilisearch-test-utils.js"; +import { test, afterAll } from "vitest"; +import { getClient, assert } from "./utils/meilisearch-test-utils.js"; +import { Index, type SwapIndexesPayload } from "../src/index.js"; -const indexNoPk = { - uid: "movies_test", -}; -const indexPk = { - uid: "movies_test2", - primaryKey: "id", -}; +const MY_INDEX_ONE = "my-index-one"; +const MY_INDEX_TWO = "my-index-two"; +const client = await getClient("Master"); -afterAll(() => clearAllIndexes(config)); - -describe.each([{ permission: "Master" }, { permission: "Admin" }])( - "Test on indexes w/ master and admin key", - ({ permission }) => { - beforeEach(() => { - return clearAllIndexes(config); - }); - - test(`${permission} key: create index with NO primary key`, async () => { - const client = await getClient(permission); - await client.createIndex(indexNoPk.uid).waitTask(); - - const newIndex = await client.getIndex(indexNoPk.uid); - - expect(newIndex).toHaveProperty("uid", indexNoPk.uid); - expect(newIndex).toHaveProperty("primaryKey", null); - - const rawIndex = await client.index(indexNoPk.uid).getRawInfo(); - - expect(rawIndex).toHaveProperty("uid", indexNoPk.uid); - expect(rawIndex).toHaveProperty("primaryKey", null); - expect(rawIndex).toHaveProperty("createdAt", expect.any(String)); - expect(rawIndex).toHaveProperty("updatedAt", expect.any(String)); - }); - - test(`${permission} key: create index with primary key`, async () => { - const client = await getClient(permission); - await client - .createIndex(indexPk.uid, { - primaryKey: indexPk.primaryKey, - }) - .waitTask(); - - const newIndex = await client.getIndex(indexPk.uid); - - expect(newIndex).toHaveProperty("uid", indexPk.uid); - expect(newIndex).toHaveProperty("primaryKey", indexPk.primaryKey); - - const rawIndex = await client.index(indexPk.uid).getRawInfo(); - - expect(rawIndex).toHaveProperty("uid", indexPk.uid); - expect(rawIndex).toHaveProperty("primaryKey", indexPk.primaryKey); - expect(rawIndex).toHaveProperty("createdAt", expect.any(String)); - expect(rawIndex).toHaveProperty("updatedAt", expect.any(String)); - }); - - test(`${permission} key: Get raw index that exists`, async () => { - const client = await getClient(permission); - await client.createIndex(indexPk.uid).waitTask(); - - const response = await client.getRawIndex(indexPk.uid); - - expect(response).toHaveProperty("uid", indexPk.uid); - }); - - test(`${permission} key: Get all indexes in Index instances`, async () => { - const client = await getClient(permission); - await client.createIndex(indexPk.uid).waitTask(); - - const { results } = await client.getRawIndexes(); - - expect(results.length).toEqual(1); - expect(results[0].uid).toEqual(indexPk.uid); - }); - - test(`${permission} key: Get index that does not exist`, async () => { - const client = await getClient(permission); - await expect(client.getIndex("does_not_exist")).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INDEX_NOT_FOUND, - ); - }); - - test(`${permission} key: Get raw index that does not exist`, async () => { - const client = await getClient(permission); - await expect(client.getRawIndex("does_not_exist")).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INDEX_NOT_FOUND, - ); - }); - - test(`${permission} key: Get raw index info through client with primary key`, async () => { - const client = await getClient(permission); - await client - .createIndex(indexPk.uid, { primaryKey: indexPk.primaryKey }) - .waitTask(); - - const response = await client.getRawIndex(indexPk.uid); - - expect(response).toHaveProperty("uid", indexPk.uid); - expect(response).toHaveProperty("primaryKey", indexPk.primaryKey); - }); - - test(`${permission} key: Get raw index info through client with NO primary key`, async () => { - const client = await getClient(permission); - await client.createIndex(indexNoPk.uid).waitTask(); - - const response = await client.getRawIndex(indexNoPk.uid); - - expect(response).toHaveProperty("uid", indexNoPk.uid); - expect(response).toHaveProperty("primaryKey", null); - }); - - test(`${permission} key: Get raw index info with primary key`, async () => { - const client = await getClient(permission); - await client - .createIndex(indexPk.uid, { primaryKey: indexPk.primaryKey }) - .waitTask(); - - const response = await client.index(indexPk.uid).getRawInfo(); - - expect(response).toHaveProperty("uid", indexPk.uid); - expect(response).toHaveProperty("primaryKey", indexPk.primaryKey); - }); - - test(`${permission} key: Get raw index info with NO primary key`, async () => { - const client = await getClient(permission); - await client.createIndex(indexNoPk.uid).waitTask(); - - const response = await client.index(indexNoPk.uid).getRawInfo(); - - expect(response).toHaveProperty("uid", indexNoPk.uid); - expect(response).toHaveProperty("primaryKey", null); - }); - - test(`${permission} key: fetch index with primary key`, async () => { - const client = await getClient(permission); - await client - .createIndex(indexPk.uid, { - primaryKey: indexPk.primaryKey, - }) - .waitTask(); - - const index = client.index(indexPk.uid); - const response = await index.fetchInfo(); - - expect(response).toHaveProperty("uid", indexPk.uid); - expect(response).toHaveProperty("primaryKey", indexPk.primaryKey); - }); - - test(`${permission} key: fetch primary key on an index with primary key`, async () => { - const client = await getClient(permission); - await client - .createIndex(indexPk.uid, { - primaryKey: indexPk.primaryKey, - }) - .waitTask(); - - const index = client.index(indexPk.uid); - const response: string | undefined = await index.fetchPrimaryKey(); - - expect(response).toBe(indexPk.primaryKey); - }); - - test(`${permission} key: fetch primary key on an index with NO primary key`, async () => { - const client = await getClient(permission); - await client.createIndex(indexNoPk.uid).waitTask(); - - const index = client.index(indexNoPk.uid); - const response: string | undefined = await index.fetchPrimaryKey(); - - expect(response).toBe(null); - }); - - test(`${permission} key: fetch index with primary key`, async () => { - const client = await getClient(permission); - await client - .createIndex(indexPk.uid, { - primaryKey: indexPk.primaryKey, - }) - .waitTask(); - - const index = client.index(indexPk.uid); - const response = await index.fetchInfo(); - - expect(response).toHaveProperty("uid", indexPk.uid); - expect(response).toHaveProperty("primaryKey", indexPk.primaryKey); - }); - - test(`${permission} key: fetch index with NO primary key`, async () => { - const client = await getClient(permission); - await client.createIndex(indexNoPk.uid).waitTask(); - - const index = client.index(indexNoPk.uid); - const response = await index.fetchInfo(); - - expect(response).toHaveProperty("uid", indexNoPk.uid); - expect(response).toHaveProperty("primaryKey", null); - }); - - test(`${permission} key: get all indexes`, async () => { - const client = await getClient(permission); - await client.createIndex(indexNoPk.uid).waitTask(); - await client.createIndex(indexPk.uid).waitTask(); - - const indexes = await client.getIndexes(); - - expect(indexes.results.length).toEqual(2); - }); - - test(`${permission} key: get all indexes with filters`, async () => { - const client = await getClient(permission); - await client.createIndex(indexNoPk.uid).waitTask(); - await client.createIndex(indexPk.uid).waitTask(); - - const indexes = await client.getIndexes({ limit: 1, offset: 1 }); - - expect(indexes.results.length).toEqual(1); - expect(indexes.results[0].uid).toEqual(indexPk.uid); - }); - - test(`${permission} key: update primary key on an index that has no primary key already`, async () => { - const client = await getClient(permission); - await client.createIndex(indexNoPk.uid).waitTask(); - await client - .index(indexNoPk.uid) - .update({ primaryKey: "newPrimaryKey" }) - .waitTask(); - - const index = await client.getIndex(indexNoPk.uid); - - expect(index).toHaveProperty("uid", indexNoPk.uid); - expect(index).toHaveProperty("primaryKey", "newPrimaryKey"); - }); - - test(`${permission} key: update primary key on an index that has NO primary key already through client`, async () => { - const client = await getClient(permission); - await client.createIndex(indexNoPk.uid).waitTask(); - await client - .updateIndex(indexNoPk.uid, { - primaryKey: indexPk.primaryKey, - }) - .waitTask(); - - const index = await client.getIndex(indexNoPk.uid); - - expect(index).toHaveProperty("uid", indexNoPk.uid); - expect(index).toHaveProperty("primaryKey", indexPk.primaryKey); - }); - - test(`${permission} key: update primary key on an index that has already a primary key and fail through client`, async () => { - const client = await getClient(permission); - await client - .createIndex(indexPk.uid, { - primaryKey: indexPk.primaryKey, - }) - .waitTask(); - await client - .updateIndex(indexPk.uid, { - primaryKey: "newPrimaryKey", - }) - .waitTask(); - - const index = await client.getIndex(indexPk.uid); - - expect(index).toHaveProperty("uid", indexPk.uid); - expect(index).toHaveProperty("primaryKey", "newPrimaryKey"); - }); - - test(`${permission} key: update primary key on an index that has already a primary key and fail`, async () => { - const client = await getClient(permission); - await client - .createIndex(indexPk.uid, { primaryKey: indexPk.primaryKey }) - .waitTask(); - await client - .index(indexPk.uid) - .update({ primaryKey: "newPrimaryKey" }) - .waitTask(); - - const index = await client.getIndex(indexPk.uid); - - expect(index).toHaveProperty("uid", indexPk.uid); - expect(index).toHaveProperty("primaryKey", "newPrimaryKey"); - }); - - test(`${permission} key: delete index`, async () => { - const client = await getClient(permission); - await client.createIndex(indexNoPk.uid).waitTask(); - await client.index(indexNoPk.uid).delete().waitTask(); - - const { results } = await client.getIndexes(); - - expect(results).toHaveLength(0); - }); - - test(`${permission} key: delete index using client`, async () => { - const client = await getClient(permission); - await client.createIndex(indexPk.uid); - await client.deleteIndex(indexPk.uid).waitTask(); - - const { results } = await client.getIndexes(); - - expect(results).toHaveLength(0); - }); - - test(`${permission} key: fetch deleted index should fail`, async () => { - const client = await getClient(permission); - const index = client.index(indexNoPk.uid); - await expect(index.getRawInfo()).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INDEX_NOT_FOUND, - ); - }); - - test(`${permission} key: get deleted raw index should fail through client`, async () => { - const client = await getClient(permission); - await expect(client.getRawIndex(indexNoPk.uid)).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INDEX_NOT_FOUND, - ); - }); - - test(`${permission} key: delete index with uid that does not exist should fail`, async () => { - const client = await getClient(permission); - const index = client.index(indexNoPk.uid); - const task = await index.delete().waitTask(); - - expect(task.status).toBe("failed"); - }); - - test(`${permission} key: get stats of an index`, async () => { - const client = await getClient(permission); - await client.createIndex(indexNoPk.uid).waitTask(); - - const response = await client.index(indexNoPk.uid).getStats(); - - expect(response).toHaveProperty("numberOfDocuments", 0); - expect(response).toHaveProperty("isIndexing", false); - expect(response).toHaveProperty("fieldDistribution", {}); - expect(response).toHaveProperty("numberOfEmbeddedDocuments", 0); - expect(response).toHaveProperty("numberOfEmbeddings", 0); - expect(response).toHaveProperty("rawDocumentDbSize", 0); - expect(response).toHaveProperty("avgDocumentSize", 0); - }); - - test(`${permission} key: Get updatedAt and createdAt through fetch info`, async () => { - const client = await getClient(permission); - await client.createIndex(indexPk.uid).waitTask(); - - const index = await client.index(indexPk.uid).fetchInfo(); - - expect(index.createdAt).toBeInstanceOf(Date); - expect(index.updatedAt).toBeInstanceOf(Date); - }); - - test(`${permission} key: Get updatedAt and createdAt index through getRawInfo`, async () => { - const client = await getClient(permission); - await client.createIndex(indexPk.uid).waitTask(); - - const index = client.index(indexPk.uid); - - expect(index.createdAt).toBe(undefined); - expect(index.updatedAt).toBe(undefined); - - await index.getRawInfo(); - - expect(index.createdAt).toBeInstanceOf(Date); - expect(index.updatedAt).toBeInstanceOf(Date); - }); - }, -); - -describe.each([{ permission: "Search" }])( - "Test on routes with search key", - ({ permission }) => { - beforeEach(() => { - return clearAllIndexes(config); - }); - - test(`${permission} key: try to get index info and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(indexNoPk.uid).getRawInfo(), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); +test.concurrent("index method", () => { + const myIndex = client.index(MY_INDEX_ONE); + assert.instanceOf(myIndex, Index); +}); - test(`${permission} key: try to get raw index and be denied`, async () => { - const client = await getClient(permission); - await expect(client.getRawIndex(indexNoPk.uid)).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INVALID_API_KEY, - ); - }); +afterAll(async () => { + await Promise.all([ + client.deleteIndexIfExists(MY_INDEX_ONE), + client.deleteIndexIfExists(MY_INDEX_TWO), + ]); +}); - test(`${permission} key: try to delete index and be denied`, async () => { - const client = await getClient(permission); - await expect(client.index(indexPk.uid).delete()).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INVALID_API_KEY, - ); - }); +test("createIndex and getIndex method", async () => { + const primaryKey = "objectID"; + await client.createIndex({ uid: MY_INDEX_ONE, primaryKey }).waitTask(); - test(`${permission} key: try to update index and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(indexPk.uid).update({ primaryKey: indexPk.primaryKey }), - ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INVALID_API_KEY); - }); + const { createdAt, updatedAt, ...myIndex } = + await client.getIndex(MY_INDEX_ONE); - test(`${permission} key: try to get stats and be denied`, async () => { - const client = await getClient(permission); - await expect(client.index(indexPk.uid).getStats()).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.INVALID_API_KEY, - ); - }); - }, -); + assert.deepEqual(myIndex, { + primaryKey, + uid: MY_INDEX_ONE, + }); + assert.typeOf(createdAt, "string"); + assert.typeOf(updatedAt, "string"); +}); -describe.each([{ permission: "No" }])( - "Test on routes without an API key", - ({ permission }) => { - beforeEach(() => { - return clearAllIndexes(config); - }); +test("updateIndex method", async () => { + const primaryKey = "id"; + await client.updateIndex(MY_INDEX_ONE, { primaryKey }).waitTask(); - test(`${permission} key: try to get all indexes and be denied`, async () => { - const client = await getClient(permission); - await expect(client.getIndexes()).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); + const { + createdAt: _ca, + updatedAt: _ua, + ...myIndex + } = await client.getIndex(MY_INDEX_ONE); - test(`${permission} key: try to get index info and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(indexNoPk.uid).getRawInfo(), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); + assert.deepEqual(myIndex, { + primaryKey, + uid: MY_INDEX_ONE, + }); +}); - test(`${permission} key: try to get raw index and be denied`, async () => { - const client = await getClient(permission); - await expect(client.getRawIndex(indexNoPk.uid)).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); +test("deleteIndex method", async () => { + const task = await client.deleteIndex(MY_INDEX_ONE).waitTask(); + assert.strictEqual(task.status, "succeeded"); +}); - test(`${permission} key: try to delete index and be denied`, async () => { - const client = await getClient(permission); - await expect(client.index(indexPk.uid).delete()).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); +test("swapIndexes method", async () => { + const indexOne = client.index(MY_INDEX_ONE); + const indexTwo = client.index(MY_INDEX_TWO); - test(`${permission} key: try to update index and be denied`, async () => { - const client = await getClient(permission); - await expect( - client.index(indexPk.uid).update({ primaryKey: indexPk.primaryKey }), - ).rejects.toHaveProperty( - "cause.code", - ErrorStatusCode.MISSING_AUTHORIZATION_HEADER, - ); - }); - }, -); + const doc1 = { id: 1, title: "index_1" }; + const doc2 = { id: 1, title: "index_2" }; -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(`getStats route`, async () => { - const route = `indexes/${indexPk.uid}/stats`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.index(indexPk.uid).getStats()).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); + await indexOne.addDocuments([doc1]).waitTask(); + await indexTwo.addDocuments([doc2]).waitTask(); - test(`getRawInfo route`, async () => { - const route = `indexes/${indexPk.uid}`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.index(indexPk.uid).getRawInfo()).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - await expect(client.index(indexPk.uid).getRawInfo()).rejects.toHaveProperty( - "name", - "MeiliSearchRequestError", - ); - }); + const swaps: SwapIndexesPayload[] = [ + { indexes: [MY_INDEX_ONE, MY_INDEX_TWO] }, + ]; - test(`getRawIndex route`, async () => { - const route = `indexes/${indexPk.uid}`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.getRawIndex(indexPk.uid)).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - await expect(client.getRawIndex(indexPk.uid)).rejects.toHaveProperty( - "name", - "MeiliSearchRequestError", - ); - }); + const task = await client.swapIndexes(swaps).waitTask(); + const docIndex1 = await indexOne.getDocument(doc2.id); + const docIndex2 = await indexTwo.getDocument(doc1.id); - test(`updateIndex route`, async () => { - const route = `indexes/${indexPk.uid}`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.index(indexPk.uid).getRawInfo()).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); + assert.deepEqual(doc1, docIndex2); + assert.deepEqual(doc2, docIndex1); - test(`delete index route`, async () => { - const route = `indexes/${indexPk.uid}`; - const client = new MeiliSearch({ host }); - const strippedHost = trailing ? host.slice(0, -1) : host; - await expect(client.index(indexPk.uid).getRawInfo()).rejects.toHaveProperty( - "message", - `Request to ${strippedHost}/${route} has failed`, - ); - }); + const { type, details } = task; + assert.deepEqual( + { type, details }, + { details: { swaps }, type: "indexSwap" }, + ); }); diff --git a/tests/keys.test.ts b/tests/keys.test.ts index a1e305d07..9a9f30920 100644 --- a/tests/keys.test.ts +++ b/tests/keys.test.ts @@ -136,7 +136,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( }); const newClient = new MeiliSearch({ host: HOST, apiKey: key.key }); - await newClient.createIndex("wildcard_keys_permission"); // test index creation + await newClient.createIndex({ uid: "wildcard_keys_permission" }); // test index creation const task = await newClient .index("wildcard_keys_permission") .addDocuments([{ id: 1 }]) diff --git a/tests/localized_attributes.test.ts b/tests/localized_attributes.test.ts index 963f406be..4b8c9e5d7 100644 --- a/tests/localized_attributes.test.ts +++ b/tests/localized_attributes.test.ts @@ -108,7 +108,7 @@ describe.each([{ permission: "Search" }])( ({ permission }) => { beforeEach(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get localizedAttributes and be denied`, async () => { @@ -139,7 +139,7 @@ describe.each([{ permission: "No" }])( ({ permission }) => { beforeAll(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get localizedAttributes and be denied`, async () => { diff --git a/tests/pagination.test.ts b/tests/pagination.test.ts index f8736bf53..87888f17d 100644 --- a/tests/pagination.test.ts +++ b/tests/pagination.test.ts @@ -84,7 +84,7 @@ describe.each([{ permission: "Search" }])( ({ permission }) => { beforeEach(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get pagination and be denied`, async () => { @@ -115,7 +115,7 @@ describe.each([{ permission: "No" }])( ({ permission }) => { beforeAll(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get pagination and be denied`, async () => { diff --git a/tests/prefix_search_settings.test.ts b/tests/prefix_search_settings.test.ts index 77685c5fc..438b5cfe4 100644 --- a/tests/prefix_search_settings.test.ts +++ b/tests/prefix_search_settings.test.ts @@ -59,7 +59,7 @@ describe.each([{ permission: "Search" }])( beforeEach(async () => { await clearAllIndexes(config); const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get prefix search settings and be denied`, async () => { @@ -91,7 +91,7 @@ describe.each([{ permission: "No" }])( beforeEach(async () => { await clearAllIndexes(config); const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get prefix search settings and be denied`, async () => { diff --git a/tests/search.test.ts b/tests/search.test.ts index 76611c04a..9062df860 100644 --- a/tests/search.test.ts +++ b/tests/search.test.ts @@ -126,8 +126,8 @@ describe.each([ beforeAll(async () => { await clearAllIndexes(config); const client = await getClient("Master"); - await client.createIndex(index.uid); - await client.createIndex(emptyIndex.uid); + await client.createIndex({ uid: index.uid }); + await client.createIndex({ uid: emptyIndex.uid }); const newFilterableAttributes = ["genre", "title", "id", "author"]; await client @@ -292,7 +292,7 @@ describe.each([ const masterClient = await getClient("Master"); // Setup to have a new "movies" index - await masterClient.createIndex("movies"); + await masterClient.createIndex({ uid: "movies" }); const newFilterableAttributes = ["title", "id"]; await masterClient .index("movies") @@ -370,7 +370,7 @@ describe.each([ const masterClient = await getClient("Master"); // Setup to have a new "movies" index - await masterClient.createIndex("movies"); + await masterClient.createIndex({ uid: "movies" }); const newFilterableAttributes = ["title", "id"]; await masterClient .index("movies") @@ -1247,7 +1247,7 @@ describe.each([ test(`${permission} key: Try to search on deleted index and fail`, async () => { const client = await getClient(permission); const masterClient = await getClient("Master"); - await masterClient.index(index.uid).delete().waitTask(); + await masterClient.deleteIndex(index.uid).waitTask(); await expect( client.index(index.uid).search("prince", {}), @@ -1260,7 +1260,7 @@ describe.each([{ permission: "No" }])( ({ permission }) => { beforeAll(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: Try Basic search and be denied`, async () => { @@ -1289,7 +1289,7 @@ describe.each([{ permission: "Master" }])( beforeEach(async () => { await clearAllIndexes(config); const client = await getClient("Master"); - await client.createIndex(index.uid); + await client.createIndex({ uid: index.uid }); await client.index(index.uid).addDocuments(datasetWithNests).waitTask(); }); @@ -1363,7 +1363,7 @@ describe.each([ beforeAll(async () => { const client = await getClient("Master"); await clearAllIndexes(config); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: search on index and abort`, async () => { diff --git a/tests/search_cutoff_ms.test.ts b/tests/search_cutoff_ms.test.ts index 7c96faa04..4fdbbe825 100644 --- a/tests/search_cutoff_ms.test.ts +++ b/tests/search_cutoff_ms.test.ts @@ -101,7 +101,7 @@ describe.each([{ permission: "Search" }])( ({ permission }) => { beforeEach(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get searchCutoffMs and be denied`, async () => { @@ -132,7 +132,7 @@ describe.each([{ permission: "No" }])( ({ permission }) => { beforeAll(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get searchCutoffMs and be denied`, async () => { diff --git a/tests/searchable_attributes.test.ts b/tests/searchable_attributes.test.ts index 8a1b1030f..421506cab 100644 --- a/tests/searchable_attributes.test.ts +++ b/tests/searchable_attributes.test.ts @@ -78,7 +78,7 @@ describe.each([{ permission: "Search" }])( ({ permission }) => { beforeEach(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get searchable attributes and be denied`, async () => { @@ -109,7 +109,7 @@ describe.each([{ permission: "No" }])( ({ permission }) => { beforeAll(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get searchable attributes and be denied`, async () => { diff --git a/tests/sortable_attributes.test.ts b/tests/sortable_attributes.test.ts index 814c7f7f0..acdcdaefb 100644 --- a/tests/sortable_attributes.test.ts +++ b/tests/sortable_attributes.test.ts @@ -29,7 +29,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( ({ permission }) => { beforeEach(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); await client.index(index.uid).addDocuments(dataset).waitTask(); }); @@ -79,7 +79,7 @@ describe.each([{ permission: "Search" }])( ({ permission }) => { beforeEach(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get sortable attributes and be denied`, async () => { @@ -110,7 +110,7 @@ describe.each([{ permission: "No" }])( ({ permission }) => { beforeAll(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: try to get sortable attributes and be denied`, async () => { diff --git a/tests/task.test.ts b/tests/task.test.ts index 2032e9747..b939ff608 100644 --- a/tests/task.test.ts +++ b/tests/task.test.ts @@ -31,7 +31,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( ({ permission }) => { beforeEach(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); test(`${permission} key: Get one enqueued task`, async () => { @@ -92,7 +92,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( const client = await getClient(permission); await client.index(index.uid).addDocuments([{ id: 1 }]); await client.index(index.uid).deleteDocument(1); - await client.createIndex(index2.uid); + await client.createIndex({ uid: index2.uid }); const tasks = await client.tasks.getTasks({ types: ["documentAdditionOrUpdate", "documentDeletion"], diff --git a/tests/token.test.ts b/tests/token.test.ts index 349c95037..eb10776d2 100644 --- a/tests/token.test.ts +++ b/tests/token.test.ts @@ -83,7 +83,7 @@ describe.each([{ permission: "Admin" }])( ({ permission }) => { beforeEach(async () => { const client = await getClient("Master"); - await client.index(UID).delete(); + await client.deleteIndex(UID).waitTask(); await client.index(UID).addDocuments(dataset).waitTask(); const keys = await client.getKeys(); diff --git a/tests/typed_search.test.ts b/tests/typed_search.test.ts index a34381989..7cc2e586d 100644 --- a/tests/typed_search.test.ts +++ b/tests/typed_search.test.ts @@ -113,8 +113,8 @@ describe.each([ const client = await getClient("Master"); await clearAllIndexes(config); - await client.createIndex(index.uid).waitTask(); - await client.createIndex(emptyIndex.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); + await client.createIndex({ uid: emptyIndex.uid }).waitTask(); const newFilterableAttributes = ["genre", "title"]; await client @@ -393,7 +393,7 @@ describe.each([ test(`${permission} key: Try to Search on deleted index and fail`, async () => { const client = await getClient(permission); const masterClient = await getClient("Master"); - await masterClient.index(index.uid).delete().waitTask(); + await masterClient.deleteIndex(index.uid).waitTask(); await expect( client.index(index.uid).search("prince"), @@ -407,7 +407,7 @@ describe.each([{ permission: "Master" }])( beforeEach(async () => { await clearAllIndexes(config); const client = await getClient("Master"); - await client.createIndex(index.uid); + await client.createIndex({ uid: index.uid }); await client.index(index.uid).addDocuments(datasetWithNests).waitTask(); }); diff --git a/tests/utils/meilisearch-test-utils.ts b/tests/utils/meilisearch-test-utils.ts index 39fc66b2b..be71afdfc 100644 --- a/tests/utils/meilisearch-test-utils.ts +++ b/tests/utils/meilisearch-test-utils.ts @@ -79,12 +79,10 @@ async function getClient(permission: string): Promise { const clearAllIndexes = async (config: Config): Promise => { const client = new MeiliSearch(config); - const { results } = await client.getRawIndexes(); + const { results } = await client.getIndexes(); await Promise.all( - results.map((v) => - client.index(v.uid).delete().waitTask({ timeout: 60_000 }), - ), + results.map((v) => client.deleteIndex(v.uid).waitTask({ timeout: 60_000 })), ); }; diff --git a/tests/wait_for_task.test.ts b/tests/wait_for_task.test.ts index 95c33ff08..52c54c4c6 100644 --- a/tests/wait_for_task.test.ts +++ b/tests/wait_for_task.test.ts @@ -19,7 +19,7 @@ describe.each([{ permission: "Master" }, { permission: "Admin" }])( ({ permission }) => { beforeEach(async () => { const client = await getClient("Master"); - await client.createIndex(index.uid).waitTask(); + await client.createIndex({ uid: index.uid }).waitTask(); }); // Client Wait for task From ade4dbaf7bec52f106e3e62b664d29fe3538134e Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Tue, 8 Apr 2025 18:25:10 +0300 Subject: [PATCH 03/20] Remove unneeded property --- src/indexes.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/indexes.ts b/src/indexes.ts index 6e59ba496..fd984858c 100644 --- a/src/indexes.ts +++ b/src/indexes.ts @@ -58,7 +58,6 @@ import { export class Index { uid: string; - primaryKey: string | undefined; httpRequest: HttpRequests; tasks: TaskClient; readonly #httpRequestsWithTask: HttpRequestsWithEnqueuedTaskPromise; @@ -68,9 +67,8 @@ export class Index { * @param uid - UID of the index * @param primaryKey - Primary Key of the index */ - constructor(config: Config, uid: string, primaryKey?: string) { + constructor(config: Config, uid: string) { this.uid = uid; - this.primaryKey = primaryKey; this.httpRequest = new HttpRequests(config); this.tasks = new TaskClient(this.httpRequest, config.defaultWaitOptions); this.#httpRequestsWithTask = getHttpRequestsWithEnqueuedTaskPromise( From 396745c441e078a945367ae154aa3411aea1620b Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Tue, 8 Apr 2025 18:27:01 +0300 Subject: [PATCH 04/20] Misc fixes --- tests/env/typescript-node/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/env/typescript-node/src/index.ts b/tests/env/typescript-node/src/index.ts index c8c3539d8..bb209f7d7 100644 --- a/tests/env/typescript-node/src/index.ts +++ b/tests/env/typescript-node/src/index.ts @@ -28,7 +28,7 @@ const indexUid = "movies" ;(async () => { await client.deleteIndex(indexUid).waitTask() - await client.createIndex({uid:indexUid}).waitTask() + await client.createIndex({ uid:indexUid }).waitTask() const index = client.index(indexUid) const indexes = await client.getIndexes() @@ -62,5 +62,5 @@ const indexUid = "movies" console.log(await generateTenantToken({ apiKey: config.apiKey, apiKeyUid: 'e489fe16-3381-431b-bee3-00430192915d' })) - await index.delete() + await client.deleteIndex(indexUid).waitTask() })() From 5a79a0b33ae47dbae22c6ae9a245e50214e82cb0 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Tue, 8 Apr 2025 21:23:51 +0300 Subject: [PATCH 05/20] Add ability to use Index instance instead of uid, misc --- src/indexes.ts | 164 +++++++++--------- src/meilisearch.ts | 26 +-- src/types/index.ts | 2 +- .../{task_and_batch.ts => task-and-batch.ts} | 19 +- src/types/types.ts | 2 +- 5 files changed, 112 insertions(+), 101 deletions(-) rename src/types/{task_and_batch.ts => task-and-batch.ts} (97%) diff --git a/src/indexes.ts b/src/indexes.ts index fd984858c..d96a9593d 100644 --- a/src/indexes.ts +++ b/src/indexes.ts @@ -57,7 +57,11 @@ import { } from "./task.js"; export class Index { - uid: string; + readonly #uid: string; + get uid() { + return this.#uid; + } + httpRequest: HttpRequests; tasks: TaskClient; readonly #httpRequestsWithTask: HttpRequestsWithEnqueuedTaskPromise; @@ -68,7 +72,7 @@ export class Index { * @param primaryKey - Primary Key of the index */ constructor(config: Config, uid: string) { - this.uid = uid; + this.#uid = uid; this.httpRequest = new HttpRequests(config); this.tasks = new TaskClient(this.httpRequest, config.defaultWaitOptions); this.#httpRequestsWithTask = getHttpRequestsWithEnqueuedTaskPromise( @@ -95,7 +99,7 @@ export class Index { extraRequestInit?: ExtraRequestInit, ): Promise> { return await this.httpRequest.post>({ - path: `indexes/${this.uid}/search`, + path: `indexes/${this.#uid}/search`, body: { q: query, ...options }, extraRequestInit, }); @@ -141,7 +145,7 @@ export class Index { }; return await this.httpRequest.get>({ - path: `indexes/${this.uid}/search`, + path: `indexes/${this.#uid}/search`, params: getParams, extraRequestInit, }); @@ -159,7 +163,7 @@ export class Index { extraRequestInit?: ExtraRequestInit, ): Promise { return await this.httpRequest.post({ - path: `indexes/${this.uid}/facet-search`, + path: `indexes/${this.#uid}/facet-search`, body: params, extraRequestInit, }); @@ -176,7 +180,7 @@ export class Index { S extends SearchParams = SearchParams, >(params: SearchSimilarDocumentsParams): Promise> { return await this.httpRequest.post>({ - path: `indexes/${this.uid}/similar`, + path: `indexes/${this.#uid}/similar`, body: params, }); } @@ -192,7 +196,7 @@ export class Index { */ async getStats(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/stats`, + path: `indexes/${this.#uid}/stats`, }); } @@ -210,7 +214,7 @@ export class Index { async getDocuments( params?: DocumentsQuery, ): Promise> { - const relativeBaseURL = `indexes/${this.uid}/documents`; + const relativeBaseURL = `indexes/${this.#uid}/documents`; return params?.filter !== undefined ? // In case `filter` is provided, use `POST /documents/fetch` @@ -241,7 +245,7 @@ export class Index { : undefined; return await this.httpRequest.get({ - path: `indexes/${this.uid}/documents/${documentId}`, + path: `indexes/${this.#uid}/documents/${documentId}`, params: { ...parameters, fields }, }); } @@ -255,7 +259,7 @@ export class Index { */ addDocuments(documents: T[], options?: DocumentOptions): EnqueuedTaskPromise { return this.#httpRequestsWithTask.post({ - path: `indexes/${this.uid}/documents`, + path: `indexes/${this.#uid}/documents`, params: options, body: documents, }); @@ -277,7 +281,7 @@ export class Index { queryParams?: RawDocumentAdditionOptions, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.post({ - path: `indexes/${this.uid}/documents`, + path: `indexes/${this.#uid}/documents`, body: documents, params: queryParams, contentType, @@ -320,7 +324,7 @@ export class Index { options?: DocumentOptions, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/documents`, + path: `indexes/${this.#uid}/documents`, params: options, body: documents, }); @@ -366,7 +370,7 @@ export class Index { queryParams?: RawDocumentAdditionOptions, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/documents`, + path: `indexes/${this.#uid}/documents`, body: documents, params: queryParams, contentType, @@ -381,7 +385,7 @@ export class Index { */ deleteDocument(documentId: string | number): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/documents/${documentId}`, + path: `indexes/${this.#uid}/documents/${documentId}`, }); } @@ -407,7 +411,7 @@ export class Index { : "documents/delete-batch"; return this.#httpRequestsWithTask.post({ - path: `indexes/${this.uid}/${endpoint}`, + path: `indexes/${this.#uid}/${endpoint}`, body: params, }); } @@ -419,7 +423,7 @@ export class Index { */ deleteAllDocuments(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/documents`, + path: `indexes/${this.#uid}/documents`, }); } @@ -439,7 +443,7 @@ export class Index { options: UpdateDocumentsByFunctionOptions, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.post({ - path: `indexes/${this.uid}/documents/edit`, + path: `indexes/${this.#uid}/documents/edit`, body: options, }); } @@ -455,7 +459,7 @@ export class Index { */ async getSettings(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings`, + path: `indexes/${this.#uid}/settings`, }); } @@ -467,7 +471,7 @@ export class Index { */ updateSettings(settings: Settings): EnqueuedTaskPromise { return this.#httpRequestsWithTask.patch({ - path: `indexes/${this.uid}/settings`, + path: `indexes/${this.#uid}/settings`, body: settings, }); } @@ -479,7 +483,7 @@ export class Index { */ resetSettings(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings`, + path: `indexes/${this.#uid}/settings`, }); } @@ -494,7 +498,7 @@ export class Index { */ async getPagination(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/pagination`, + path: `indexes/${this.#uid}/settings/pagination`, }); } @@ -506,7 +510,7 @@ export class Index { */ updatePagination(pagination: PaginationSettings): EnqueuedTaskPromise { return this.#httpRequestsWithTask.patch({ - path: `indexes/${this.uid}/settings/pagination`, + path: `indexes/${this.#uid}/settings/pagination`, body: pagination, }); } @@ -518,7 +522,7 @@ export class Index { */ resetPagination(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/pagination`, + path: `indexes/${this.#uid}/settings/pagination`, }); } @@ -533,7 +537,7 @@ export class Index { */ async getSynonyms(): Promise> { return await this.httpRequest.get>({ - path: `indexes/${this.uid}/settings/synonyms`, + path: `indexes/${this.#uid}/settings/synonyms`, }); } @@ -545,7 +549,7 @@ export class Index { */ updateSynonyms(synonyms: Synonyms): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/synonyms`, + path: `indexes/${this.#uid}/settings/synonyms`, body: synonyms, }); } @@ -557,7 +561,7 @@ export class Index { */ resetSynonyms(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/synonyms`, + path: `indexes/${this.#uid}/settings/synonyms`, }); } @@ -572,7 +576,7 @@ export class Index { */ async getStopWords(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/stop-words`, + path: `indexes/${this.#uid}/settings/stop-words`, }); } @@ -584,7 +588,7 @@ export class Index { */ updateStopWords(stopWords: StopWords): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/stop-words`, + path: `indexes/${this.#uid}/settings/stop-words`, body: stopWords, }); } @@ -596,7 +600,7 @@ export class Index { */ resetStopWords(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/stop-words`, + path: `indexes/${this.#uid}/settings/stop-words`, }); } @@ -611,7 +615,7 @@ export class Index { */ async getRankingRules(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/ranking-rules`, + path: `indexes/${this.#uid}/settings/ranking-rules`, }); } @@ -624,7 +628,7 @@ export class Index { */ updateRankingRules(rankingRules: RankingRules): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/ranking-rules`, + path: `indexes/${this.#uid}/settings/ranking-rules`, body: rankingRules, }); } @@ -636,7 +640,7 @@ export class Index { */ resetRankingRules(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/ranking-rules`, + path: `indexes/${this.#uid}/settings/ranking-rules`, }); } @@ -651,7 +655,7 @@ export class Index { */ async getDistinctAttribute(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/distinct-attribute`, + path: `indexes/${this.#uid}/settings/distinct-attribute`, }); } @@ -665,7 +669,7 @@ export class Index { distinctAttribute: DistinctAttribute, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/distinct-attribute`, + path: `indexes/${this.#uid}/settings/distinct-attribute`, body: distinctAttribute, }); } @@ -677,7 +681,7 @@ export class Index { */ resetDistinctAttribute(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/distinct-attribute`, + path: `indexes/${this.#uid}/settings/distinct-attribute`, }); } @@ -692,7 +696,7 @@ export class Index { */ async getFilterableAttributes(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/filterable-attributes`, + path: `indexes/${this.#uid}/settings/filterable-attributes`, }); } @@ -707,7 +711,7 @@ export class Index { filterableAttributes: FilterableAttributes, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/filterable-attributes`, + path: `indexes/${this.#uid}/settings/filterable-attributes`, body: filterableAttributes, }); } @@ -719,7 +723,7 @@ export class Index { */ resetFilterableAttributes(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/filterable-attributes`, + path: `indexes/${this.#uid}/settings/filterable-attributes`, }); } @@ -734,7 +738,7 @@ export class Index { */ async getSortableAttributes(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/sortable-attributes`, + path: `indexes/${this.#uid}/settings/sortable-attributes`, }); } @@ -749,7 +753,7 @@ export class Index { sortableAttributes: SortableAttributes, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/sortable-attributes`, + path: `indexes/${this.#uid}/settings/sortable-attributes`, body: sortableAttributes, }); } @@ -761,7 +765,7 @@ export class Index { */ resetSortableAttributes(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/sortable-attributes`, + path: `indexes/${this.#uid}/settings/sortable-attributes`, }); } @@ -776,7 +780,7 @@ export class Index { */ async getSearchableAttributes(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/searchable-attributes`, + path: `indexes/${this.#uid}/settings/searchable-attributes`, }); } @@ -791,7 +795,7 @@ export class Index { searchableAttributes: SearchableAttributes, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/searchable-attributes`, + path: `indexes/${this.#uid}/settings/searchable-attributes`, body: searchableAttributes, }); } @@ -803,7 +807,7 @@ export class Index { */ resetSearchableAttributes(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/searchable-attributes`, + path: `indexes/${this.#uid}/settings/searchable-attributes`, }); } @@ -818,7 +822,7 @@ export class Index { */ async getDisplayedAttributes(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/displayed-attributes`, + path: `indexes/${this.#uid}/settings/displayed-attributes`, }); } @@ -833,7 +837,7 @@ export class Index { displayedAttributes: DisplayedAttributes, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/displayed-attributes`, + path: `indexes/${this.#uid}/settings/displayed-attributes`, body: displayedAttributes, }); } @@ -845,7 +849,7 @@ export class Index { */ resetDisplayedAttributes(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/displayed-attributes`, + path: `indexes/${this.#uid}/settings/displayed-attributes`, }); } @@ -860,7 +864,7 @@ export class Index { */ async getTypoTolerance(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/typo-tolerance`, + path: `indexes/${this.#uid}/settings/typo-tolerance`, }); } @@ -873,7 +877,7 @@ export class Index { */ updateTypoTolerance(typoTolerance: TypoTolerance): EnqueuedTaskPromise { return this.#httpRequestsWithTask.patch({ - path: `indexes/${this.uid}/settings/typo-tolerance`, + path: `indexes/${this.#uid}/settings/typo-tolerance`, body: typoTolerance, }); } @@ -885,7 +889,7 @@ export class Index { */ resetTypoTolerance(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/typo-tolerance`, + path: `indexes/${this.#uid}/settings/typo-tolerance`, }); } @@ -900,7 +904,7 @@ export class Index { */ async getFaceting(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/faceting`, + path: `indexes/${this.#uid}/settings/faceting`, }); } @@ -912,7 +916,7 @@ export class Index { */ updateFaceting(faceting: Faceting): EnqueuedTaskPromise { return this.#httpRequestsWithTask.patch({ - path: `indexes/${this.uid}/settings/faceting`, + path: `indexes/${this.#uid}/settings/faceting`, body: faceting, }); } @@ -924,7 +928,7 @@ export class Index { */ resetFaceting(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/faceting`, + path: `indexes/${this.#uid}/settings/faceting`, }); } @@ -939,7 +943,7 @@ export class Index { */ async getSeparatorTokens(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/separator-tokens`, + path: `indexes/${this.#uid}/settings/separator-tokens`, }); } @@ -951,7 +955,7 @@ export class Index { */ updateSeparatorTokens(separatorTokens: SeparatorTokens): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/separator-tokens`, + path: `indexes/${this.#uid}/settings/separator-tokens`, body: separatorTokens, }); } @@ -963,7 +967,7 @@ export class Index { */ resetSeparatorTokens(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/separator-tokens`, + path: `indexes/${this.#uid}/settings/separator-tokens`, }); } @@ -978,7 +982,7 @@ export class Index { */ async getNonSeparatorTokens(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/non-separator-tokens`, + path: `indexes/${this.#uid}/settings/non-separator-tokens`, }); } @@ -992,7 +996,7 @@ export class Index { nonSeparatorTokens: NonSeparatorTokens, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/non-separator-tokens`, + path: `indexes/${this.#uid}/settings/non-separator-tokens`, body: nonSeparatorTokens, }); } @@ -1004,7 +1008,7 @@ export class Index { */ resetNonSeparatorTokens(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/non-separator-tokens`, + path: `indexes/${this.#uid}/settings/non-separator-tokens`, }); } @@ -1019,7 +1023,7 @@ export class Index { */ async getDictionary(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/dictionary`, + path: `indexes/${this.#uid}/settings/dictionary`, }); } @@ -1031,7 +1035,7 @@ export class Index { */ updateDictionary(dictionary: Dictionary): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/dictionary`, + path: `indexes/${this.#uid}/settings/dictionary`, body: dictionary, }); } @@ -1043,7 +1047,7 @@ export class Index { */ resetDictionary(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/dictionary`, + path: `indexes/${this.#uid}/settings/dictionary`, }); } @@ -1058,7 +1062,7 @@ export class Index { */ async getProximityPrecision(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/proximity-precision`, + path: `indexes/${this.#uid}/settings/proximity-precision`, }); } @@ -1073,7 +1077,7 @@ export class Index { proximityPrecision: ProximityPrecision, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/proximity-precision`, + path: `indexes/${this.#uid}/settings/proximity-precision`, body: proximityPrecision, }); } @@ -1085,7 +1089,7 @@ export class Index { */ resetProximityPrecision(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/proximity-precision`, + path: `indexes/${this.#uid}/settings/proximity-precision`, }); } @@ -1100,7 +1104,7 @@ export class Index { */ async getEmbedders(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/embedders`, + path: `indexes/${this.#uid}/settings/embedders`, }); } @@ -1112,7 +1116,7 @@ export class Index { */ updateEmbedders(embedders: Embedders): EnqueuedTaskPromise { return this.#httpRequestsWithTask.patch({ - path: `indexes/${this.uid}/settings/embedders`, + path: `indexes/${this.#uid}/settings/embedders`, body: embedders, }); } @@ -1124,7 +1128,7 @@ export class Index { */ resetEmbedders(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/embedders`, + path: `indexes/${this.#uid}/settings/embedders`, }); } @@ -1139,7 +1143,7 @@ export class Index { */ async getSearchCutoffMs(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/search-cutoff-ms`, + path: `indexes/${this.#uid}/settings/search-cutoff-ms`, }); } @@ -1151,7 +1155,7 @@ export class Index { */ updateSearchCutoffMs(searchCutoffMs: SearchCutoffMs): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/search-cutoff-ms`, + path: `indexes/${this.#uid}/settings/search-cutoff-ms`, body: searchCutoffMs, }); } @@ -1163,7 +1167,7 @@ export class Index { */ resetSearchCutoffMs(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/search-cutoff-ms`, + path: `indexes/${this.#uid}/settings/search-cutoff-ms`, }); } @@ -1178,7 +1182,7 @@ export class Index { */ async getLocalizedAttributes(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/localized-attributes`, + path: `indexes/${this.#uid}/settings/localized-attributes`, }); } @@ -1192,7 +1196,7 @@ export class Index { localizedAttributes: LocalizedAttributes, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/localized-attributes`, + path: `indexes/${this.#uid}/settings/localized-attributes`, body: localizedAttributes, }); } @@ -1204,7 +1208,7 @@ export class Index { */ resetLocalizedAttributes(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/localized-attributes`, + path: `indexes/${this.#uid}/settings/localized-attributes`, }); } @@ -1219,7 +1223,7 @@ export class Index { */ async getFacetSearch(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/facet-search`, + path: `indexes/${this.#uid}/settings/facet-search`, }); } @@ -1231,7 +1235,7 @@ export class Index { */ updateFacetSearch(facetSearch: boolean): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/facet-search`, + path: `indexes/${this.#uid}/settings/facet-search`, body: facetSearch, }); } @@ -1243,7 +1247,7 @@ export class Index { */ resetFacetSearch(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/facet-search`, + path: `indexes/${this.#uid}/settings/facet-search`, }); } @@ -1258,7 +1262,7 @@ export class Index { */ async getPrefixSearch(): Promise { return await this.httpRequest.get({ - path: `indexes/${this.uid}/settings/prefix-search`, + path: `indexes/${this.#uid}/settings/prefix-search`, }); } @@ -1270,7 +1274,7 @@ export class Index { */ updatePrefixSearch(prefixSearch: PrefixSearch): EnqueuedTaskPromise { return this.#httpRequestsWithTask.put({ - path: `indexes/${this.uid}/settings/prefix-search`, + path: `indexes/${this.#uid}/settings/prefix-search`, body: prefixSearch, }); } @@ -1282,7 +1286,7 @@ export class Index { */ resetPrefixSearch(): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${this.uid}/settings/prefix-search`, + path: `indexes/${this.#uid}/settings/prefix-search`, }); } } diff --git a/src/meilisearch.ts b/src/meilisearch.ts index 951d6951e..69d1deefe 100644 --- a/src/meilisearch.ts +++ b/src/meilisearch.ts @@ -37,7 +37,13 @@ import { type HttpRequestsWithEnqueuedTaskPromise, } from "./task.js"; import { BatchClient } from "./batch.js"; -import type { MeiliSearchApiError } from "./errors/meilisearch-api-error.js"; +import type { MeiliSearchApiError } from "./errors/index.js"; + +type UidOrIndex = Index | string; + +function getUid(value: UidOrIndex): string { + return typeof value === "string" ? value : value.uid; +} export class MeiliSearch { config: Config; @@ -87,9 +93,9 @@ export class MeiliSearch { } /** {@link https://www.meilisearch.com/docs/reference/api/indexes#get-one-index} */ - async getIndex(indexUid: string): Promise { + async getIndex(uidOrIndex: UidOrIndex): Promise { return await this.httpRequest.get({ - path: `indexes/${indexUid}`, + path: `indexes/${getUid(uidOrIndex)}`, }); } @@ -111,19 +117,19 @@ export class MeiliSearch { /** {@link https://www.meilisearch.com/docs/reference/api/indexes#update-an-index} */ updateIndex( - indexUid: string, + uidOrIndex: UidOrIndex, updateIndexRequest?: UpdateIndexRequest, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.patch({ - path: `indexes/${indexUid}`, + path: `indexes/${getUid(uidOrIndex)}`, body: updateIndexRequest, }); } /** {@link https://www.meilisearch.com/docs/reference/api/indexes#delete-an-index} */ - deleteIndex(indexUid: string): EnqueuedTaskPromise { + deleteIndex(uidOrIndex: UidOrIndex): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${indexUid}`, + path: `indexes/${getUid(uidOrIndex)}`, }); } @@ -131,13 +137,13 @@ export class MeiliSearch { * Deletes an index. In case it does not exist, this function will not throw. * Otherwise it's the same as {@link MeiliSearch.deleteIndex}. * - * @param uid - The UID of the index + * @param uidOrIndex - The UID of the index * @returns A promise that resolves to false if index does not exist, * otherwise to true. */ - async deleteIndexIfExists(uid: string): Promise { + async deleteIndexIfExists(uidOrIndex: UidOrIndex): Promise { try { - await this.deleteIndex(uid); + await this.deleteIndex(uidOrIndex); return true; } catch (error) { if ((error as MeiliSearchApiError)?.cause?.code === "index_not_found") { diff --git a/src/types/index.ts b/src/types/index.ts index a68fb0bc5..7ae247de2 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,4 +1,4 @@ export * from "./indexes.js"; -export * from "./task_and_batch.js"; +export * from "./task-and-batch.js"; export * from "./token.js"; export * from "./types.js"; diff --git a/src/types/task_and_batch.ts b/src/types/task-and-batch.ts similarity index 97% rename from src/types/task_and_batch.ts rename to src/types/task-and-batch.ts index 0ef561478..1ac4ee92e 100644 --- a/src/types/task_and_batch.ts +++ b/src/types/task-and-batch.ts @@ -1,5 +1,4 @@ import type { Settings, MeiliSearchErrorResponse } from "./types.js"; -import type { PaginationView } from "./shared.js"; import type { SwapIndexesPayload } from "./indexes.js"; /** Options for awaiting {@link EnqueuedTask}. */ @@ -139,19 +138,21 @@ export type EnqueuedTaskPromise = Promise & { waitTask: (waitOptions?: WaitOptions) => Promise; }; -/** - * {@link https://www.meilisearch.com/docs/reference/api/tasks#response} - * - * @see `meilisearch::routes::tasks::AllTasks` at {@link https://github.com/meilisearch/meilisearch} - */ -export type TasksResults = { - results: Task[]; +type Results = { + results: T[]; total: number; limit: number; from: number | null; next: number | null; }; +/** + * {@link https://www.meilisearch.com/docs/reference/api/tasks#response} + * + * @see `meilisearch::routes::tasks::AllTasks` at {@link https://github.com/meilisearch/meilisearch} + */ +export type TasksResults = Results; + /** {@link https://www.meilisearch.com/docs/reference/api/batches#steps} */ type BatchProgressStep = { currentStep: string; @@ -193,4 +194,4 @@ export type Batch = { * * @see `meilisearch::routes::batches::AllBatches` at {@link https://github.com/meilisearch/meilisearch} */ -export type BatchesResults = PaginationView; +export type BatchesResults = Results; diff --git a/src/types/types.ts b/src/types/types.ts index fc09ea57f..839056cb7 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -4,7 +4,7 @@ // Definitions: https://github.com/meilisearch/meilisearch-js // TypeScript Version: ^5.8.2 -import type { WaitOptions } from "./task_and_batch.js"; +import type { WaitOptions } from "./task-and-batch.js"; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type RecordAny = Record; From 546ae0fe43315ac18636ebfece97cf7425ea3f35 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Tue, 8 Apr 2025 21:40:11 +0300 Subject: [PATCH 06/20] Fix tests --- tests/env/browser/index.html | 4 ++-- tests/env/express/public/headers.html | 2 +- tests/env/express/public/index.html | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/env/browser/index.html b/tests/env/browser/index.html index 933050d4b..fd8f3676d 100644 --- a/tests/env/browser/index.html +++ b/tests/env/browser/index.html @@ -27,7 +27,7 @@ await client.index(UID).addDocuments([{ id: 1, title: "wonder woman" }]).waitTask() - const index = await client.index(UID).getRawInfo() + const index = await client.getIndex(UID) // Create dynamic element to wait on with puppeteer const indexDiv = document.createElement("div"); @@ -41,7 +41,7 @@ searchDiv.innerHTML = JSON.stringify(search) document.body.insertBefore(searchDiv, document.querySelector("#content")); - await client.index(UID).delete().waitTask() + await client.deleteIndex(UID).waitTask() } catch (e) { console.error(e); } diff --git a/tests/env/express/public/headers.html b/tests/env/express/public/headers.html index 58d4a96e3..eccb98f0d 100644 --- a/tests/env/express/public/headers.html +++ b/tests/env/express/public/headers.html @@ -40,7 +40,7 @@ errorDiv.innerHTML = error document.body.insertBefore(errorDiv, document.querySelector("#content")); - await client.index(UID).delete().waitTask() + await client.deleteIndex(UID).waitTask() })() diff --git a/tests/env/express/public/index.html b/tests/env/express/public/index.html index 32dad5380..76ec9e51b 100644 --- a/tests/env/express/public/index.html +++ b/tests/env/express/public/index.html @@ -30,7 +30,7 @@ await client.index(UID).addDocuments([{ id: 1, title: "wonder woman" }]).waitTask() - const index = await client.index(UID).getRawInfo() + const index = await client.getIndex(UID) // Create dynamic element to wait on with puppeteer const indexDiv = document.createElement("div"); @@ -48,6 +48,6 @@ } searchDiv.innerHTML = content document.body.insertBefore(searchDiv, document.querySelector("#content")); - await client.index(UID).delete().waitTask() + await client.deleteIndex(UID).waitTask() })() From 915e7e4557ff61c717837bdb6d24ed44ac7d158d Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Tue, 8 Apr 2025 21:47:29 +0300 Subject: [PATCH 07/20] Fix tests --- tests/env/browser/index.html | 2 +- tests/env/express/public/headers.html | 2 +- tests/env/express/public/index.html | 2 +- tests/env/node/search_example.cjs | 2 +- tests/env/typescript-node/src/index.ts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/env/browser/index.html b/tests/env/browser/index.html index fd8f3676d..4cbd37572 100644 --- a/tests/env/browser/index.html +++ b/tests/env/browser/index.html @@ -23,7 +23,7 @@ host: 'http://localhost:7700', apiKey: 'masterKey', }) - await client.createIndex(UID).waitTask() + await client.createIndex({ uid: UID }).waitTask() await client.index(UID).addDocuments([{ id: 1, title: "wonder woman" }]).waitTask() diff --git a/tests/env/express/public/headers.html b/tests/env/express/public/headers.html index eccb98f0d..cae08115c 100644 --- a/tests/env/express/public/headers.html +++ b/tests/env/express/public/headers.html @@ -23,7 +23,7 @@ let error = 'NO ERRORS' try { - await client.createIndex(UID).waitTask() + await client.createIndex({ uid: UID }).waitTask() await fetch(`http://localhost:7700/indexes/${UID}/documents`, { method: 'POST', headers: { diff --git a/tests/env/express/public/index.html b/tests/env/express/public/index.html index 76ec9e51b..776d5f052 100644 --- a/tests/env/express/public/index.html +++ b/tests/env/express/public/index.html @@ -26,7 +26,7 @@ const UID = "testIndex" try { - await client.createIndex(UID).waitTask() + await client.createIndex({ uid: UID }).waitTask() await client.index(UID).addDocuments([{ id: 1, title: "wonder woman" }]).waitTask() diff --git a/tests/env/node/search_example.cjs b/tests/env/node/search_example.cjs index ed84b227c..dd05a9372 100644 --- a/tests/env/node/search_example.cjs +++ b/tests/env/node/search_example.cjs @@ -11,7 +11,7 @@ const indexUid = 'movies' const addDataset = async () => { await client.deleteIndex(indexUid) - await client.createIndex(indexUid).waitTask() + await client.createIndex({ uid: indexUid }).waitTask() const index = client.index(indexUid) diff --git a/tests/env/typescript-node/src/index.ts b/tests/env/typescript-node/src/index.ts index bb209f7d7..94f0a5ce3 100644 --- a/tests/env/typescript-node/src/index.ts +++ b/tests/env/typescript-node/src/index.ts @@ -28,7 +28,7 @@ const indexUid = "movies" ;(async () => { await client.deleteIndex(indexUid).waitTask() - await client.createIndex({ uid:indexUid }).waitTask() + await client.createIndex({ uid: indexUid }).waitTask() const index = client.index(indexUid) const indexes = await client.getIndexes() From 7e0324f4eebf1df753e2765e7e1b8152e38254cc Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Wed, 9 Apr 2025 10:01:45 +0300 Subject: [PATCH 08/20] Adjust code and documentation --- .code-samples.meilisearch.yaml | 6 ++-- README.md | 54 ++++------------------------------ src/meilisearch.ts | 38 ++++++++++++------------ src/types/types.ts | 7 ++++- tests/index.test.ts | 8 +++++ tests/stats.test.ts | 3 ++ 6 files changed, 44 insertions(+), 72 deletions(-) create mode 100644 tests/stats.test.ts diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 84676a78c..1ca7b1a0b 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -24,11 +24,11 @@ date_guide_sort_1: |- sort: ['release_timestamp:desc'], }) get_one_index_1: |- - client.index('movies').getRawInfo() + client.getIndex('movies') list_all_indexes_1: |- client.getIndexes({ limit: 3 }) create_an_index_1: |- - client.createIndex('movies', { primaryKey: 'id' }) + client.createIndex({ uid: 'movies', primaryKey: 'id' }) update_an_index_1: |- client.updateIndex('movies', { primaryKey: 'id' }) delete_an_index_1: |- @@ -406,7 +406,7 @@ primary_field_guide_update_document_primary_key: |- primaryKey: 'title' }) primary_field_guide_create_index_primary_key: |- - client.createIndex('books', { primaryKey: 'reference_number' }) + client.createIndex({ uid: 'books', primaryKey: 'reference_number' }) primary_field_guide_add_document_primary_key: |- client.index('books').addDocuments([ { diff --git a/README.md b/README.md index 3d5e3441f..45f77af34 100644 --- a/README.md +++ b/README.md @@ -592,23 +592,17 @@ client.getBatches(parameters: BatchesQuery = {}): Promise ### Indexes -#### [Get all indexes in Index instances](https://www.meilisearch.com/docs/reference/api/indexes#list-all-indexes) - -```ts -client.getIndexes(parameters: IndexesQuery): Promise> -``` - #### [Get all indexes](https://www.meilisearch.com/docs/reference/api/indexes#list-all-indexes) ```ts -client.getRawIndexes(parameters: IndexesQuery): Promise> +client.getIndexes(listIndexes?: ListIndexes): Promise ``` #### [Create a new index](https://www.meilisearch.com/docs/reference/api/indexes#create-an-index) ```ts -client.createIndex(uid: string, options?: IndexOptions): Promise +client.createIndex(indexCreateRequest: IndexCreateRequest): EnqueuedTaskPromise ``` #### Create a local reference to an index @@ -617,48 +611,22 @@ client.createIndex(uid: string, options?: IndexOptions): Promise(uid: string): Index ``` -#### [Get an index instance completed with information fetched from Meilisearch](https://www.meilisearch.com/docs/reference/api/indexes#get-one-index) - -```ts -client.getIndex(uid: string): Promise> -``` - #### [Get the raw index JSON response from Meilisearch](https://www.meilisearch.com/docs/reference/api/indexes#get-one-index) ```ts -client.getRawIndex(uid: string): Promise -``` - -#### [Get an object with information about the index](https://www.meilisearch.com/docs/reference/api/indexes#get-one-index) - -```ts -client.index('myIndex').getRawInfo(): Promise +client.getIndex(uidOrIndex: UidOrIndex): Promise ``` #### [Update Index](https://www.meilisearch.com/docs/reference/api/indexes#update-an-index) -##### Using the client - -```ts -client.updateIndex(uid: string, options: IndexOptions): Promise -``` - -##### Using the index object - ```ts -client.index('myIndex').update(data: IndexOptions): Promise +client.updateIndex(uidOrIndex: UidOrIndex, updateIndexRequest?: UpdateIndexRequest): EnqueuedTaskPromise ``` #### [Delete index](https://www.meilisearch.com/docs/reference/api/indexes#delete-an-index) -##### Using the client ```ts -client.deleteIndex(uid): Promise -``` - -##### Using the index object -```ts -client.index('myIndex').delete(): Promise +client.deleteIndex(uidOrIndex: UidOrIndex): EnqueuedTaskPromise ``` #### [Get specific index stats](https://www.meilisearch.com/docs/reference/api/stats#get-stats-of-an-index) @@ -667,18 +635,6 @@ client.index('myIndex').delete(): Promise client.index('myIndex').getStats(): Promise ``` -##### Return Index instance with updated information - -```ts -client.index('myIndex').fetchInfo(): Promise -``` - -##### Get Primary Key of an Index - -```ts -client.index('myIndex').fetchPrimaryKey(): Promise -``` - ##### Swap two indexes ```ts diff --git a/src/meilisearch.ts b/src/meilisearch.ts index 69d1deefe..0a1953fba 100644 --- a/src/meilisearch.ts +++ b/src/meilisearch.ts @@ -29,6 +29,7 @@ import type { IndexView, IndexCreateRequest, UpdateIndexRequest, + ConditionalIndexDeleteResult as SafeIndexDeletionResult, } from "./types/index.js"; import { HttpRequests } from "./http-requests.js"; import { @@ -37,13 +38,7 @@ import { type HttpRequestsWithEnqueuedTaskPromise, } from "./task.js"; import { BatchClient } from "./batch.js"; -import type { MeiliSearchApiError } from "./errors/index.js"; - -type UidOrIndex = Index | string; - -function getUid(value: UidOrIndex): string { - return typeof value === "string" ? value : value.uid; -} +import { MeiliSearchApiError } from "./errors/index.js"; export class MeiliSearch { config: Config; @@ -93,9 +88,9 @@ export class MeiliSearch { } /** {@link https://www.meilisearch.com/docs/reference/api/indexes#get-one-index} */ - async getIndex(uidOrIndex: UidOrIndex): Promise { + async getIndex(indexUid: string): Promise { return await this.httpRequest.get({ - path: `indexes/${getUid(uidOrIndex)}`, + path: `indexes/${indexUid}`, }); } @@ -117,19 +112,19 @@ export class MeiliSearch { /** {@link https://www.meilisearch.com/docs/reference/api/indexes#update-an-index} */ updateIndex( - uidOrIndex: UidOrIndex, + indexUid: string, updateIndexRequest?: UpdateIndexRequest, ): EnqueuedTaskPromise { return this.#httpRequestsWithTask.patch({ - path: `indexes/${getUid(uidOrIndex)}`, + path: `indexes/${indexUid}`, body: updateIndexRequest, }); } /** {@link https://www.meilisearch.com/docs/reference/api/indexes#delete-an-index} */ - deleteIndex(uidOrIndex: UidOrIndex): EnqueuedTaskPromise { + deleteIndex(indexUid: string): EnqueuedTaskPromise { return this.#httpRequestsWithTask.delete({ - path: `indexes/${getUid(uidOrIndex)}`, + path: `indexes/${indexUid}`, }); } @@ -137,17 +132,22 @@ export class MeiliSearch { * Deletes an index. In case it does not exist, this function will not throw. * Otherwise it's the same as {@link MeiliSearch.deleteIndex}. * - * @param uidOrIndex - The UID of the index + * @param indexUid - The UID of the index * @returns A promise that resolves to false if index does not exist, * otherwise to true. */ - async deleteIndexIfExists(uidOrIndex: UidOrIndex): Promise { + async deleteIndexIfExists( + indexUid: string, + ): Promise { try { - await this.deleteIndex(uidOrIndex); - return true; + const value = await this.deleteIndex(indexUid).waitTask(); + return { success: true, value }; } catch (error) { - if ((error as MeiliSearchApiError)?.cause?.code === "index_not_found") { - return false; + if ( + error instanceof MeiliSearchApiError && + error.cause?.code === "index_not_found" + ) { + return { success: false, value: error }; } throw error; diff --git a/src/types/types.ts b/src/types/types.ts index 839056cb7..b3254bca9 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -4,7 +4,8 @@ // Definitions: https://github.com/meilisearch/meilisearch-js // TypeScript Version: ^5.8.2 -import type { WaitOptions } from "./task-and-batch.js"; +import type { MeiliSearchApiError } from "../errors/index.js"; +import type { Task, WaitOptions } from "./task-and-batch.js"; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type RecordAny = Record; @@ -1081,3 +1082,7 @@ export const ErrorStatusCode = { export type ErrorStatusCode = (typeof ErrorStatusCode)[keyof typeof ErrorStatusCode]; + +export type ConditionalIndexDeleteResult = + | { success: true; value: Task } + | { success: false; value: MeiliSearchApiError }; diff --git a/tests/index.test.ts b/tests/index.test.ts index da2b83b10..aba2f7ac1 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -9,6 +9,7 @@ const client = await getClient("Master"); test.concurrent("index method", () => { const myIndex = client.index(MY_INDEX_ONE); assert.instanceOf(myIndex, Index); + assert.strictEqual(myIndex.uid, MY_INDEX_ONE); }); afterAll(async () => { @@ -81,3 +82,10 @@ test("swapIndexes method", async () => { { details: { swaps }, type: "indexSwap" }, ); }); + +test("deleteIndexIfExists method where index doesn't exist", async () => { + const result = await client.deleteIndexIfExists( + "57b78d25-8c88-4ffb-b16e-d16485edc76a", + ); + assert.isFalse(result.success); +}); diff --git a/tests/stats.test.ts b/tests/stats.test.ts new file mode 100644 index 000000000..ca095f997 --- /dev/null +++ b/tests/stats.test.ts @@ -0,0 +1,3 @@ +import { test } from "vitest"; + +test.todo("index stats"); From a88d39e876ae8dad07cf918d9c06d854a807554c Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Wed, 9 Apr 2025 10:14:18 +0300 Subject: [PATCH 09/20] Remove misconceived function --- playgrounds/javascript/src/meilisearch.ts | 2 +- src/meilisearch.ts | 28 ----------------------- src/types/types.ts | 7 +----- tests/index.test.ts | 11 ++------- vite.config.ts | 2 +- 5 files changed, 5 insertions(+), 45 deletions(-) diff --git a/playgrounds/javascript/src/meilisearch.ts b/playgrounds/javascript/src/meilisearch.ts index 63a7c62d5..22e4fcdde 100644 --- a/playgrounds/javascript/src/meilisearch.ts +++ b/playgrounds/javascript/src/meilisearch.ts @@ -10,7 +10,7 @@ const index = client.index<{ id: number; title: string; genres: string[] }>( ); export async function addDocuments(): Promise { - await client.deleteIndexIfExists(indexUid); + await client.deleteIndex(indexUid).waitTask(); await client.createIndex({ uid: indexUid }).waitTask(); diff --git a/src/meilisearch.ts b/src/meilisearch.ts index 0a1953fba..85e516a21 100644 --- a/src/meilisearch.ts +++ b/src/meilisearch.ts @@ -29,7 +29,6 @@ import type { IndexView, IndexCreateRequest, UpdateIndexRequest, - ConditionalIndexDeleteResult as SafeIndexDeletionResult, } from "./types/index.js"; import { HttpRequests } from "./http-requests.js"; import { @@ -38,7 +37,6 @@ import { type HttpRequestsWithEnqueuedTaskPromise, } from "./task.js"; import { BatchClient } from "./batch.js"; -import { MeiliSearchApiError } from "./errors/index.js"; export class MeiliSearch { config: Config; @@ -128,32 +126,6 @@ export class MeiliSearch { }); } - /** - * Deletes an index. In case it does not exist, this function will not throw. - * Otherwise it's the same as {@link MeiliSearch.deleteIndex}. - * - * @param indexUid - The UID of the index - * @returns A promise that resolves to false if index does not exist, - * otherwise to true. - */ - async deleteIndexIfExists( - indexUid: string, - ): Promise { - try { - const value = await this.deleteIndex(indexUid).waitTask(); - return { success: true, value }; - } catch (error) { - if ( - error instanceof MeiliSearchApiError && - error.cause?.code === "index_not_found" - ) { - return { success: false, value: error }; - } - - throw error; - } - } - /** {@link https://www.meilisearch.com/docs/reference/api/indexes#swap-indexes} */ swapIndexes(swapIndexesPayloads: SwapIndexesPayload[]): EnqueuedTaskPromise { return this.#httpRequestsWithTask.post({ diff --git a/src/types/types.ts b/src/types/types.ts index b3254bca9..839056cb7 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -4,8 +4,7 @@ // Definitions: https://github.com/meilisearch/meilisearch-js // TypeScript Version: ^5.8.2 -import type { MeiliSearchApiError } from "../errors/index.js"; -import type { Task, WaitOptions } from "./task-and-batch.js"; +import type { WaitOptions } from "./task-and-batch.js"; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type RecordAny = Record; @@ -1082,7 +1081,3 @@ export const ErrorStatusCode = { export type ErrorStatusCode = (typeof ErrorStatusCode)[keyof typeof ErrorStatusCode]; - -export type ConditionalIndexDeleteResult = - | { success: true; value: Task } - | { success: false; value: MeiliSearchApiError }; diff --git a/tests/index.test.ts b/tests/index.test.ts index aba2f7ac1..03e9a0537 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -14,8 +14,8 @@ test.concurrent("index method", () => { afterAll(async () => { await Promise.all([ - client.deleteIndexIfExists(MY_INDEX_ONE), - client.deleteIndexIfExists(MY_INDEX_TWO), + client.deleteIndex(MY_INDEX_ONE).waitTask(), + client.deleteIndex(MY_INDEX_TWO).waitTask(), ]); }); @@ -82,10 +82,3 @@ test("swapIndexes method", async () => { { details: { swaps }, type: "indexSwap" }, ); }); - -test("deleteIndexIfExists method where index doesn't exist", async () => { - const result = await client.deleteIndexIfExists( - "57b78d25-8c88-4ffb-b16e-d16485edc76a", - ); - assert.isFalse(result.success); -}); diff --git a/vite.config.ts b/vite.config.ts index 461eae93d..f9b849804 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -55,7 +55,7 @@ export default defineConfig(({ mode }) => { }, }, test: { - include: ["tests/**/*.test.ts"], + include: ["tests/**/index.test.ts"], exclude: ["tests/env/**"], fileParallelism: false, testTimeout: 100_000, // 100 seconds From 83864bc7bd74e5619e7333d23bbbe7e4d4c6858c Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Wed, 9 Apr 2025 10:17:30 +0300 Subject: [PATCH 10/20] Whoops --- vite.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vite.config.ts b/vite.config.ts index f9b849804..461eae93d 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -55,7 +55,7 @@ export default defineConfig(({ mode }) => { }, }, test: { - include: ["tests/**/index.test.ts"], + include: ["tests/**/*.test.ts"], exclude: ["tests/env/**"], fileParallelism: false, testTimeout: 100_000, // 100 seconds From 93ff6cf4bb4b563989532db354ee6334992557e8 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Wed, 9 Apr 2025 10:24:04 +0300 Subject: [PATCH 11/20] Adjust doc --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 45f77af34..074d2ffe3 100644 --- a/README.md +++ b/README.md @@ -614,19 +614,19 @@ client.index(uid: string): Index #### [Get the raw index JSON response from Meilisearch](https://www.meilisearch.com/docs/reference/api/indexes#get-one-index) ```ts -client.getIndex(uidOrIndex: UidOrIndex): Promise +client.getIndex(uid: string): Promise ``` #### [Update Index](https://www.meilisearch.com/docs/reference/api/indexes#update-an-index) ```ts -client.updateIndex(uidOrIndex: UidOrIndex, updateIndexRequest?: UpdateIndexRequest): EnqueuedTaskPromise +client.updateIndex(uid: string, updateIndexRequest?: UpdateIndexRequest): EnqueuedTaskPromise ``` #### [Delete index](https://www.meilisearch.com/docs/reference/api/indexes#delete-an-index) ```ts -client.deleteIndex(uidOrIndex: UidOrIndex): EnqueuedTaskPromise +client.deleteIndex(uid: string): EnqueuedTaskPromise ``` #### [Get specific index stats](https://www.meilisearch.com/docs/reference/api/stats#get-stats-of-an-index) From c0a56cda6c243c8fc6e5a7257dfa35de7499bf9a Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Wed, 9 Apr 2025 12:29:31 +0300 Subject: [PATCH 12/20] Add test for index stats --- tests/index-stats.test.ts | 25 +++++++++++++++++++++++++ tests/stats.test.ts | 3 --- 2 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 tests/index-stats.test.ts delete mode 100644 tests/stats.test.ts diff --git a/tests/index-stats.test.ts b/tests/index-stats.test.ts new file mode 100644 index 000000000..33fd22a84 --- /dev/null +++ b/tests/index-stats.test.ts @@ -0,0 +1,25 @@ +import { afterAll, expect, test } from "vitest"; +import { getClient } from "./utils/meilisearch-test-utils.js"; + +const INDEX_UID = "stats-index"; +const client = await getClient("Master"); + +afterAll(async () => { + await client.deleteIndex(INDEX_UID).waitTask(); +}); + +test("getStats method", async () => { + await client.createIndex({ uid: INDEX_UID }).waitTask(); + const stats = await client.index(INDEX_UID).getStats(); + expect(stats).toMatchInlineSnapshot(` + { + "avgDocumentSize": 0, + "fieldDistribution": {}, + "isIndexing": false, + "numberOfDocuments": 0, + "numberOfEmbeddedDocuments": 0, + "numberOfEmbeddings": 0, + "rawDocumentDbSize": 0, + } + `); +}); diff --git a/tests/stats.test.ts b/tests/stats.test.ts deleted file mode 100644 index ca095f997..000000000 --- a/tests/stats.test.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { test } from "vitest"; - -test.todo("index stats"); From ef5ddd13d09da0a22e4be422f63530de18448422 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Wed, 9 Apr 2025 18:11:39 +0300 Subject: [PATCH 13/20] Improve test --- tests/index.test.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/index.test.ts b/tests/index.test.ts index 03e9a0537..0111f49f3 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -51,8 +51,18 @@ test("updateIndex method", async () => { }); test("deleteIndex method", async () => { - const task = await client.deleteIndex(MY_INDEX_ONE).waitTask(); - assert.strictEqual(task.status, "succeeded"); + const { indexUid, status, type } = await client + .deleteIndex(MY_INDEX_ONE) + .waitTask(); + + assert.deepEqual( + { indexUid, status, type }, + { + indexUid: MY_INDEX_ONE, + status: "succeeded", + type: "indexDeletion", + }, + ); }); test("swapIndexes method", async () => { From 8867e7691babe9f5acaa041d923cef26923ea4e7 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Fri, 11 Apr 2025 11:07:03 +0300 Subject: [PATCH 14/20] Move methods requiring index uid param to Index class --- .code-samples.meilisearch.yaml | 8 +++---- README.md | 6 ++--- playgrounds/javascript/src/meilisearch.ts | 2 +- src/indexes.ts | 24 ++++++++++++++++++++ src/meilisearch.ts | 27 ----------------------- tests/documents.test.ts | 12 +++++----- tests/env/browser/index.html | 2 +- tests/env/express/public/headers.html | 2 +- tests/env/express/public/index.html | 2 +- tests/env/node/search_example.cjs | 2 +- tests/env/typescript-node/src/index.ts | 4 ++-- tests/get_search.test.ts | 2 +- tests/index-stats.test.ts | 2 +- tests/index.test.ts | 21 +++++++++--------- tests/search.test.ts | 2 +- tests/token.test.ts | 2 +- tests/typed_search.test.ts | 2 +- tests/utils/meilisearch-test-utils.ts | 4 +++- 18 files changed, 62 insertions(+), 64 deletions(-) diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 1ca7b1a0b..5c1d9aed9 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -24,15 +24,15 @@ date_guide_sort_1: |- sort: ['release_timestamp:desc'], }) get_one_index_1: |- - client.getIndex('movies') + client.index('movies').getIndex() list_all_indexes_1: |- client.getIndexes({ limit: 3 }) create_an_index_1: |- client.createIndex({ uid: 'movies', primaryKey: 'id' }) update_an_index_1: |- - client.updateIndex('movies', { primaryKey: 'id' }) + client.index('movies').updateIndex({ primaryKey: 'id' }) delete_an_index_1: |- - client.deleteIndex('movies') + client.index('movies').deleteIndex() swap_indexes_1: |- client.swapIndexes([ { 'indexes': ['indexA', 'indexB'] }, @@ -402,7 +402,7 @@ add_movies_json_1: |- const movies = require('./movies.json') client.index('movies').addDocuments(movies).then((res) => console.log(res)) primary_field_guide_update_document_primary_key: |- - client.updateIndex('books', { + client.index('books').updateIndex({ primaryKey: 'title' }) primary_field_guide_create_index_primary_key: |- diff --git a/README.md b/README.md index 074d2ffe3..ffb8caa71 100644 --- a/README.md +++ b/README.md @@ -614,19 +614,19 @@ client.index(uid: string): Index #### [Get the raw index JSON response from Meilisearch](https://www.meilisearch.com/docs/reference/api/indexes#get-one-index) ```ts -client.getIndex(uid: string): Promise +client.index(uid: string).getIndex(): Promise ``` #### [Update Index](https://www.meilisearch.com/docs/reference/api/indexes#update-an-index) ```ts -client.updateIndex(uid: string, updateIndexRequest?: UpdateIndexRequest): EnqueuedTaskPromise +client.index(uid: string).updateIndex(updateIndexRequest?: UpdateIndexRequest): EnqueuedTaskPromise ``` #### [Delete index](https://www.meilisearch.com/docs/reference/api/indexes#delete-an-index) ```ts -client.deleteIndex(uid: string): EnqueuedTaskPromise +client.index(uid: string).deleteIndex(): EnqueuedTaskPromise ``` #### [Get specific index stats](https://www.meilisearch.com/docs/reference/api/stats#get-stats-of-an-index) diff --git a/playgrounds/javascript/src/meilisearch.ts b/playgrounds/javascript/src/meilisearch.ts index 22e4fcdde..4af579f61 100644 --- a/playgrounds/javascript/src/meilisearch.ts +++ b/playgrounds/javascript/src/meilisearch.ts @@ -10,7 +10,7 @@ const index = client.index<{ id: number; title: string; genres: string[] }>( ); export async function addDocuments(): Promise { - await client.deleteIndex(indexUid).waitTask(); + await client.index(indexUid).deleteIndex().waitTask(); await client.createIndex({ uid: indexUid }).waitTask(); diff --git a/src/indexes.ts b/src/indexes.ts index d96a9593d..026b758ed 100644 --- a/src/indexes.ts +++ b/src/indexes.ts @@ -48,6 +48,8 @@ import type { PrefixSearch, RecordAny, EnqueuedTaskPromise, + IndexView, + UpdateIndexRequest, } from "./types/index.js"; import { HttpRequests } from "./http-requests.js"; import { @@ -185,6 +187,28 @@ export class Index { }); } + /// + /// INDEX + /// + + /** {@link https://www.meilisearch.com/docs/reference/api/indexes#get-one-index} */ + async getIndex(): Promise { + return await this.httpRequest.get({ path: `indexes/${this.#uid}` }); + } + + /** {@link https://www.meilisearch.com/docs/reference/api/indexes#update-an-index} */ + updateIndex(updateIndexRequest?: UpdateIndexRequest): EnqueuedTaskPromise { + return this.#httpRequestsWithTask.patch({ + path: `indexes/${this.#uid}`, + body: updateIndexRequest, + }); + } + + /** {@link https://www.meilisearch.com/docs/reference/api/indexes#delete-an-index} */ + deleteIndex(): EnqueuedTaskPromise { + return this.#httpRequestsWithTask.delete({ path: `indexes/${this.#uid}` }); + } + /// /// STATS /// diff --git a/src/meilisearch.ts b/src/meilisearch.ts index 85e516a21..02c6df843 100644 --- a/src/meilisearch.ts +++ b/src/meilisearch.ts @@ -26,9 +26,7 @@ import type { RecordAny, IndexViewList, ListIndexes, - IndexView, IndexCreateRequest, - UpdateIndexRequest, } from "./types/index.js"; import { HttpRequests } from "./http-requests.js"; import { @@ -85,13 +83,6 @@ export class MeiliSearch { return new Index(this.config, indexUid); } - /** {@link https://www.meilisearch.com/docs/reference/api/indexes#get-one-index} */ - async getIndex(indexUid: string): Promise { - return await this.httpRequest.get({ - path: `indexes/${indexUid}`, - }); - } - /** {@link https://www.meilisearch.com/docs/reference/api/indexes#list-all-indexes} */ async getIndexes(listIndexes?: ListIndexes): Promise { return await this.httpRequest.get({ @@ -108,24 +99,6 @@ export class MeiliSearch { }); } - /** {@link https://www.meilisearch.com/docs/reference/api/indexes#update-an-index} */ - updateIndex( - indexUid: string, - updateIndexRequest?: UpdateIndexRequest, - ): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.patch({ - path: `indexes/${indexUid}`, - body: updateIndexRequest, - }); - } - - /** {@link https://www.meilisearch.com/docs/reference/api/indexes#delete-an-index} */ - deleteIndex(indexUid: string): EnqueuedTaskPromise { - return this.#httpRequestsWithTask.delete({ - path: `indexes/${indexUid}`, - }); - } - /** {@link https://www.meilisearch.com/docs/reference/api/indexes#swap-indexes} */ swapIndexes(swapIndexesPayloads: SwapIndexesPayload[]): EnqueuedTaskPromise { return this.#httpRequestsWithTask.post({ diff --git a/tests/documents.test.ts b/tests/documents.test.ts index add7aa1c6..e32f76861 100644 --- a/tests/documents.test.ts +++ b/tests/documents.test.ts @@ -399,7 +399,7 @@ describe("Documents tests", () => { }; await client.index(indexNoPk.uid).addDocuments([doc]).waitTask(); - const index = await client.getIndex(indexNoPk.uid); + const index = await client.index(indexNoPk.uid).getIndex(); expect(index).toHaveProperty("primaryKey", "_id"); }); @@ -412,7 +412,7 @@ describe("Documents tests", () => { }; await client.index(indexNoPk.uid).addDocuments([doc]).waitTask(); - const index = await client.getIndex(indexNoPk.uid); + const index = await client.index(indexNoPk.uid).getIndex(); expect(index).toHaveProperty("primaryKey", "findmeid"); }); @@ -428,7 +428,7 @@ describe("Documents tests", () => { .index(indexNoPk.uid) .addDocuments([doc]) .waitTask(); - const index = await client.getIndex(indexNoPk.uid); + const index = await client.index(indexNoPk.uid).getIndex(); expect(task.error?.code).toEqual( "index_primary_key_multiple_candidates_found", @@ -446,7 +446,7 @@ describe("Documents tests", () => { .index(indexNoPk.uid) .addDocuments([doc]) .waitTask(); - const index = await client.getIndex(indexNoPk.uid); + const index = await client.index(indexNoPk.uid).getIndex(); expect(task.error?.code).toEqual( "index_primary_key_no_candidate_found", @@ -623,7 +623,7 @@ describe("Documents tests", () => { .addDocuments(docs, { primaryKey: "unique" }) .waitTask(); - const response = await client.getIndex(pkIndex); + const response = await client.index(pkIndex).getIndex(); expect(response).toHaveProperty("uid", pkIndex); expect(response).toHaveProperty("primaryKey", "unique"); }); @@ -659,7 +659,7 @@ describe("Documents tests", () => { ]) .waitTask(); - const index = await client.getIndex(indexNoPk.uid); + const index = await client.index(indexNoPk.uid).getIndex(); expect(index.uid).toEqual(indexNoPk.uid); expect(index.primaryKey).toEqual(null); diff --git a/tests/env/browser/index.html b/tests/env/browser/index.html index 4cbd37572..bb10292bc 100644 --- a/tests/env/browser/index.html +++ b/tests/env/browser/index.html @@ -41,7 +41,7 @@ searchDiv.innerHTML = JSON.stringify(search) document.body.insertBefore(searchDiv, document.querySelector("#content")); - await client.deleteIndex(UID).waitTask() + await client.index(UID).deleteIndex().waitTask() } catch (e) { console.error(e); } diff --git a/tests/env/express/public/headers.html b/tests/env/express/public/headers.html index cae08115c..c79999229 100644 --- a/tests/env/express/public/headers.html +++ b/tests/env/express/public/headers.html @@ -40,7 +40,7 @@ errorDiv.innerHTML = error document.body.insertBefore(errorDiv, document.querySelector("#content")); - await client.deleteIndex(UID).waitTask() + await client.index(UID).deleteIndex().waitTask() })() diff --git a/tests/env/express/public/index.html b/tests/env/express/public/index.html index 776d5f052..66d764d39 100644 --- a/tests/env/express/public/index.html +++ b/tests/env/express/public/index.html @@ -48,6 +48,6 @@ } searchDiv.innerHTML = content document.body.insertBefore(searchDiv, document.querySelector("#content")); - await client.deleteIndex(UID).waitTask() + await client.index(UID).deleteIndex().waitTask() })() diff --git a/tests/env/node/search_example.cjs b/tests/env/node/search_example.cjs index dd05a9372..0a5283a9f 100644 --- a/tests/env/node/search_example.cjs +++ b/tests/env/node/search_example.cjs @@ -10,7 +10,7 @@ const client = new MeiliSearch(config) const indexUid = 'movies' const addDataset = async () => { - await client.deleteIndex(indexUid) + await client.index(indexUid).deleteIndex() await client.createIndex({ uid: indexUid }).waitTask() const index = client.index(indexUid) diff --git a/tests/env/typescript-node/src/index.ts b/tests/env/typescript-node/src/index.ts index 94f0a5ce3..07b57e952 100644 --- a/tests/env/typescript-node/src/index.ts +++ b/tests/env/typescript-node/src/index.ts @@ -27,7 +27,7 @@ const client = new MeiliSearch(config) const indexUid = "movies" ;(async () => { - await client.deleteIndex(indexUid).waitTask() + await client.index(indexUid).deleteIndex().waitTask() await client.createIndex({ uid: indexUid }).waitTask() const index = client.index(indexUid) @@ -62,5 +62,5 @@ const indexUid = "movies" console.log(await generateTenantToken({ apiKey: config.apiKey, apiKeyUid: 'e489fe16-3381-431b-bee3-00430192915d' })) - await client.deleteIndex(indexUid).waitTask() + await client.index(indexUid).deleteIndex().waitTask() })() diff --git a/tests/get_search.test.ts b/tests/get_search.test.ts index 02a242a6f..ccbaa43cd 100644 --- a/tests/get_search.test.ts +++ b/tests/get_search.test.ts @@ -546,7 +546,7 @@ describe.each([ test(`${permission} key: Try to search on deleted index and fail`, async () => { const client = await getClient(permission); const masterClient = await getClient("Master"); - await masterClient.deleteIndex(index.uid).waitTask(); + await masterClient.index(index.uid).deleteIndex().waitTask(); await expect( client.index(index.uid).searchGet("prince"), ).rejects.toHaveProperty("cause.code", ErrorStatusCode.INDEX_NOT_FOUND); diff --git a/tests/index-stats.test.ts b/tests/index-stats.test.ts index 33fd22a84..b986ea04f 100644 --- a/tests/index-stats.test.ts +++ b/tests/index-stats.test.ts @@ -5,7 +5,7 @@ const INDEX_UID = "stats-index"; const client = await getClient("Master"); afterAll(async () => { - await client.deleteIndex(INDEX_UID).waitTask(); + await client.index(INDEX_UID).deleteIndex().waitTask(); }); test("getStats method", async () => { diff --git a/tests/index.test.ts b/tests/index.test.ts index 0111f49f3..e5f3549d3 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -14,8 +14,8 @@ test.concurrent("index method", () => { afterAll(async () => { await Promise.all([ - client.deleteIndex(MY_INDEX_ONE).waitTask(), - client.deleteIndex(MY_INDEX_TWO).waitTask(), + client.index(MY_INDEX_ONE).deleteIndex().waitTask(), + client.index(MY_INDEX_TWO).deleteIndex().waitTask(), ]); }); @@ -23,8 +23,9 @@ test("createIndex and getIndex method", async () => { const primaryKey = "objectID"; await client.createIndex({ uid: MY_INDEX_ONE, primaryKey }).waitTask(); - const { createdAt, updatedAt, ...myIndex } = - await client.getIndex(MY_INDEX_ONE); + const { createdAt, updatedAt, ...myIndex } = await client + .index(MY_INDEX_ONE) + .getIndex(); assert.deepEqual(myIndex, { primaryKey, @@ -36,13 +37,10 @@ test("createIndex and getIndex method", async () => { test("updateIndex method", async () => { const primaryKey = "id"; - await client.updateIndex(MY_INDEX_ONE, { primaryKey }).waitTask(); + const index = client.index(MY_INDEX_ONE); + await index.updateIndex({ primaryKey }).waitTask(); - const { - createdAt: _ca, - updatedAt: _ua, - ...myIndex - } = await client.getIndex(MY_INDEX_ONE); + const { createdAt: _ca, updatedAt: _ua, ...myIndex } = await index.getIndex(); assert.deepEqual(myIndex, { primaryKey, @@ -52,7 +50,8 @@ test("updateIndex method", async () => { test("deleteIndex method", async () => { const { indexUid, status, type } = await client - .deleteIndex(MY_INDEX_ONE) + .index(MY_INDEX_ONE) + .deleteIndex() .waitTask(); assert.deepEqual( diff --git a/tests/search.test.ts b/tests/search.test.ts index 9062df860..1f9847c7a 100644 --- a/tests/search.test.ts +++ b/tests/search.test.ts @@ -1247,7 +1247,7 @@ describe.each([ test(`${permission} key: Try to search on deleted index and fail`, async () => { const client = await getClient(permission); const masterClient = await getClient("Master"); - await masterClient.deleteIndex(index.uid).waitTask(); + await masterClient.index(index.uid).deleteIndex().waitTask(); await expect( client.index(index.uid).search("prince", {}), diff --git a/tests/token.test.ts b/tests/token.test.ts index eb10776d2..bd410dfdf 100644 --- a/tests/token.test.ts +++ b/tests/token.test.ts @@ -83,7 +83,7 @@ describe.each([{ permission: "Admin" }])( ({ permission }) => { beforeEach(async () => { const client = await getClient("Master"); - await client.deleteIndex(UID).waitTask(); + await client.index(UID).deleteIndex().waitTask(); await client.index(UID).addDocuments(dataset).waitTask(); const keys = await client.getKeys(); diff --git a/tests/typed_search.test.ts b/tests/typed_search.test.ts index 7cc2e586d..d2d9502ae 100644 --- a/tests/typed_search.test.ts +++ b/tests/typed_search.test.ts @@ -393,7 +393,7 @@ describe.each([ test(`${permission} key: Try to Search on deleted index and fail`, async () => { const client = await getClient(permission); const masterClient = await getClient("Master"); - await masterClient.deleteIndex(index.uid).waitTask(); + await masterClient.index(index.uid).deleteIndex().waitTask(); await expect( client.index(index.uid).search("prince"), diff --git a/tests/utils/meilisearch-test-utils.ts b/tests/utils/meilisearch-test-utils.ts index be71afdfc..57ec8ee9f 100644 --- a/tests/utils/meilisearch-test-utils.ts +++ b/tests/utils/meilisearch-test-utils.ts @@ -82,7 +82,9 @@ const clearAllIndexes = async (config: Config): Promise => { const { results } = await client.getIndexes(); await Promise.all( - results.map((v) => client.deleteIndex(v.uid).waitTask({ timeout: 60_000 })), + results.map((v) => + client.index(v.uid).deleteIndex().waitTask({ timeout: 60_000 }), + ), ); }; From a6fd0060b8a32f3982e739263984e2c3394bf6c0 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Fri, 11 Apr 2025 11:17:06 +0300 Subject: [PATCH 15/20] Attempt to fix tests --- tests/env/browser/index.html | 2 +- tests/env/express/public/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/env/browser/index.html b/tests/env/browser/index.html index bb10292bc..9a40ccb49 100644 --- a/tests/env/browser/index.html +++ b/tests/env/browser/index.html @@ -27,7 +27,7 @@ await client.index(UID).addDocuments([{ id: 1, title: "wonder woman" }]).waitTask() - const index = await client.getIndex(UID) + const index = await client.index(UID).getIndex() // Create dynamic element to wait on with puppeteer const indexDiv = document.createElement("div"); diff --git a/tests/env/express/public/index.html b/tests/env/express/public/index.html index 66d764d39..4c451dacd 100644 --- a/tests/env/express/public/index.html +++ b/tests/env/express/public/index.html @@ -30,7 +30,7 @@ await client.index(UID).addDocuments([{ id: 1, title: "wonder woman" }]).waitTask() - const index = await client.getIndex(UID) + const index = await client.index(UID).getIndex() // Create dynamic element to wait on with puppeteer const indexDiv = document.createElement("div"); From 6189297e8d836056743bea0d03d75e4d3f212d29 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Mon, 21 Apr 2025 12:29:26 +0300 Subject: [PATCH 16/20] Minor adjustments --- tests/index.test.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/index.test.ts b/tests/index.test.ts index e5f3549d3..6778bbedc 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -2,25 +2,26 @@ import { test, afterAll } from "vitest"; import { getClient, assert } from "./utils/meilisearch-test-utils.js"; import { Index, type SwapIndexesPayload } from "../src/index.js"; -const MY_INDEX_ONE = "my-index-one"; -const MY_INDEX_TWO = "my-index-two"; +const MY_INDEX_ONE = "c5ffe1f8-7da8-4e47-a698-d4183f98a552"; +const MY_INDEX_TWO = "8be542e9-0f24-4c72-b4e9-4a23e7e29e9d"; const client = await getClient("Master"); -test.concurrent("index method", () => { +test("index method", () => { const myIndex = client.index(MY_INDEX_ONE); assert.instanceOf(myIndex, Index); assert.strictEqual(myIndex.uid, MY_INDEX_ONE); }); afterAll(async () => { - await Promise.all([ - client.index(MY_INDEX_ONE).deleteIndex().waitTask(), - client.index(MY_INDEX_TWO).deleteIndex().waitTask(), - ]); + await Promise.all( + [MY_INDEX_ONE, MY_INDEX_TWO].map((i) => + client.index(i).deleteIndex().waitTask(), + ), + ); }); test("createIndex and getIndex method", async () => { - const primaryKey = "objectID"; + const primaryKey = "cléPrimaire"; await client.createIndex({ uid: MY_INDEX_ONE, primaryKey }).waitTask(); const { createdAt, updatedAt, ...myIndex } = await client From 3179acc7555d46024378fc9576a36a03e1b59e86 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Fri, 25 Apr 2025 13:25:43 +0300 Subject: [PATCH 17/20] Improve tests --- tests/index.test.ts | 105 ++++++++++++++------------ tests/utils/meilisearch-test-utils.ts | 6 +- 2 files changed, 60 insertions(+), 51 deletions(-) diff --git a/tests/index.test.ts b/tests/index.test.ts index 6778bbedc..a2d17193a 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -2,93 +2,98 @@ import { test, afterAll } from "vitest"; import { getClient, assert } from "./utils/meilisearch-test-utils.js"; import { Index, type SwapIndexesPayload } from "../src/index.js"; -const MY_INDEX_ONE = "c5ffe1f8-7da8-4e47-a698-d4183f98a552"; -const MY_INDEX_TWO = "8be542e9-0f24-4c72-b4e9-4a23e7e29e9d"; -const client = await getClient("Master"); +const INDEX_UID_ONE = "c5ffe1f8-7da8-4e47-a698-d4183f98a552"; +const INDEX_UID_TWO = "8be542e9-0f24-4c72-b4e9-4a23e7e29e9d"; +const ms = await getClient("Master"); +const index = ms.index(INDEX_UID_ONE); -test("index method", () => { - const myIndex = client.index(MY_INDEX_ONE); +test(`${ms.index.name} method`, () => { + const myIndex = ms.index(INDEX_UID_ONE); assert.instanceOf(myIndex, Index); - assert.strictEqual(myIndex.uid, MY_INDEX_ONE); + assert.strictEqual(myIndex.uid, INDEX_UID_ONE); }); afterAll(async () => { await Promise.all( - [MY_INDEX_ONE, MY_INDEX_TWO].map((i) => - client.index(i).deleteIndex().waitTask(), + [INDEX_UID_ONE, INDEX_UID_TWO].map((i) => + ms.index(i).deleteIndex().waitTask(), ), ); }); -test("createIndex and getIndex method", async () => { +test(`${ms.createIndex.name} and ${index.getIndex.name} method`, async () => { const primaryKey = "cléPrimaire"; - await client.createIndex({ uid: MY_INDEX_ONE, primaryKey }).waitTask(); + const task = await ms + .createIndex({ uid: INDEX_UID_ONE, primaryKey }) + .waitTask(); + + assert.isTaskSuccessful(task); + assert.strictEqual(task.indexUid, INDEX_UID_ONE); + assert.deepEqual(task.details, { primaryKey }); + assert.strictEqual(task.type, "indexCreation"); - const { createdAt, updatedAt, ...myIndex } = await client - .index(MY_INDEX_ONE) - .getIndex(); + const { createdAt, updatedAt, ...myIndex } = await index.getIndex(); assert.deepEqual(myIndex, { primaryKey, - uid: MY_INDEX_ONE, + uid: INDEX_UID_ONE, }); assert.typeOf(createdAt, "string"); assert.typeOf(updatedAt, "string"); }); -test("updateIndex method", async () => { +test(`${index.updateIndex.name} and ${index.getIndex.name} method`, async () => { const primaryKey = "id"; - const index = client.index(MY_INDEX_ONE); - await index.updateIndex({ primaryKey }).waitTask(); + const task = await index.updateIndex({ primaryKey }).waitTask(); + + assert.isTaskSuccessful(task); + assert.strictEqual(task.indexUid, INDEX_UID_ONE); + assert.deepEqual(task.details, { primaryKey }); + assert.strictEqual(task.type, "indexUpdate"); - const { createdAt: _ca, updatedAt: _ua, ...myIndex } = await index.getIndex(); + const { createdAt, updatedAt, ...myIndex } = await index.getIndex(); + + assert.typeOf(createdAt, "string"); + assert.typeOf(updatedAt, "string"); assert.deepEqual(myIndex, { primaryKey, - uid: MY_INDEX_ONE, + uid: INDEX_UID_ONE, }); }); -test("deleteIndex method", async () => { - const { indexUid, status, type } = await client - .index(MY_INDEX_ONE) - .deleteIndex() - .waitTask(); +test(`${index.deleteIndex.name} method`, async () => { + const task = await index.deleteIndex().waitTask(); - assert.deepEqual( - { indexUid, status, type }, - { - indexUid: MY_INDEX_ONE, - status: "succeeded", - type: "indexDeletion", - }, - ); + assert.isTaskSuccessful(task); + assert.strictEqual(task.indexUid, INDEX_UID_ONE); + assert.deepEqual(task.details, { deletedDocuments: 0 }); + assert.strictEqual(task.type, "indexDeletion"); }); -test("swapIndexes method", async () => { - const indexOne = client.index(MY_INDEX_ONE); - const indexTwo = client.index(MY_INDEX_TWO); +test(`${ms.swapIndexes.name} method`, async () => { + const otherIndex = ms.index(INDEX_UID_TWO); - const doc1 = { id: 1, title: "index_1" }; - const doc2 = { id: 1, title: "index_2" }; + const doc1 = { id: 1, title: "index_un" }; + const doc2 = { id: 1, title: "index_deux" }; - await indexOne.addDocuments([doc1]).waitTask(); - await indexTwo.addDocuments([doc2]).waitTask(); + await index.addDocuments([doc1]).waitTask(); + await otherIndex.addDocuments([doc2]).waitTask(); const swaps: SwapIndexesPayload[] = [ - { indexes: [MY_INDEX_ONE, MY_INDEX_TWO] }, + { indexes: [INDEX_UID_ONE, INDEX_UID_TWO] }, ]; - const task = await client.swapIndexes(swaps).waitTask(); - const docIndex1 = await indexOne.getDocument(doc2.id); - const docIndex2 = await indexTwo.getDocument(doc1.id); + const task = await ms.swapIndexes(swaps).waitTask(); - assert.deepEqual(doc1, docIndex2); - assert.deepEqual(doc2, docIndex1); + assert.isTaskSuccessful(task); + assert.strictEqual(task.indexUid, null); + assert.deepEqual(task.details, { swaps }); + assert.strictEqual(task.type, "indexSwap"); - const { type, details } = task; - assert.deepEqual( - { type, details }, - { details: { swaps }, type: "indexSwap" }, - ); + const docIndex = await index.getDocument(doc2.id); + const docOtherIndex = await otherIndex.getDocument(doc1.id); + + assert.deepEqual(doc1, docOtherIndex); + assert.deepEqual(doc2, docIndex); }); diff --git a/tests/utils/meilisearch-test-utils.ts b/tests/utils/meilisearch-test-utils.ts index 904636525..dadd88678 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, From 6612246d0fa1a5f0d0184b1b9db43f3a24ed0621 Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Fri, 25 Apr 2025 13:35:12 +0300 Subject: [PATCH 18/20] Improve tests --- tests/index-stats.test.ts | 53 +++++++++++++++++++++++++-------------- tests/index.test.ts | 7 +++--- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/tests/index-stats.test.ts b/tests/index-stats.test.ts index b986ea04f..6eca470ff 100644 --- a/tests/index-stats.test.ts +++ b/tests/index-stats.test.ts @@ -1,25 +1,40 @@ -import { afterAll, expect, test } from "vitest"; -import { getClient } from "./utils/meilisearch-test-utils.js"; +import { afterAll, test } from "vitest"; +import { assert, getClient } from "./utils/meilisearch-test-utils.js"; -const INDEX_UID = "stats-index"; -const client = await getClient("Master"); +const INDEX_UID = "7dfb3954-d408-4fb9-9cb9-acede082f650"; +const ms = await getClient("Master"); +const index = ms.index(INDEX_UID); afterAll(async () => { - await client.index(INDEX_UID).deleteIndex().waitTask(); + const task = await ms.index(INDEX_UID).deleteIndex().waitTask(); + assert.isTaskSuccessful(task); }); -test("getStats method", async () => { - await client.createIndex({ uid: INDEX_UID }).waitTask(); - const stats = await client.index(INDEX_UID).getStats(); - expect(stats).toMatchInlineSnapshot(` - { - "avgDocumentSize": 0, - "fieldDistribution": {}, - "isIndexing": false, - "numberOfDocuments": 0, - "numberOfEmbeddedDocuments": 0, - "numberOfEmbeddings": 0, - "rawDocumentDbSize": 0, - } - `); +test(`${index.getStats.name} method`, async () => { + const task = await index + .addDocuments([ + { id: 1, liberté: true }, + { id: 2, égalité: true }, + { id: 3, fraternité: true }, + ]) + .waitTask(); + + assert.isTaskSuccessful(task); + + const stats = await index.getStats(); + + assert.deepEqual(stats, { + avgDocumentSize: 1357, + fieldDistribution: { + fraternité: 1, + id: 3, + liberté: 1, + égalité: 1, + }, + isIndexing: false, + numberOfDocuments: 3, + numberOfEmbeddedDocuments: 0, + numberOfEmbeddings: 0, + rawDocumentDbSize: 4096, + }); }); diff --git a/tests/index.test.ts b/tests/index.test.ts index a2d17193a..ea65a6990 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -15,9 +15,10 @@ test(`${ms.index.name} method`, () => { afterAll(async () => { await Promise.all( - [INDEX_UID_ONE, INDEX_UID_TWO].map((i) => - ms.index(i).deleteIndex().waitTask(), - ), + [INDEX_UID_ONE, INDEX_UID_TWO].map(async (i) => { + const task = await ms.index(i).deleteIndex().waitTask(); + assert.isTaskSuccessful(task); + }), ); }); From 4219bd3a2e875f4dd7f9018d2764e4562fa8814c Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Thu, 15 May 2025 09:52:45 +0300 Subject: [PATCH 19/20] Update tests/env/node/search_example.cjs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- tests/env/node/search_example.cjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/env/node/search_example.cjs b/tests/env/node/search_example.cjs index 0a5283a9f..968a1c462 100644 --- a/tests/env/node/search_example.cjs +++ b/tests/env/node/search_example.cjs @@ -10,7 +10,7 @@ const client = new MeiliSearch(config) const indexUid = 'movies' const addDataset = async () => { - await client.index(indexUid).deleteIndex() + await client.index(indexUid).deleteIndex().waitTask() await client.createIndex({ uid: indexUid }).waitTask() const index = client.index(indexUid) From 3d980b1c4f7394f16e06c747c873a1050b1d59ec Mon Sep 17 00:00:00 2001 From: "F. Levi" <55688616+flevi29@users.noreply.github.com> Date: Mon, 19 May 2025 20:51:13 +0300 Subject: [PATCH 20/20] Use randomUUID instead of fixed UUID --- tests/index-stats.test.ts | 3 ++- tests/index.test.ts | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/index-stats.test.ts b/tests/index-stats.test.ts index 6eca470ff..22bd8ac49 100644 --- a/tests/index-stats.test.ts +++ b/tests/index-stats.test.ts @@ -1,7 +1,8 @@ +import { randomUUID } from "node:crypto"; import { afterAll, test } from "vitest"; import { assert, getClient } from "./utils/meilisearch-test-utils.js"; -const INDEX_UID = "7dfb3954-d408-4fb9-9cb9-acede082f650"; +const INDEX_UID = randomUUID(); const ms = await getClient("Master"); const index = ms.index(INDEX_UID); diff --git a/tests/index.test.ts b/tests/index.test.ts index ea65a6990..a0ea0915a 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -1,9 +1,10 @@ +import { randomUUID } from "node:crypto"; import { test, afterAll } from "vitest"; import { getClient, assert } from "./utils/meilisearch-test-utils.js"; import { Index, type SwapIndexesPayload } from "../src/index.js"; -const INDEX_UID_ONE = "c5ffe1f8-7da8-4e47-a698-d4183f98a552"; -const INDEX_UID_TWO = "8be542e9-0f24-4c72-b4e9-4a23e7e29e9d"; +const INDEX_UID_ONE = randomUUID(); +const INDEX_UID_TWO = randomUUID(); const ms = await getClient("Master"); const index = ms.index(INDEX_UID_ONE);