UNPKG

@elastic/search-application-client

Version:
1 lines 23 kB
{"version":3,"sources":["../src/cache.ts","../src/api.ts","../src/request_builder.ts","../src/query_builder.ts","../src/client.ts","../src/utils.ts","../src/index.ts"],"names":["Cache","ttl","method","url","params","key","cached","value","API","apiKey","endpoint","path","options","__spreadValues","body","cacheParams","__spreadProps","cachedQueryResult","response","err","result","_a","_b","_c","errorMessage","fetchError","__async","error","TermsAggregation","facetConfiguration","StatsAggregation","RequestBuilder","facetsConfiguration","facetFilters","filter","sort","requests","facetName","acc","facetNames","initialRequest","aggs","aggregation","filters","facetFilter","transformResponse","results","facetConfigurations","combinedAggregations","facets","buckets","bucket","min","max","avg","sum","count","userSpecifiedAggs","aggregationKey","QueryBuilder","apiClient","baseParams","rest","__objRest","field","parameter","query","request","data","Client","applicationName","apiOptions","Highlight","hit","highlightValue","throwParamRequiredError","param","SearchApplicationClient","client"],"mappings":"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","sourcesContent":["const ONE_HOUR = 1000 * 60 * 60\nexport class Cache {\n private cache: Record<string, any> = {}\n\n constructor(private readonly ttl: number = ONE_HOUR) {}\n\n private createKeyByRequestParams(method, url, params: Record<string, any>) {\n return method + url + JSON.stringify(params)\n }\n\n getByRequestParams(method, url, params: Record<string, any>) {\n const key = this.createKeyByRequestParams(method, url, params)\n\n return this.get(key)\n }\n\n get(key: string) {\n const cached = this.cache[key]\n\n if (!cached) return null\n\n if (cached.expiration < Date.now()) {\n delete this.cache[key]\n\n return null\n }\n\n return cached.value\n }\n\n set(key: string, value: any) {\n this.cache[key] = {\n value,\n expiration: Date.now() + this.ttl,\n }\n }\n\n setByRequestParams(\n method: 'POST' | 'GET',\n url: string,\n params: Record<string, any>,\n value: any\n ) {\n const key = this.createKeyByRequestParams(method, url, params)\n this.set(key, value)\n }\n}\n","import { Cache } from './cache'\nimport { RequestParams, ResponseParams } from './types'\nimport { ErrorResponseBase } from '@elastic/elasticsearch/lib/api/types'\n\ninterface NetworkError extends Error {\n isNetworkError: boolean\n}\ninterface FetchError extends Error {\n isFetchError: boolean\n data: ErrorResponseBase\n}\n\nexport interface Options {\n cacheExpiration?: number\n cache?: boolean\n headers?: HeadersInit\n}\n\nexport class API {\n private readonly options: Options\n private readonly cacheService\n constructor(\n private readonly apiKey: string,\n private readonly endpoint: string,\n private readonly path: string,\n options: Options = {\n cache: true,\n headers: {},\n }\n ) {\n this.cacheService = new Cache(options.cacheExpiration)\n this.options = { cache: true, ...options }\n }\n\n private request<R extends ResponseParams = ResponseParams>(\n method: 'POST' | 'GET',\n url: string,\n body?: { params: RequestParams }\n ): Promise<R> {\n const cacheParams = {\n ...body,\n apiKey: this.apiKey,\n endpoint: this.endpoint,\n }\n const cachedQueryResult =\n this.options.cache &&\n this.cacheService.getByRequestParams(method, url, cacheParams)\n\n if (cachedQueryResult) {\n return Promise.resolve(cachedQueryResult)\n }\n\n return fetch(url, {\n method,\n headers: {\n ...this.options.headers,\n 'Content-Type': 'application/json',\n Authorization: `Apikey ${this.apiKey}`,\n },\n body: body ? JSON.stringify(body) : undefined,\n })\n .then(\n (response) => response.json(),\n (err) => {\n err.isNetworkError = true\n\n throw err\n }\n )\n .then((result) => {\n if (result.error) {\n const errorMessage =\n (result as ErrorResponseBase)?.error?.reason ||\n (result as ErrorResponseBase)?.error?.caused_by?.reason\n const fetchError = new Error(errorMessage) as FetchError\n fetchError.isFetchError = true\n fetchError.data = result\n\n throw fetchError\n }\n\n if (this.options.cache) {\n this.cacheService.setByRequestParams(method, url, cacheParams, result)\n }\n\n return result\n })\n .catch(this.handleError)\n }\n\n async post<R extends ResponseParams = ResponseParams>(body: {\n params: RequestParams\n }) {\n return await this.request<R>('POST', `${this.endpoint}${this.path}`, body)\n }\n\n private handleError(error: Error): void {\n if ((error as NetworkError).isNetworkError) {\n error.name = '[Network Error]'\n } else if (\n (error as FetchError).isFetchError &&\n (error as FetchError).data.status === 500 &&\n ((error as FetchError).data.error?.caused_by?.type.includes(\n 'format_exception'\n ) ||\n (error as FetchError).data.error.type === 'json_parse_exception')\n ) {\n error.name = '[Parameter or type is invalid]'\n } else if (\n (error as FetchError).isFetchError &&\n (error as FetchError).data.status === 401\n ) {\n error.name = '[Authorization Error]'\n } else if (\n (error as FetchError).isFetchError &&\n (error as FetchError).data.status === 404\n ) {\n error.name = '[Not Found Error]'\n error.message = `${(error as FetchError).data.error.type}: ${\n error.message\n }`\n }\n\n console.error(error)\n }\n}\n","import {\n Aggregations,\n FacetFilters,\n Params,\n Query,\n RequestParams,\n SortFields,\n} from './types'\n\ninterface BaseFacetConfiguration {\n type: 'terms' | 'stats'\n field: string\n disjunctive?: boolean\n}\n\ninterface TermsFacetConfiguration extends BaseFacetConfiguration {\n type: 'terms'\n size: number\n}\n\ninterface StatsFacetConfiguration extends BaseFacetConfiguration {\n type: 'stats'\n}\n\nexport type FacetConfiguration =\n | TermsFacetConfiguration\n | StatsFacetConfiguration\n\ninterface FacetsConfiguration {\n [facetName: string]: FacetConfiguration\n}\n\nconst TermsAggregation = (\n facetConfiguration: TermsFacetConfiguration\n): Pick<Aggregations, 'terms'> => ({\n terms: {\n field: facetConfiguration.field,\n size: facetConfiguration.size,\n },\n})\n\nconst StatsAggregation = (\n facetConfiguration: StatsFacetConfiguration\n): Pick<Aggregations, 'stats'> => ({\n stats: {\n field: facetConfiguration.field,\n },\n})\n\nexport class RequestBuilder {\n constructor(\n private readonly facetsConfiguration: FacetsConfiguration,\n private readonly facetFilters: FacetFilters,\n private readonly filter: Query,\n private readonly sort: SortFields,\n private readonly params: Params\n ) {}\n\n build(): RequestParams[] {\n const facetRequests = Object.keys(this.facetsConfiguration).reduce<\n string[][]\n >(\n (requests, facetName) => {\n const facetConfiguration = this.facetsConfiguration[facetName]\n if (\n facetConfiguration.disjunctive &&\n this.facetFilters[facetName]?.length > 0\n ) {\n requests.push([facetName])\n return requests\n }\n requests[0].push(facetName)\n return requests\n },\n [[]]\n )\n\n return facetRequests.reduce<RequestParams[]>((acc, facetNames, i) => {\n const initialRequest = i === 0\n\n const aggs = facetNames.reduce<Record<string, Aggregations>>(\n (acc, facetName) => {\n const facetConfiguration = this.facetsConfiguration[facetName]\n\n const aggregation =\n facetConfiguration.type === 'terms'\n ? TermsAggregation(facetConfiguration)\n : StatsAggregation(facetConfiguration)\n\n return {\n ...acc,\n [`${facetName}_facet`]: aggregation,\n }\n },\n {}\n )\n\n const filters = Object.keys(this.facetsConfiguration).reduce(\n (acc, facetName) => {\n const facetConfiguration = this.facetsConfiguration[facetName]\n const facetFilter = this.facetFilters[facetName] || []\n\n if (facetFilter.length === 0) return acc\n if (facetConfiguration.disjunctive && !initialRequest) return acc\n\n return [\n ...acc,\n {\n [facetConfiguration.type === 'terms' ? 'terms' : 'range']: {\n [facetConfiguration.field]: facetFilter,\n },\n },\n ]\n },\n []\n )\n\n acc.push({\n _es_aggs: aggs,\n _es_filters: {\n bool: {\n must: [...(this.filter ? [this.filter] : []), ...filters],\n },\n },\n ...(this.sort ? { _es_sort_fields: this.sort } : {}),\n ...this.params,\n ...(initialRequest ? {} : { size: 0, from: 0 }),\n })\n return acc\n }, [])\n }\n}\n","import { API } from './api'\nimport { FacetConfiguration, RequestBuilder } from './request_builder'\nimport type {\n FilterFieldValue,\n Params,\n Query,\n SortFields,\n ResponseParams,\n ResponseTermsAggregation,\n ResponseStatsAggregation,\n ResponseFacets,\n} from './types'\n\nconst transformResponse = <T extends ResponseParams = ResponseParams>(\n results: T[],\n facetConfigurations: Record<string, FacetConfiguration>\n): T & { facets?: ResponseFacets[] } => {\n const combinedAggregations = results.reduce((acc, result) => {\n return {\n ...acc,\n ...result.aggregations,\n }\n }, {})\n\n const facets = Object.keys(combinedAggregations).reduce<ResponseFacets[]>(\n (facets, facetName) => {\n const key = facetName.replace('_facet', '')\n const facetConfiguration = facetConfigurations[key]\n if (!facetConfiguration) return facets\n\n const aggregation = combinedAggregations[facetName]\n if (facetConfiguration.type === 'terms') {\n const { buckets } = aggregation as ResponseTermsAggregation\n\n return [\n ...facets,\n {\n name: key,\n entries: (Array.isArray(buckets)\n ? buckets\n : Object.values(buckets)\n ).map((bucket) => {\n return {\n value: bucket.key,\n count: bucket.doc_count,\n }\n }),\n },\n ]\n } else if (facetConfiguration.type === 'stats') {\n const { min, max, avg, sum, count } =\n aggregation as ResponseStatsAggregation\n\n return [\n ...facets,\n {\n name: key,\n stats: {\n min,\n max,\n avg,\n sum,\n count,\n },\n },\n ]\n }\n },\n []\n )\n\n const userSpecifiedAggs = Object.keys(results[0]?.aggregations || {}).reduce(\n (acc, aggregationKey) => {\n if (!facetConfigurations[aggregationKey.replace('_facet', '')]) {\n return {\n ...acc,\n [aggregationKey]: results[0].aggregations[aggregationKey],\n }\n }\n return acc\n },\n {}\n )\n\n return {\n ...results[0],\n aggregations: userSpecifiedAggs,\n facets,\n }\n}\n\nexport class QueryBuilder {\n readonly facets: Record<string, FacetConfiguration> = {}\n facetFilters: Record<string, FilterFieldValue[]> = {}\n sort: SortFields\n filter: Query\n params: Params = {}\n\n constructor(\n private readonly apiClient: API,\n baseParams: {\n facets?: Record<string, FacetConfiguration>\n } & Params = {}\n ) {\n const { facets, ...rest } = baseParams\n this.facets = facets || {}\n this.params = rest\n }\n\n /**\n * @public\n * @param {string} field\n * @param {string | Array.string | Object} value\n * @returns {QueryBuilder}\n */\n addFacetFilter(field: string, value: FilterFieldValue): this {\n const facetInfo = this.facets?.[field]\n\n if (!facetInfo) {\n throw new Error(`Facet ${field} wasn't passed in configuration params`)\n }\n\n this.facetFilters[field] = [\n ...(this.facetFilters[field] || []),\n Array.isArray(value) ? value : [value],\n ].flat()\n\n return this\n }\n\n /**\n * @public\n * @param {string} parameter\n * @param {*} value\n * @returns {QueryBuilder}\n */\n addParameter(parameter: keyof Params, value: Params[keyof Params]): this {\n this.params[parameter] = value\n\n return this\n }\n\n /**\n * @public\n * @param {string} query\n * @returns {QueryBuilder}\n */\n query(query: string): this {\n return this.addParameter('query', query)\n }\n\n /**\n * @async\n * @public - returns search results\n * @returns {Promise.<Array.<Object>>}\n */\n async search<Result = unknown>() {\n const requests = new RequestBuilder(\n this.facets,\n this.facetFilters,\n this.filter,\n this.sort,\n this.params\n ).build()\n\n const results = (\n await Promise.all(\n requests.map((request) =>\n this.apiClient.post<ResponseParams<Result>>({ params: request })\n )\n )\n ).filter((data) => !!data)\n\n return transformResponse<ResponseParams<Result>>(results, this.facets)\n }\n\n /**\n * @public\n * @param {Object} value\n * @returns {QueryBuilder}\n */\n setFilter(value: Query): this {\n this.filter = value\n return this\n }\n\n /**\n * @public\n * @param {number} value\n * @returns {QueryBuilder}\n */\n setFrom(value: Params['from']): this {\n return this.addParameter('from', value)\n }\n\n /**\n * @public\n * @param {number} value\n * @returns {QueryBuilder}\n */\n setPageSize(value: Params['size']): this {\n return this.addParameter('size', value)\n }\n\n /**\n * @public\n * @param {Array.<Object<string, 'desc' | 'asc'>|'_score'>} sort\n * @returns {QueryBuilder}\n */\n setSort(sort: SortFields): this {\n this.sort = sort\n\n return this\n }\n}\n","import { API, Options } from './api'\nimport { QueryBuilder } from './query_builder'\n\nexport class Client {\n private readonly apiClient: API\n private readonly baseParams: Record<string, any>\n\n constructor({\n applicationName,\n endpoint,\n apiKey,\n baseParams,\n apiOptions,\n }: {\n applicationName: string\n endpoint: string\n apiKey: string\n baseParams?: Record<string, any>\n apiOptions?: Options\n }) {\n this.baseParams = baseParams || {}\n this.apiClient = new API(\n apiKey,\n endpoint,\n `/_application/search_application/${applicationName}/_search`,\n apiOptions\n )\n }\n\n /**\n * @public\n * @returns {QueryBuilder} - returns QueryBuilder instance\n */\n initQuery() {\n return new QueryBuilder(this.apiClient, this.baseParams)\n }\n}\n","import { ResponseParams } from './types'\n\nexport const Highlight = (\n hit: ResponseParams['hits']['hits'][0],\n field: string\n) => {\n const highlightValue = hit.highlight?.[field]\n\n return highlightValue?.length\n ? highlightValue.join('...')\n : hit['_source'][field]\n}\n","import { Options } from './api'\nimport { Client } from './client'\nimport { QueryBuilder } from './query_builder'\n\nconst throwParamRequiredError = (param: string) => {\n throw new Error(`${param} is required`)\n}\n\n/**\n * @function SearchApplicationClient\n * @param {string} applicationName\n * @param {string} endpoint\n * @param {string} apiKey\n * @param {Object} params\n * @param {Object} apiOptions\n * @returns {function(): QueryBuilder}\n */\nexport default function SearchApplicationClient(\n applicationName: string,\n endpoint: string,\n apiKey: string,\n params?: Record<string, any>,\n apiOptions?: Options\n): () => QueryBuilder {\n if (!applicationName) throwParamRequiredError('applicationName')\n if (!endpoint) throwParamRequiredError('endpoint')\n if (!apiKey) throwParamRequiredError('apiKey')\n\n const client = new Client({\n applicationName,\n endpoint,\n apiKey,\n baseParams: params,\n apiOptions,\n })\n\n return () => client.initQuery()\n}\n\nexport * from './utils'\n"]}