diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 5370f8281..a31d7a654 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -858,3 +858,12 @@ search_parameter_reference_media_1: |- } } }) +export_post_1: |- + client.export({ + url: 'TARGET_INSTANCE_URL', + indexes: { + '*': { + overrideSettings: true + } + } + }) diff --git a/.github/workflows/meilisearch-prototype-tests.yml b/.github/workflows/meilisearch-prototype-tests.yml index 961598618..0e29e984a 100644 --- a/.github/workflows/meilisearch-prototype-tests.yml +++ b/.github/workflows/meilisearch-prototype-tests.yml @@ -44,6 +44,13 @@ jobs: MEILI_NO_ANALYTICS: 'true' ports: - '7700:7700' + export-meilisearch: + image: getmeili/meilisearch:${{ needs.meilisearch-version.outputs.version }} + env: + MEILI_MASTER_KEY: 'masterKey' + MEILI_NO_ANALYTICS: 'true' + ports: + - '7702:7700' strategy: matrix: node: ['20', '22'] diff --git a/.github/workflows/pre-release-tests.yml b/.github/workflows/pre-release-tests.yml index cc27fd8a2..905be4a9b 100644 --- a/.github/workflows/pre-release-tests.yml +++ b/.github/workflows/pre-release-tests.yml @@ -41,6 +41,13 @@ jobs: MEILI_NO_ANALYTICS: 'true' ports: - '7700:7700' + export-meilisearch: + image: getmeili/meilisearch:${{ needs.meilisearch-version.outputs.version }} + env: + MEILI_MASTER_KEY: 'masterKey' + MEILI_NO_ANALYTICS: 'true' + ports: + - '7702:7700' strategy: matrix: node: ['20', '22'] diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c154680fa..4ee53252b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,6 +33,11 @@ jobs: MEILI_NO_ANALYTICS: 'true' ports: - '7700:7700' + export-meilisearch: + image: getmeili/meilisearch:latest + env: + MEILI_MASTER_KEY: 'masterKey' + MEILI_NO_ANALYTICS: 'true' strategy: fail-fast: false matrix: diff --git a/docker-compose.yml b/docker-compose.yml index cb0c9c7dc..ccaea6d2e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,3 +20,17 @@ services: environment: - MEILI_MASTER_KEY=masterKey - MEILI_NO_ANALYTICS=true + networks: + - ms-network + + export-meilisearch: + image: getmeili/meilisearch + environment: + - MEILI_MASTER_KEY=masterKey + - MEILI_NO_ANALYTICS=true + networks: + - ms-network + +networks: + ms-network: + driver: bridge diff --git a/src/meilisearch.ts b/src/meilisearch.ts index b2e7d7527..4976b1894 100644 --- a/src/meilisearch.ts +++ b/src/meilisearch.ts @@ -34,6 +34,7 @@ import type { ResultsWrapper, WebhookCreatePayload, WebhookUpdatePayload, + ExportOptions, } from "./types/index.js"; import { ErrorStatusCode } from "./types/index.js"; import { HttpRequests } from "./http-requests.js"; @@ -547,6 +548,15 @@ export class MeiliSearch { }); } + /// + /// EXPORT + /// + + /** {@link https://www.meilisearch.com/docs/reference/api/export} */ + export(options: ExportOptions): EnqueuedTaskPromise { + return this.#httpRequestsWithTask.post({ path: "export", body: options }); + } + /// /// EXPERIMENTAL-FEATURES /// diff --git a/src/types/export.ts b/src/types/export.ts new file mode 100644 index 000000000..de839d4aa --- /dev/null +++ b/src/types/export.ts @@ -0,0 +1,30 @@ +import type { Filter } from "./types.js"; + +/** + * {@link https://www.meilisearch.com/docs/reference/api/export#indexes} + * + * @see `meilisearch::routes::export::ExportIndexSettings` + */ +export type ExportIndexSettings = { + filter?: Filter; + overrideSettings?: boolean; +}; + +/** {@link https://www.meilisearch.com/docs/reference/api/export#indexes} */ +export type ExportIndexSettingsRecord = Record; + +/** + * {@link https://www.meilisearch.com/docs/reference/api/export#body} + * + * @see `meilisearch::routes::export::Export` + */ +export type ExportOptions = { + /** {@link https://www.meilisearch.com/docs/reference/api/export#url} */ + url: string; + /** {@link https://www.meilisearch.com/docs/reference/api/export#apikey} */ + apiKey?: string; + /** {@link https://www.meilisearch.com/docs/reference/api/export#payloadsize} */ + payloadSize?: string; + /** {@link https://www.meilisearch.com/docs/reference/api/export#indexes} */ + indexes?: ExportIndexSettingsRecord; +}; diff --git a/src/types/index.ts b/src/types/index.ts index 6d744c635..01f8ef9d7 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,4 +1,5 @@ export * from "./experimental-features.js"; +export * from "./export.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 index 0c30212f6..01fc1b26c 100644 --- a/src/types/task_and_batch.ts +++ b/src/types/task_and_batch.ts @@ -52,6 +52,7 @@ export type TaskType = PascalToCamelCase< | "TaskDeletion" | "DumpCreation" | "SnapshotCreation" + | "Export" | "UpgradeDatabase" >; diff --git a/tests/export.test.ts b/tests/export.test.ts new file mode 100644 index 000000000..76909377d --- /dev/null +++ b/tests/export.test.ts @@ -0,0 +1,40 @@ +import { randomUUID } from "node:crypto"; +import { afterAll, beforeAll, test } from "vitest"; +import { assert, getClient } from "./utils/meilisearch-test-utils.js"; + +const INDEX_UID = randomUUID(); +const ms = await getClient("Master"); + +beforeAll(async () => { + const task = await ms.createIndex(INDEX_UID).waitTask(); + assert.isTaskSuccessful(task); + + const idx = ms.index(INDEX_UID); + + const task2 = await idx.updateFilterableAttributes(["beep"]).waitTask(); + assert.isTaskSuccessful(task2); + + const task3 = await idx.addDocuments([{ id: 0, beep: "boop" }]).waitTask(); + assert.isTaskSuccessful(task3); +}); + +afterAll(async () => { + const task = await ms.deleteIndex(INDEX_UID).waitTask(); + assert.isTaskSuccessful(task); +}); + +test(`${ms.export.name} method`, async () => { + const task = await ms + .export({ + url: "http://export-meilisearch:7700", + apiKey: "masterKey", + payloadSize: "50MiB", + indexes: { + [INDEX_UID]: { filter: "beep = boop", overrideSettings: true }, + }, + }) + .waitTask({ timeout: 60_000 }); + + assert.isTaskSuccessful(task); + assert.strictEqual(task.type, "export"); +}); diff --git a/tests/utils/meilisearch-test-utils.ts b/tests/utils/meilisearch-test-utils.ts index 234e502d5..b5e397565 100644 --- a/tests/utils/meilisearch-test-utils.ts +++ b/tests/utils/meilisearch-test-utils.ts @@ -155,7 +155,7 @@ const source = { }, isTask(task: Task) { const { length } = Object.keys(task); - vitestAssert(length >= 11 && length <= 12); + vitestAssert(length >= 11 && length <= 13); const { indexUid, status, @@ -199,6 +199,7 @@ const source = { taskDeletion: null, dumpCreation: null, snapshotCreation: null, + export: null, upgradeDatabase: null, }), ); diff --git a/tests/utils/tasks-and-batches.ts b/tests/utils/tasks-and-batches.ts index 79a56ae7c..f438c8de9 100644 --- a/tests/utils/tasks-and-batches.ts +++ b/tests/utils/tasks-and-batches.ts @@ -29,6 +29,7 @@ export const possibleTaskTypes = objectKeys({ taskDeletion: null, dumpCreation: null, snapshotCreation: null, + export: null, upgradeDatabase: null, });