Files
medusa-store/packages/medusa-plugin-algolia/src/services/algolia.ts
Riqwan Thamir 107ae23a3f fix(utils, types, medusa-plugin-meilisearch, medusa-plugin-algolia): move SoftDeletableFilterKey, variantKeys, indexTypes from types to utils (#4623)
* chore: move SoftDeletableKey from types to utils

* chore: move variantkeys, indextypes
2023-07-27 16:42:26 +02:00

178 lines
5.2 KiB
TypeScript

import { SearchTypes } from "@medusajs/types"
import { SearchUtils } from "@medusajs/utils"
import Algolia, { SearchClient } from "algoliasearch"
import { AlgoliaPluginOptions, SearchOptions } from "../types"
import { transformProduct } from "../utils/transformer"
class AlgoliaService extends SearchUtils.AbstractSearchService {
isDefault = false
protected readonly config_: AlgoliaPluginOptions
protected readonly client_: SearchClient
constructor(_, options: AlgoliaPluginOptions) {
super(_, options)
this.config_ = options
const { applicationId, adminApiKey } = options
if (!applicationId) {
throw new Error("Please provide a valid Application ID")
}
if (!adminApiKey) {
throw new Error("Please provide a valid Admin Api Key")
}
this.client_ = Algolia(applicationId, adminApiKey)
}
/**
* Add two numbers.
* @param {string} indexName - The name of the index
* @param {*} options - not required just to match the schema we are used it
* @return {*}
*/
createIndex(indexName: string, options: Record<string, unknown> = {}) {
return this.client_.initIndex(indexName)
}
/**
* Used to get an index
* @param {string} indexName - the index name.
* @return {Promise<{object}>} - returns response from search engine provider
*/
async getIndex(indexName: string) {
let hits: Record<string, unknown>[] = []
return await this.client_
.initIndex(indexName)
.browseObjects({
query: indexName,
batch: (batch) => {
hits = hits.concat(batch)
},
})
.then(() => hits)
}
/**
*
* @param {string} indexName
* @param {Array} documents - products list array
* @param {*} type
* @return {*}
*/
async addDocuments(indexName: string, documents: any, type: string) {
const transformedDocuments = await this.getTransformedDocuments(
type,
documents
)
return await this.client_
.initIndex(indexName)
.saveObjects(transformedDocuments)
}
/**
* Used to replace documents
* @param {string} indexName - the index name.
* @param {Object} documents - array of document objects that will replace existing documents
* @param {Array.<Object>} type - type of documents to be replaced (e.g: products, regions, orders, etc)
* @return {Promise<{object}>} - returns response from search engine provider
*/
async replaceDocuments(indexName: string, documents: any, type: string) {
const transformedDocuments = await this.getTransformedDocuments(
type,
documents
)
return await this.client_
.initIndex(indexName)
.replaceAllObjects(transformedDocuments)
}
/**
* Used to delete document
* @param {string} indexName - the index name
* @param {string} documentId - the id of the document
* @return {Promise<{object}>} - returns response from search engine provider
*/
async deleteDocument(indexName: string, documentId: string) {
return await this.client_.initIndex(indexName).deleteObject(documentId)
}
/**
* Used to delete all documents
* @param {string} indexName - the index name
* @return {Promise<{object}>} - returns response from search engine provider
*/
async deleteAllDocuments(indexName: string) {
return await this.client_.initIndex(indexName).delete()
}
/**
* Used to search for a document in an index
* @param {string} indexName - the index name
* @param {string} query - the search query
* @param {*} options
* - any options passed to the request object other than the query and indexName
* - additionalOptions contain any provider specific options
* @return {*} - returns response from search engine provider
*/
async search(
indexName: string,
query: string,
options: SearchOptions & Record<string, unknown>
) {
const { paginationOptions, filter, additionalOptions } = options
// fit our pagination options to what Algolia expects
if ("limit" in paginationOptions && paginationOptions.limit != null) {
paginationOptions["length"] = paginationOptions.limit
delete paginationOptions.limit
}
return await this.client_.initIndex(indexName).search(query, {
filters: filter,
...paginationOptions,
...additionalOptions,
})
}
/**
* Used to update the settings of an index
* @param {string} indexName - the index name
* @param {object} settings - settings object
* @return {Promise<{object}>} - returns response from search engine provider
*/
async updateSettings(
indexName: string,
settings: SearchTypes.IndexSettings & Record<string, unknown>
) {
// backward compatibility
const indexSettings = settings.indexSettings ?? settings ?? {}
return await this.client_.initIndex(indexName).setSettings(indexSettings)
}
async getTransformedDocuments(type: string, documents: any[]) {
if (!documents?.length) {
return []
}
switch (type) {
case SearchUtils.indexTypes.PRODUCTS:
const productsTransformer =
this.config_.settings?.[SearchUtils.indexTypes.PRODUCTS]
?.transformer ?? transformProduct
return documents.map(productsTransformer)
default:
return documents
}
}
}
export default AlgoliaService