Skip to content

Improve various types #1919

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
6 changes: 3 additions & 3 deletions src/errors/meilisearch-api-error.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { MeiliSearchErrorResponse } from "../types/index.js";
import type { ResponseError } from "../types/index.js";
import { MeiliSearchError } from "./meilisearch-error.js";

export class MeiliSearchApiError extends MeiliSearchError {
override name = "MeiliSearchApiError";
override cause?: MeiliSearchErrorResponse;
override cause?: ResponseError;
readonly response: Response;

constructor(response: Response, responseBody?: MeiliSearchErrorResponse) {
constructor(response: Response, responseBody?: ResponseError) {
super(
responseBody?.message ?? `${response.status}: ${response.statusText}`,
);
Expand Down
6 changes: 3 additions & 3 deletions src/http-requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {
RequestOptions,
MainRequestOptions,
URLSearchParamsRecord,
MeiliSearchErrorResponse,
ResponseError,
} from "./types/index.js";
import { PACKAGE_VERSION } from "./package-version.js";
import {
Expand Down Expand Up @@ -251,12 +251,12 @@ export class HttpRequests {
const parsedResponse =
responseBody === ""
? undefined
: (JSON.parse(responseBody) as T | MeiliSearchErrorResponse);
: (JSON.parse(responseBody) as T | ResponseError);

if (!response.ok) {
throw new MeiliSearchApiError(
response,
parsedResponse as MeiliSearchErrorResponse | undefined,
parsedResponse as ResponseError | undefined,
);
}

Expand Down
10 changes: 2 additions & 8 deletions src/indexes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,15 +277,9 @@ export class Index<T extends RecordAny = RecordAny> {
/// STATS
///

/**
* Get stats of an index
*
* @returns Promise containing object with stats of the index
*/
/** {@link https://www.meilisearch.com/docs/reference/api/stats#get-stats-of-an-index} */
async getStats(): Promise<IndexStats> {
return await this.httpRequest.get<IndexStats>({
path: `indexes/${this.uid}/stats`,
});
return await this.httpRequest.get({ path: `indexes/${this.uid}/stats` });
}

///
Expand Down
58 changes: 15 additions & 43 deletions src/meilisearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
IndexOptions,
IndexObject,
Key,
Health,
HealthResponse,
Stats,
Version,
VersionResponse,
KeyUpdate,
IndexesQuery,
IndexesResults,
Expand All @@ -30,7 +30,6 @@
RecordAny,
RuntimeTogglableFeatures,
} from "./types/index.js";
import { ErrorStatusCode } from "./types/index.js";
import { HttpRequests } from "./http-requests.js";
import {
getHttpRequestsWithEnqueuedTaskPromise,
Expand Down Expand Up @@ -186,10 +185,7 @@
await this.deleteIndex(uid);
return true;
} catch (e) {
if (
(e as MeiliSearchApiError)?.cause?.code ===
ErrorStatusCode.INDEX_NOT_FOUND
) {
if ((e as MeiliSearchApiError)?.cause?.code === "index_not_found") {

Check warning on line 188 in src/meilisearch.ts

View check run for this annotation

Codecov / codecov/patch

src/meilisearch.ts#L188

Added line #L188 was not covered by tests
return false;
}

Expand Down Expand Up @@ -377,13 +373,9 @@
/// HEALTH
///

/**
* Checks if the server is healthy, otherwise an error will be thrown.
*
* @returns Promise returning an object with health details
*/
async health(): Promise<Health> {
return await this.httpRequest.get<Health>({ path: "health" });
/** {@link https://www.meilisearch.com/docs/reference/api/health#get-health} */
async health(): Promise<HealthResponse> {
return await this.httpRequest.get({ path: "health" });
}

/**
Expand All @@ -404,56 +396,36 @@
/// STATS
///

/**
* Get the stats of all the database
*
* @returns Promise returning object of all the stats
*/
/** {@link https://www.meilisearch.com/docs/reference/api/stats#get-stats-of-all-indexes} */
async getStats(): Promise<Stats> {
return await this.httpRequest.get<Stats>({ path: "stats" });
return await this.httpRequest.get({ path: "stats" });
}

///
/// VERSION
///

/**
* Get the version of MeiliSearch
*
* @returns Promise returning object with version details
*/
async getVersion(): Promise<Version> {
return await this.httpRequest.get<Version>({ path: "version" });
/** {@link https://www.meilisearch.com/docs/reference/api/version} */
async getVersion(): Promise<VersionResponse> {
return await this.httpRequest.get({ path: "version" });
}

///
/// DUMPS
///

/**
* Creates a dump
*
* @returns Promise returning object of the enqueued task
*/
/** {@link https://www.meilisearch.com/docs/reference/api/dump#create-a-dump} */
createDump(): EnqueuedTaskPromise {
return this.#httpRequestsWithTask.post({
path: "dumps",
});
return this.#httpRequestsWithTask.post({ path: "dumps" });
}

///
/// SNAPSHOTS
///

/**
* Creates a snapshot
*
* @returns Promise returning object of the enqueued task
*/
/** {@link https://www.meilisearch.com/docs/reference/api/snapshots#create-a-snapshot} */
createSnapshot(): EnqueuedTaskPromise {
return this.#httpRequestsWithTask.post({
path: "snapshots",
});
return this.#httpRequestsWithTask.post({ path: "snapshots" });
}

///
Expand Down
225 changes: 225 additions & 0 deletions src/types/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
type CamelToSnakeCase<S extends string> = S extends `${infer T}${infer U}`
? `${T extends Capitalize<T> ? "_" : ""}${Lowercase<T>}${CamelToSnakeCase<U>}`
: S;
type PascalToSnakeCase<S extends string> = CamelToSnakeCase<Uncapitalize<S>>;

/**
* {@link https://www.meilisearch.com/docs/reference/errors/error_codes}
*
* @see `meilisearch_types::error::Code`
*/
export type Code = PascalToSnakeCase<
| "ApiKeyAlreadyExists"
| "ApiKeyNotFound"
| "BadParameter"
| "BadRequest"
| "DatabaseSizeLimitReached"
| "DocumentNotFound"
| "DumpAlreadyProcessing"
| "DumpNotFound"
| "DumpProcessFailed"
| "DuplicateIndexFound"
| "ImmutableApiKeyActions"
| "ImmutableApiKeyCreatedAt"
| "ImmutableApiKeyExpiresAt"
| "ImmutableApiKeyIndexes"
| "ImmutableApiKeyKey"
| "ImmutableApiKeyUid"
| "ImmutableApiKeyUpdatedAt"
| "ImmutableIndexCreatedAt"
| "ImmutableIndexUid"
| "ImmutableIndexUpdatedAt"
| "IndexAlreadyExists"
| "IndexCreationFailed"
| "IndexNotFound"
| "IndexPrimaryKeyAlreadyExists"
| "IndexPrimaryKeyMultipleCandidatesFound"
| "IndexPrimaryKeyNoCandidateFound"
| "Internal"
| "InvalidApiKey"
| "InvalidApiKeyActions"
| "InvalidApiKeyDescription"
| "InvalidApiKeyExpiresAt"
| "InvalidApiKeyIndexes"
| "InvalidApiKeyLimit"
| "InvalidApiKeyName"
| "InvalidApiKeyOffset"
| "InvalidApiKeyUid"
| "InvalidContentType"
| "InvalidDocumentCsvDelimiter"
| "InvalidDocumentFields"
| "InvalidDocumentRetrieveVectors"
| "MissingDocumentFilter"
| "MissingDocumentEditionFunction"
| "InvalidDocumentFilter"
| "InvalidDocumentGeoField"
| "InvalidVectorDimensions"
| "InvalidVectorsType"
| "InvalidDocumentId"
| "InvalidDocumentIds"
| "InvalidDocumentLimit"
| "InvalidDocumentOffset"
| "InvalidSearchEmbedder"
| "InvalidSimilarEmbedder"
| "InvalidSearchHybridQuery"
| "InvalidIndexLimit"
| "InvalidIndexOffset"
| "InvalidIndexPrimaryKey"
| "InvalidIndexUid"
| "InvalidMultiSearchFacets"
| "InvalidMultiSearchFacetsByIndex"
| "InvalidMultiSearchFacetOrder"
| "InvalidMultiSearchFederated"
| "InvalidMultiSearchFederationOptions"
| "InvalidMultiSearchMaxValuesPerFacet"
| "InvalidMultiSearchMergeFacets"
| "InvalidMultiSearchQueryFacets"
| "InvalidMultiSearchQueryPagination"
| "InvalidMultiSearchQueryRankingRules"
| "InvalidMultiSearchQueryPosition"
| "InvalidMultiSearchRemote"
| "InvalidMultiSearchWeight"
| "InvalidNetworkRemotes"
| "InvalidNetworkSelf"
| "InvalidNetworkSearchApiKey"
| "InvalidNetworkUrl"
| "InvalidSearchAttributesToSearchOn"
| "InvalidSearchAttributesToCrop"
| "InvalidSearchAttributesToHighlight"
| "InvalidSimilarAttributesToRetrieve"
| "InvalidSimilarRetrieveVectors"
| "InvalidSearchAttributesToRetrieve"
| "InvalidSearchRankingScoreThreshold"
| "InvalidSimilarRankingScoreThreshold"
| "InvalidSearchRetrieveVectors"
| "InvalidSearchCropLength"
| "InvalidSearchCropMarker"
| "InvalidSearchFacets"
| "InvalidSearchSemanticRatio"
| "InvalidSearchLocales"
| "InvalidFacetSearchExhaustiveFacetCount"
| "InvalidFacetSearchFacetName"
| "InvalidSimilarId"
| "InvalidSearchFilter"
| "InvalidSimilarFilter"
| "InvalidSearchHighlightPostTag"
| "InvalidSearchHighlightPreTag"
| "InvalidSearchHitsPerPage"
| "InvalidSimilarLimit"
| "InvalidSearchLimit"
| "InvalidSearchMatchingStrategy"
| "InvalidSimilarOffset"
| "InvalidSearchOffset"
| "InvalidSearchPage"
| "InvalidSearchQ"
| "InvalidFacetSearchQuery"
| "InvalidFacetSearchName"
| "FacetSearchDisabled"
| "InvalidSearchVector"
| "InvalidSearchShowMatchesPosition"
| "InvalidSearchShowRankingScore"
| "InvalidSimilarShowRankingScore"
| "InvalidSearchShowRankingScoreDetails"
| "InvalidSimilarShowRankingScoreDetails"
| "InvalidSearchSort"
| "InvalidSearchDistinct"
| "InvalidSettingsDisplayedAttributes"
| "InvalidSettingsDistinctAttribute"
| "InvalidSettingsProximityPrecision"
| "InvalidSettingsFacetSearch"
| "InvalidSettingsPrefixSearch"
| "InvalidSettingsFaceting"
| "InvalidSettingsFilterableAttributes"
| "InvalidSettingsPagination"
| "InvalidSettingsSearchCutoffMs"
| "InvalidSettingsEmbedders"
| "InvalidSettingsRankingRules"
| "InvalidSettingsSearchableAttributes"
| "InvalidSettingsSortableAttributes"
| "InvalidSettingsStopWords"
| "InvalidSettingsNonSeparatorTokens"
| "InvalidSettingsSeparatorTokens"
| "InvalidSettingsDictionary"
| "InvalidSettingsSynonyms"
| "InvalidSettingsTypoTolerance"
| "InvalidSettingsLocalizedAttributes"
| "InvalidState"
| "InvalidStoreFile"
| "InvalidSwapDuplicateIndexFound"
| "InvalidSwapIndexes"
| "InvalidTaskAfterEnqueuedAt"
| "InvalidTaskAfterFinishedAt"
| "InvalidTaskAfterStartedAt"
| "InvalidTaskBeforeEnqueuedAt"
| "InvalidTaskBeforeFinishedAt"
| "InvalidTaskBeforeStartedAt"
| "InvalidTaskCanceledBy"
| "InvalidTaskFrom"
| "InvalidTaskLimit"
| "InvalidTaskReverse"
| "InvalidTaskStatuses"
| "InvalidTaskTypes"
| "InvalidTaskUids"
| "InvalidBatchUids"
| "IoError"
| "FeatureNotEnabled"
| "MalformedPayload"
| "MaxFieldsLimitExceeded"
| "MissingApiKeyActions"
| "MissingApiKeyExpiresAt"
| "MissingApiKeyIndexes"
| "MissingAuthorizationHeader"
| "MissingContentType"
| "MissingDocumentId"
| "MissingFacetSearchFacetName"
| "MissingIndexUid"
| "MissingMasterKey"
| "MissingNetworkUrl"
| "MissingPayload"
| "MissingSearchHybrid"
| "MissingSwapIndexes"
| "MissingTaskFilters"
| "NoSpaceLeftOnDevice"
| "PayloadTooLarge"
| "RemoteBadResponse"
| "RemoteBadRequest"
| "RemoteCouldNotSendRequest"
| "RemoteInvalidApiKey"
| "RemoteRemoteError"
| "RemoteTimeout"
| "TooManySearchRequests"
| "TaskNotFound"
| "TaskFileNotFound"
| "BatchNotFound"
| "TooManyOpenFiles"
| "TooManyVectors"
| "UnretrievableDocument"
| "UnretrievableErrorCode"
| "UnsupportedMediaType"
| "VectorEmbeddingError"
| "NotFoundSimilarId"
| "InvalidDocumentEditionContext"
| "InvalidDocumentEditionFunctionFilter"
| "EditDocumentsByFunctionError"
>;

/**
* {@link https://www.meilisearch.com/docs/reference/errors/overview#errors}
*
* @see `meilisearch_types::error::ErrorType`
*/
export type ErrorType = PascalToSnakeCase<
"Internal" | "InvalidRequest" | "Auth" | "System"
>;

/**
* {@link https://www.meilisearch.com/docs/reference/errors/overview#error-format}
*
* @see `meilisearch_types::error::ResponseError`
*/
export type ResponseError = {
message: string;
code: Code;
type: ErrorType;
link: string;
};
Loading