Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions src/meilisearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import type {
ResultsWrapper,
WebhookCreatePayload,
WebhookUpdatePayload,
UpdatableNetwork,
} from "./types/index.js";
import { ErrorStatusCode } from "./types/index.js";
import { HttpRequests } from "./http-requests.js";
Expand Down Expand Up @@ -383,11 +384,8 @@ export class MeiliSearch {
*
* @experimental
*/
async updateNetwork(network: Partial<Network>): Promise<Network> {
return await this.httpRequest.patch({
path: "network",
body: network,
});
async updateNetwork(options: UpdatableNetwork): Promise<Network> {
return await this.httpRequest.patch({ path: "network", body: options });
}

///
Expand Down
3 changes: 2 additions & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from "./experimental-features.js";
export * from "./task_and_batch.js";
export * from "./network.js";
export * from "./task-and-batch.js";
export * from "./token.js";
export * from "./types.js";
export * from "./webhooks.js";
17 changes: 17 additions & 0 deletions src/types/network.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { DeepPartial } from "./shared.js";

/** {@link https://www.meilisearch.com/docs/reference/api/network#the-remote-object} */
export type Remote = {
url: string;
searchApiKey?: string | null;
writeApiKey?: string | null;
};

/** {@link https://www.meilisearch.com/docs/reference/api/network#the-network-object} */
export type Network = {
self?: string | null;
remotes?: Record<string, Remote>;
sharding?: boolean;
};

export type UpdatableNetwork = DeepPartial<Network>;
14 changes: 4 additions & 10 deletions src/types/shared.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import type { RecordAny } from "./types.js";

export type CursorResults<T> = {
results: T[];
limit: number;
Expand All @@ -8,14 +6,10 @@ export type CursorResults<T> = {
total: number;
};

export type NonNullableDeepRecordValues<T> = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[P in keyof T]: T[P] extends any[]
? Array<NonNullableDeepRecordValues<T[P][number]>>
: T[P] extends RecordAny
? NonNullableDeepRecordValues<T[P]>
: NonNullable<T[P]>;
};
/** Deeply map every property of a record to itself making it partial. */
export type DeepPartial<T> = T extends object
? { [TKey in keyof T]?: DeepPartial<T[TKey]> }
: T;

// taken from https://stackoverflow.com/a/65642944
export type PascalToCamelCase<S extends string> = Uncapitalize<S>;
Expand Down
14 changes: 14 additions & 0 deletions src/types/task_and_batch.ts → src/types/task-and-batch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,18 @@ export type TaskDetails = Settings &
upgradeTo: string;
}>;

/** {@link https://www.meilisearch.com/docs/reference/api/tasks#network} */
type Origin = { remoteName: string; taskUid: number };

/** {@link https://www.meilisearch.com/docs/reference/api/tasks#network} */
type NetworkOrigin = { origin: Origin };

/** {@link https://www.meilisearch.com/docs/reference/api/tasks#network} */
type RemoteTask = { taskUid?: number; error: MeiliSearchErrorResponse | null };

/** {@link https://www.meilisearch.com/docs/reference/api/tasks#network} */
type NetworkRemoteTasks = { remoteTasks: Record<string, RemoteTask> };

/**
* {@link https://www.meilisearch.com/docs/reference/api/tasks#task-object}
*
Expand All @@ -150,6 +162,8 @@ export type Task = SafeOmit<EnqueuedTask, "taskUid"> & {
duration: string | null;
startedAt: string | null;
finishedAt: string | null;
/** {@link https://www.meilisearch.com/docs/reference/api/tasks#network} */
network?: NetworkOrigin | NetworkRemoteTasks;
};

/**
Expand Down
28 changes: 1 addition & 27 deletions src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, any>;
Expand Down Expand Up @@ -310,26 +310,6 @@ export type FederatedMultiSearchParams = {
queries: MultiSearchQueryWithFederation[];
};

/**
* {@link https://www.meilisearch.com/docs/reference/api/network#the-remote-object}
*
* @see `meilisearch_types::features::Remote` at {@link https://github.com/meilisearch/meilisearch}
*/
export type Remote = {
url: string;
searchApiKey: string | null;
};

/**
* {@link https://www.meilisearch.com/docs/reference/api/network#the-network-object}
*
* @see `meilisearch_types::features::Network` at {@link https://github.com/meilisearch/meilisearch}
*/
export type Network = {
self: string | null;
remotes: Record<string, Remote>;
};

