nestjs-meili
Version:
Seamless and declarative integration of [MeiliSearch](https://www.meilisearch.com/) into [NestJS](https://nestjs.com/). Use decorators to configure indexes and inject `MeiliSearch` with type safety and zero boilerplate.
83 lines (82 loc) • 2.94 kB
JavaScript
import { Module, Global, } from "@nestjs/common";
import { MeiliClient } from "./client";
import { MeiliUtils } from "./utils";
import { getMeiliIndexToken } from "./inject-meili";
import { MEILI_INDEX } from "./watermarks";
import { MeiliSearch } from "meilisearch";
()
({})
export class MeiliModule {
static forRoot(options) {
const clientController = new MeiliClient(options.host, options.apiKey);
const clientControllerProvider = {
provide: MeiliClient,
useValue: clientController,
};
const clientProvider = {
provide: MeiliSearch,
useValue: clientController.client,
};
return {
module: MeiliModule,
imports: [],
providers: [clientControllerProvider, clientProvider],
exports: [MeiliClient, clientProvider],
};
}
static forRootAsync(options) {
const clientControllerProvider = {
provide: MeiliClient,
useFactory: async (...args) => {
const config = await options.useFactory(...args);
return new MeiliClient(config.host, config.apiKey);
},
inject: options.inject || [],
};
const clientProvider = {
provide: MeiliSearch,
useFactory: async (...args) => {
const config = await options.useFactory(...args);
return new MeiliSearch({ host: config.host, apiKey: config.apiKey });
},
inject: options.inject || [],
};
return {
module: MeiliModule,
imports: options.imports || [],
providers: [clientControllerProvider, clientProvider],
exports: [MeiliClient, clientProvider],
};
}
static getIndexName(target) {
const name = Reflect.getMetadata(MEILI_INDEX, target);
if (!name) {
throw new Error(`MeiliIndex name is not defined for class ${target.name}. Use @MeiliIndex('name')`);
}
return name;
}
static forFeature(models) {
const indexProviders = models.map((model) => {
const indexName = this.getIndexName(model);
return {
provide: getMeiliIndexToken(indexName),
useFactory: (client) => client.initIndex(indexName),
inject: [MeiliClient],
};
});
const setupProvider = {
provide: "MEILI_INDEX_SETUP",
useFactory: async (utils, meiliClient) => {
for (const model of models) {
await utils.setupIndex(model, meiliClient);
}
},
inject: [MeiliUtils, MeiliClient],
};
return {
module: MeiliModule,
providers: [...indexProviders, setupProvider, MeiliUtils],
exports: indexProviders,
};
}
}