export type CategoriesDistribution = {
[category: string]: number;
};
Expand Down Expand Up @@ -842,12 +822,6 @@ export type Version = {
** ERROR HANDLER
*/

export interface FetchError extends Error {
type: string;
errno: string;
code: string;
}

export type MeiliSearchErrorResponse = {
message: string;
// https://www.meilisearch.com/docs/reference/errors/error_codes
Expand Down
36 changes: 19 additions & 17 deletions tests/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ import {
type MockInstance,
beforeAll,
} from "vitest";
import type { Health, Version, Stats, IndexSwap } from "../src/index.js";
import type {
Health,
Version,
Stats,
IndexSwap,
UpdatableNetwork,
} from "../src/index.js";
import { ErrorStatusCode, MeiliSearchRequestError } from "../src/index.js";
import pkg from "../package.json" with { type: "json" };
import {
Expand Down Expand Up @@ -887,26 +893,22 @@ describe.each([{ permission: "Master" }])(
test(`${permission} key: Update and get network settings`, async () => {
const client = await getClient(permission);

const instances = {
[instanceName]: {
url: "http://instance-1:7700",
searchApiKey: "search-key-1",
const options: UpdatableNetwork = {
self: instanceName,
remotes: {
[instanceName]: {
url: "http://instance-1:7700",
searchApiKey: "search-key-1",
writeApiKey: "write-key-1",
},
},
sharding: true,
};

await client.updateNetwork({ self: instanceName, remotes: instances });
await client.updateNetwork(options);
const response = await client.getNetwork();
expect(response).toHaveProperty("self", instanceName);
expect(response).toHaveProperty("remotes");
expect(response.remotes).toHaveProperty("instance_1");
expect(response.remotes["instance_1"]).toHaveProperty(
"url",
instances[instanceName].url,
);
expect(response.remotes["instance_1"]).toHaveProperty(
"searchApiKey",
instances[instanceName].searchApiKey,
);

assert.deepEqual(response, options);
});
},
);
21 changes: 12 additions & 9 deletions tests/tasks-and-batches.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { randomUUID } from "node:crypto";
import { beforeAll, describe, test, vi } from "vitest";
import type { TasksOrBatchesQuery } from "../src/types/index.js";
import { getClient, objectEntries } from "./utils/meilisearch-test-utils.js";
import {
getClient,
objectEntries,
assert,
possibleTaskTypes,
} from "./utils/meilisearch-test-utils.js";
import {
possibleTaskStatuses,
} from "./utils/tasks-and-batches.js";
possibleTaskTypes,
} from "./utils/assertions/tasks-and-batches.js";

const INDEX_UID = randomUUID();
const ms = await getClient("Master");
Expand Down Expand Up @@ -188,11 +191,11 @@ describe.for(objectEntries(testValuesRecord))("%s", ([key, testValues]) => {
test.for(testValues)(
`${ms.tasks.getTasks.name} method%s`,
async ([, value]) => {
const { results, ...r } = await ms.tasks.getTasks({ [key]: value });
const tasksResults = await ms.tasks.getTasks({ [key]: value });

assert.isResult(r);
assert.isTasksOrBatchesResults(tasksResults);

for (const task of results) {
for (const task of tasksResults.results) {
assert.isTask(task);
}
},
Expand All @@ -201,11 +204,11 @@ describe.for(objectEntries(testValuesRecord))("%s", ([key, testValues]) => {
test.for(testValues)(
`${ms.batches.getBatches.name} method%s`,
async ([, value]) => {
const { results, ...r } = await ms.batches.getBatches({ [key]: value });
const batchesResults = await ms.batches.getBatches({ [key]: value });

assert.isResult(r);
assert.isTasksOrBatchesResults(batchesResults);

for (const batch of results) {
for (const batch of batchesResults.results) {
assert.isBatch(batch);
}
},
Expand Down
18 changes: 18 additions & 0 deletions tests/utils/assert.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { assert } from "vitest";
import { errorAssertions } from "./assertions/error.js";
import { promiseAssertions } from "./assertions/promise.js";
import { tasksAndBatchesAssertions } from "./assertions/tasks-and-batches.js";

const source = {
...errorAssertions,
...promiseAssertions,
...tasksAndBatchesAssertions,
};

const customAssert: typeof assert & typeof source = Object.assign(
assert,
source,
);

// needs to be named assert to satisfy Vitest ESLint plugin in tests
export { customAssert as assert };
12 changes: 12 additions & 0 deletions tests/utils/assertions/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { assert } from "vitest";
import type { MeiliSearchErrorResponse } from "../../../src/index.js";

export const errorAssertions = {
isErrorResponse(error: MeiliSearchErrorResponse) {
assert.lengthOf(Object.keys(error), 4);
const { message, code, type, link } = error;
for (const val of Object.values({ message, code, type, link })) {
assert.typeOf(val, "string");
}
},
};
43 changes: 43 additions & 0 deletions tests/utils/assertions/promise.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { assert } from "vitest";

const NOT_RESOLVED = Symbol("<not resolved>");
const RESOLVED = Symbol("<resolved>");

export const promiseAssertions = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async rejects<T extends { new (...args: any[]): any }>(
promise: Promise<unknown>,
errorConstructor: T,
errMsgMatcher?: RegExp | string,
): Promise<InstanceType<T>> {
let resolvedValue;

try {
resolvedValue = await promise;
} catch (error) {
assert.instanceOf(error, errorConstructor);

if (errMsgMatcher !== undefined) {
const { message } = error as Error;
if (typeof errMsgMatcher === "string") {
assert.strictEqual(message, errMsgMatcher);
} else {
assert.match(message, errMsgMatcher);
}
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return error as InstanceType<T>;
}

assert.fail(resolvedValue, NOT_RESOLVED, "expected value to not resolve");
},

async resolves(promise: Promise<unknown>): Promise<void> {
try {
await promise;
} catch (error) {
assert.fail(error, RESOLVED, "expected value to not reject");
}
},
};
Loading