diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 000000000..153279612 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,1214 @@ +import algoliasearch from 'algoliasearch'; +import { EventEmitter } from 'events'; + +type SearchClient = Pick< + algoliasearch.Client, + 'search' | 'searchForFacetValues' +>; + +/** + * The algoliasearchHelper module is the function that will let its + * contains everything needed to use the Algoliasearch + * Helper. It is a also a function that instantiate the helper. + * To use the helper, you also need the Algolia JS client v3. + * @param client an AlgoliaSearch client + * @param index the name of the index to query + * @param opts + */ +declare function algoliasearchHelper( + client: SearchClient, + index: string, + opts?: algoliasearchHelper.PlainSearchParameters +): algoliasearchHelper.AlgoliaSearchHelper; + +declare namespace algoliasearchHelper { + export const version: string; + + export class AlgoliaSearchHelper extends EventEmitter { + state: SearchParameters; + lastResults: SearchResults | null; + derivedHelpers: DerivedHelper[]; + + on( + event: 'search', + cb: (res: { state: SearchParameters; results: SearchResults }) => void + ): this; + on( + event: 'change', + cb: (res: { + state: SearchParameters; + results: SearchResults; + isPageReset: boolean; + }) => void + ): this; + on( + event: 'searchForFacetValues', + cb: (res: { + state: SearchParameters; + facet: string; + query: string; + }) => void + ): this; + on( + event: 'searchOnce', + cb: (res: { state: SearchParameters }) => void + ): this; + on( + event: 'result', + cb: (res: { results: SearchResults; state: SearchParameters }) => void + ): this; + on(event: 'error', cb: (res: { error: Error }) => void): this; + on(event: 'searchQueueEmpty', cb: () => void): this; + + /** + * Start the search with the parameters set in the state. When the + * method is called, it triggers a `search` event. The results will + * be available through the `result` event. If an error occurs, an + * `error` will be fired instead. + * @return + * @fires search + * @fires result + * @fires error + * @chainable + */ + search(): this; + + /** + * Gets the search query parameters that would be sent to the Algolia Client + * for the hits + */ + getQuery(): algoliasearch.QueryParameters; + + /** + * Start a search using a modified version of the current state. This method does + * not trigger the helper lifecycle and does not modify the state kept internally + * by the helper. This second aspect means that the next search call will be the + * same as a search call before calling searchOnce. + * @param options can contain all the parameters that can be set to SearchParameters + * plus the index + * @param [callback] optional callback executed when the response from the + * server is back. + * @return if a callback is passed the method returns undefined + * otherwise it returns a promise containing an object with two keys : + * - content with a SearchResults + * - state with the state used for the query as a SearchParameters + * @example + * // Changing the number of records returned per page to 1 + * // This example uses the callback API + * var state = helper.searchOnce({hitsPerPage: 1}, + * function(error, content, state) { + * // if an error occurred it will be passed in error, otherwise its value is null + * // content contains the results formatted as a SearchResults + * // state is the instance of SearchParameters used for this search + * }); + * @example + * // Changing the number of records returned per page to 1 + * // This example uses the promise API + * var state1 = helper.searchOnce({hitsPerPage: 1}) + * .then(promiseHandler); + * + * function promiseHandler(res) { + * // res contains + * // { + * // content : SearchResults + * // state : SearchParameters (the one used for this specific search) + * // } + * } + */ + searchOnce( + options: PlainSearchParameters + ): Promise<{ content: SearchResults; state: SearchParameters }>; + searchOnce( + options: PlainSearchParameters, + cb: ( + error: Error, + content: SearchResults, + state: SearchParameters + ) => void + ): void; + + /** + * Search for facet values based on an query and the name of a faceted attribute. This + * triggers a search and will return a promise. On top of using the query, it also sends + * the parameters from the state so that the search is narrowed down to only the possible values. + * + * See the description of [FacetSearchResult](reference.html#FacetSearchResult) + * @param facet the name of the faceted attribute + * @param query the string query for the search + * @param [maxFacetHits] the maximum number values returned. Should be > 0 and <= 100 + * @param [userState] the set of custom parameters to use on top of the current state. Setting a property to `undefined` removes + * it in the generated query. + * @return the results of the search + */ + searchForFacetValues( + facet: string, + query: string, + maxFacetHits: number, + userState: PlainSearchParameters + ): Promise; + + /** + * Sets the text query used for the search. + * + * This method resets the current page to 0. + * @param q the user query + * @return + * @fires change + * @chainable + */ + setQuery(q: string): this; + + /** + * Remove all the types of refinements except tags. A string can be provided to remove + * only the refinements of a specific attribute. For more advanced use case, you can + * provide a function instead. This function should follow the + * [clearCallback definition](#SearchParameters.clearCallback). + * + * This method resets the current page to 0. + * @param [name] optional name of the facet / attribute on which we want to remove all refinements + * @return + * @fires change + * @chainable + * @example + * // Removing all the refinements + * helper.clearRefinements().search(); + * @example + * // Removing all the filters on a the category attribute. + * helper.clearRefinements('category').search(); + * @example + * // Removing only the exclude filters on the category facet. + * helper.clearRefinements(function(value, attribute, type) { + * return type === 'exclude' && attribute === 'category'; + * }).search(); + */ + clearRefinements(name?: string): this; + clearRefinements( + func: (value: any, attribute: string, type: string) => boolean + ): this; + + /** + * Remove all the tag filters. + * + * This method resets the current page to 0. + * @return + * @fires change + * @chainable + */ + clearTags(): this; + + /** + * Updates the name of the index that will be targeted by the query. + * + * This method resets the current page to 0. + * @param name the index name + * @return + * @fires change + * @chainable + */ + setIndex(name: string): this; + + addDisjunctiveFacetRefinement(...args: any[]): any; + addDisjunctiveRefine(...args: any[]): any; + addHierarchicalFacetRefinement(...args: any[]): any; + addNumericRefinement(...args: any[]): any; + addFacetRefinement(...args: any[]): any; + addRefine(...args: any[]): any; + addFacetExclusion(...args: any[]): any; + addExclude(...args: any[]): any; + addTag(...args: any[]): any; + removeNumericRefinement(...args: any[]): any; + removeDisjunctiveFacetRefinement(...args: any[]): any; + removeDisjunctiveRefine(...args: any[]): any; + removeHierarchicalFacetRefinement(...args: any[]): any; + removeFacetRefinement(...args: any[]): any; + removeRefine(...args: any[]): any; + removeFacetExclusion(...args: any[]): any; + removeExclude(...args: any[]): any; + removeTag(...args: any[]): any; + toggleFacetExclusion(...args: any[]): any; + toggleExclude(...args: any[]): any; + toggleRefinement(...args: any[]): any; + toggleFacetRefinement(...args: any[]): any; + toggleRefine(...args: any[]): any; + toggleTag(...args: any[]): any; + nextPage(...args: any[]): any; + previousPage(...args: any[]): any; + setCurrentPage(...args: any[]): any; + setPage(...args: any[]): any; + setQueryParameter(...args: any[]): any; + + /** + * Set the whole state (warning: will erase previous state) + * @param newState the whole new state + * @return + * @fires change + * @chainable + */ + setState(newState: PlainSearchParameters): this; + + overrideStateWithoutTriggeringChangeEvent(...args: any[]): any; + isRefined(...args: any[]): any; + hasRefinements(...args: any[]): any; + isExcluded(...args: any[]): any; + isDisjunctiveRefined(...args: any[]): any; + hasTag(...args: any[]): any; + isTagRefined(...args: any[]): any; + getIndex(...args: any[]): any; + getCurrentPage(...args: any[]): any; + getPage(...args: any[]): any; + getTags(...args: any[]): any; + getRefinements(...args: any[]): any; + getNumericRefinement(...args: any[]): any; + getHierarchicalFacetBreadcrumb(...args: any[]): any; + containsRefinement(...args: any[]): any; + clearCache(...args: any[]): any; + setClient(client: SearchClient): this; + getClient(): SearchClient; + derive( + deriveFn: (oldParams: SearchParameters) => SearchParameters + ): DerivedHelper; + detachDerivedHelper(derivedHelper: DerivedHelper): void; + hasPendingRequests(...args: any[]): any; + } + + interface DerivedHelper extends EventEmitter { + on( + event: 'search', + cb: (res: { state: SearchParameters; results: SearchResults }) => void + ): this; + on( + event: 'result', + cb: (res: { results: SearchResults; state: SearchParameters }) => void + ): this; + + lastResults: SearchResults | null; + detach(): void; + getModifiedState(): SearchParameters; + } + + namespace SearchForFacetValues { + /** + * Structure of each result when using + * [`searchForFacetValues()`](reference.html#AlgoliaSearchHelper#searchForFacetValues) + */ + export interface Hit { + value: string; + highlighted: string; + count: number; + isRefined: boolean; + } + + /** + * Structure of the data resolved by the + * [`searchForFacetValues()`](reference.html#AlgoliaSearchHelper#searchForFacetValues) + * promise. + */ + export interface Result { + facetHits: Hit[]; + processingTimeMS: number; + } + } + + export interface PlainSearchParameters extends algoliasearch.QueryParameters { + /** + * Targeted index. This parameter is mandatory. + */ + index?: string; + /** + * This attribute contains the list of all the disjunctive facets + * used. This list will be added to requested facets in the + * [facets attribute](https://www.algolia.com/doc/rest-api/search#param-facets) sent to algolia. + */ + disjunctiveFacets?: string[]; + /** + * This attribute contains the list of all the hierarchical facets + * used. This list will be added to requested facets in the + * [facets attribute](https://www.algolia.com/doc/rest-api/search#param-facets) sent to algolia. + * Hierarchical facets are a sub type of disjunctive facets that + * let you filter faceted attributes hierarchically. + */ + hierarchicalFacets?: SearchParameters.HierarchicalFacet[]; + + // Refinements + /** + * This attribute contains all the filters that need to be + * applied on the conjunctive facets. Each facet must be properly + * defined in the `facets` attribute. + * + * The key is the name of the facet, and the `FacetList` contains all + * filters selected for the associated facet name. + * + * When querying algolia, the values stored in this attribute will + * be translated into the `facetFilters` attribute. + */ + facetsRefinements?: { [facet: string]: SearchParameters.FacetList }; + /** + * This attribute contains all the filters that need to be + * excluded from the conjunctive facets. Each facet must be properly + * defined in the `facets` attribute. + * + * The key is the name of the facet, and the `FacetList` contains all + * filters excluded for the associated facet name. + * + * When querying algolia, the values stored in this attribute will + * be translated into the `facetFilters` attribute. + */ + facetsExcludes?: { [facet: string]: SearchParameters.FacetList }; + /** + * This attribute contains all the filters that need to be + * applied on the disjunctive facets. Each facet must be properly + * defined in the `disjunctiveFacets` attribute. + * + * The key is the name of the facet, and the `FacetList` contains all + * filters selected for the associated facet name. + * + * When querying algolia, the values stored in this attribute will + * be translated into the `facetFilters` attribute. + */ + disjunctiveFacetsRefinements?: { + [facet: string]: SearchParameters.FacetList; + }; + /** + * This attribute contains all the filters that need to be + * applied on the numeric attributes. + * + * The key is the name of the attribute, and the value is the + * filters to apply to this attribute. + * + * When querying algolia, the values stored in this attribute will + * be translated into the `numericFilters` attribute. + */ + numericRefinements?: { [facet: string]: SearchParameters.OperatorList }; + /** + * This attribute contains all the tags used to refine the query. + * + * When querying algolia, the values stored in this attribute will + * be translated into the `tagFilters` attribute. + */ + tagRefinements?: string[]; + /** + * This attribute contains all the filters that need to be + * applied on the hierarchical facets. Each facet must be properly + * defined in the `hierarchicalFacets` attribute. + * + * The key is the name of the facet, and the `FacetList` contains all + * filters selected for the associated facet name. The FacetList values + * are structured as a string that contain the values for each level + * separated by the configured separator. + * + * When querying algolia, the values stored in this attribute will + * be translated into the `facetFilters` attribute. + */ + hierarchicalFacetsRefinements?: { + [facet: string]: SearchParameters.FacetList; + }; + } + + export class SearchParameters implements PlainSearchParameters { + managedParameters: [ + 'index', + 'facets', + 'disjunctiveFacets', + 'facetsRefinements', + 'facetsExcludes', + 'disjunctiveFacetsRefinements', + 'numericRefinements', + 'tagRefinements', + 'hierarchicalFacets', + 'hierarchicalFacetsRefinements' + ]; + + constructor(newParameters?: PlainSearchParameters); + + /* Add a disjunctive facet to the disjunctiveFacets attribute of the helper configuration, if it isn't already present. */ + addDisjunctiveFacet(facet: string): SearchParameters; + /* Adds a refinement on a disjunctive facet. */ + addDisjunctiveFacetRefinement( + facet: string, + value: string + ): SearchParameters; + /* Exclude a value from a "normal" facet */ + addExcludeRefinement(facet: string, value: string): SearchParameters; + /* Add a facet to the facets attribute of the helper configuration, if it isn't already present. */ + addFacet(facet: string): SearchParameters; + /* Add a refinement on a "normal" facet */ + addFacetRefinement(facet: string, value: string): SearchParameters; + addHierarchicalFacet(facet: any): SearchParameters; + addHierarchicalFacetRefinement( + facet: string, + path: string + ): SearchParameters; + addNumericRefinement( + attribute: string, + operator: SearchParameters.Operator, + value: number | number[] + ): SearchParameters; + addTagRefinement(tag: string): SearchParameters; + clearRefinements( + attribute?: + | string + | ((value: any, attribute: string, type: string) => void) + ): SearchParameters; + clearTags(): SearchParameters; + getConjunctiveRefinements(facetName: string): string[]; + getDisjunctiveRefinements(facetName: string): string[]; + getExcludeRefinements(facetName: string): string[]; + getHierarchicalFacetBreadcrumb(facetName: string): string[]; + getHierarchicalFacetByName(hierarchicalFacetName: string): any; + getHierarchicalRefinement(facetName: string): string[]; + getNumericRefinements(facetName: string): SearchParameters.OperatorList[]; + getNumericRefinement( + attribute: string, + operator: SearchParameters.Operator + ): Array; + getQueryParams(): algoliasearch.QueryParameters; + getRefinedDisjunctiveFacets(facet: string, value: any): string[]; + getRefinedHierarchicalFacets(facet: string, value: any): string[]; + getUnrefinedDisjunctiveFacets(): string[]; + isConjunctiveFacet(facet: string): boolean; + isDisjunctiveFacetRefined(facet: string, value?: string): boolean; + isDisjunctiveFacet(facet: string): boolean; + isExcludeRefined(facet: string, value?: string): boolean; + isFacetRefined(facet: string, value?: string): boolean; + isHierarchicalFacetRefined(facet: string, value?: string): boolean; + isHierarchicalFacet(facet: string): boolean; + isNumericRefined( + attribute: string, + operator: SearchParameters.Operator, + value?: string + ): boolean; + isTagRefined(tag: string): boolean; + static make(newParameters: PlainSearchParameters): SearchParameters; + removeExcludeRefinement(facet: string, value: string): SearchParameters; + removeFacet(facet: string): SearchParameters; + removeFacetRefinement(facet: string, value?: string): SearchParameters; + removeDisjunctiveFacet(facet: string): SearchParameters; + removeDisjunctiveFacetRefinement( + facet: string, + value?: string + ): SearchParameters; + removeHierarchicalFacet(facet: string): SearchParameters; + removeHierarchicalFacetRefinement(facet: string): SearchParameters; + removeTagRefinement(tag: string): SearchParameters; + setDisjunctiveFacets(facets: string[]): SearchParameters; + setFacets(facets: string[]): SearchParameters; + setHitsPerPage(n: number): SearchParameters; + setPage(newPage: number): SearchParameters; + setQueryParameters(params: PlainSearchParameters): SearchParameters; + setQueryParameter(parameter: string, value: any): SearchParameters; + setQuery(newQuery: string): SearchParameters; + setTypoTolerance(typoTolerance: string): SearchParameters; + toggleDisjunctiveFacetRefinement( + facet: string, + value: any + ): SearchParameters; + toggleExcludeFacetRefinement(facet: string, value: any): SearchParameters; + toggleConjunctiveFacetRefinement( + facet: string, + value: any + ): SearchParameters; + toggleHierarchicalFacetRefinement( + facet: string, + value: any + ): SearchParameters; + toggleFacetRefinement(facet: string, value: any): SearchParameters; + toggleTagRefinement(tag: string): SearchParameters; + static validate( + currentState: SearchParameters, + parameters: PlainSearchParameters + ): null | Error; + + /** + * implementation of PlainSearchParameters, copied because it's an interface. + * Notable difference is that the managed search parameters are not optional, + * ideally this would be Required where ManagedParameters + * are the following ones. + */ + + /** + * Targeted index. This parameter is mandatory. + */ + index: string; + /** + * This attribute contains the list of all the disjunctive facets + * used. This list will be added to requested facets in the + * [facets attribute](https://www.algolia.com/doc/rest-api/search#param-facets) sent to algolia. + */ + disjunctiveFacets: string[]; + /** + * This attribute contains the list of all the hierarchical facets + * used. This list will be added to requested facets in the + * [facets attribute](https://www.algolia.com/doc/rest-api/search#param-facets) sent to algolia. + * Hierarchical facets are a sub type of disjunctive facets that + * let you filter faceted attributes hierarchically. + */ + hierarchicalFacets: SearchParameters.HierarchicalFacet[]; + + // Refinements + /** + * This attribute contains all the filters that need to be + * applied on the conjunctive facets. Each facet must be properly + * defined in the `facets` attribute. + * + * The key is the name of the facet, and the `FacetList` contains all + * filters selected for the associated facet name. + * + * When querying algolia, the values stored in this attribute will + * be translated into the `facetFilters` attribute. + */ + facetsRefinements: { [facet: string]: SearchParameters.FacetList }; + /** + * This attribute contains all the filters that need to be + * excluded from the conjunctive facets. Each facet must be properly + * defined in the `facets` attribute. + * + * The key is the name of the facet, and the `FacetList` contains all + * filters excluded for the associated facet name. + * + * When querying algolia, the values stored in this attribute will + * be translated into the `facetFilters` attribute. + */ + facetsExcludes: { [facet: string]: SearchParameters.FacetList }; + /** + * This attribute contains all the filters that need to be + * applied on the disjunctive facets. Each facet must be properly + * defined in the `disjunctiveFacets` attribute. + * + * The key is the name of the facet, and the `FacetList` contains all + * filters selected for the associated facet name. + * + * When querying algolia, the values stored in this attribute will + * be translated into the `facetFilters` attribute. + */ + disjunctiveFacetsRefinements: { + [facet: string]: SearchParameters.FacetList; + }; + /** + * This attribute contains all the filters that need to be + * applied on the numeric attributes. + * + * The key is the name of the attribute, and the value is the + * filters to apply to this attribute. + * + * When querying algolia, the values stored in this attribute will + * be translated into the `numericFilters` attribute. + */ + numericRefinements: { [facet: string]: SearchParameters.OperatorList }; + /** + * This attribute contains all the tags used to refine the query. + * + * When querying algolia, the values stored in this attribute will + * be translated into the `tagFilters` attribute. + */ + tagRefinements: string[]; + /** + * This attribute contains all the filters that need to be + * applied on the hierarchical facets. Each facet must be properly + * defined in the `hierarchicalFacets` attribute. + * + * The key is the name of the facet, and the `FacetList` contains all + * filters selected for the associated facet name. The FacetList values + * are structured as a string that contain the values for each level + * separated by the configured separator. + * + * When querying algolia, the values stored in this attribute will + * be translated into the `facetFilters` attribute. + */ + hierarchicalFacetsRefinements: { + [facet: string]: SearchParameters.FacetList; + }; + + /* end implementation of PlainSearchParameters */ + + /** + * Implementation of regular search parameters, copied from algoliasearch.QueryParameters + * Ideally there'd be a way to automatically implement this interface, but that + * isn't possible. + */ + + /** + * Query string used to perform the search + * default: '' + * https://www.algolia.com/doc/api-reference/api-parameters/query/ + */ + query?: string; + /** + * Filter the query with numeric, facet or/and tag filters + * default: "" + * https://www.algolia.com/doc/api-reference/api-parameters/filters/ + */ + filters?: string; + /** + * A string that contains the list of attributes you want to retrieve in order to minimize the size of the JSON answer. + * default: * + * https://www.algolia.com/doc/api-reference/api-parameters/attributesToRetrieve/ + */ + attributesToRetrieve?: string[]; + /** + * List of attributes you want to use for textual search + * default: attributeToIndex + * https://www.algolia.com/doc/api-reference/api-parameters/restrictSearchableAttributes/ + */ + restrictSearchableAttributes?: string[]; + /** + * You can use facets to retrieve only a part of your attributes declared in attributesForFaceting attributes + * default: [] + * https://www.algolia.com/doc/api-reference/api-parameters/facets/ + */ + facets?: string[]; + /** + * Force faceting to be applied after de-duplication (via the Distinct setting). + * When using the distinct setting in combination with faceting, facet counts may be higher than expected. + * This is because the engine, by default, computes faceting before applying de-duplication (distinct). + * When facetingAfterDistinct is set to true, the engine calculates faceting after the de-duplication has been applied. + * default "" + * https://www.algolia.com/doc/api-reference/api-parameters/facetingAfterDistinct/ + */ + facetingAfterDistinct?: boolean; + /** + * Limit the number of facet values returned for each facet. + * default: 100 + * https://www.algolia.com/doc/api-reference/api-parameters/maxValuesPerFacet/ + */ + maxValuesPerFacet?: number; + /** + * Default list of attributes to highlight. If set to null, all indexed attributes are highlighted. + * default: null + * https://www.algolia.com/doc/api-reference/api-parameters/attributesToHighlight/ + */ + attributesToHighlight?: string[]; + /** + * Default list of attributes to snippet alongside the number of words to return + * default: null + * https://www.algolia.com/doc/api-reference/api-parameters/attributesToSnippet/ + */ + attributesToSnippet?: string[]; + /** + * Specify the string that is inserted before the highlighted parts in the query result + * default: + * https://www.algolia.com/doc/api-reference/api-parameters/highlightPreTag/ + */ + highlightPreTag?: string; + /** + * Specify the string that is inserted after the highlighted parts in the query result + * default: + * https://www.algolia.com/doc/api-reference/api-parameters/highlightPostTag/ + */ + highlightPostTag?: string; + /** + * String used as an ellipsis indicator when a snippet is truncated. + * default: … + * https://www.algolia.com/doc/api-reference/api-parameters/snippetEllipsisText/ + */ + snippetEllipsisText?: string; + /** + * If set to true, restrict arrays in highlights and snippets to items that matched the query at least partially else return all array items in highlights and snippets + * default: false + * https://www.algolia.com/doc/api-reference/api-parameters/restrictHighlightAndSnippetArrays/ + */ + restrictHighlightAndSnippetArrays?: boolean; + /** + * Pagination parameter used to select the number of hits per page + * default: 20 + * https://www.algolia.com/doc/api-reference/api-parameters/hitsPerPage/ + */ + hitsPerPage?: number; + /** + * Pagination parameter used to select the page to retrieve. + * default: 0 + * https://www.algolia.com/doc/api-reference/api-parameters/page/ + */ + page?: number; + /** + * Offset of the first hit to return + * default: null + * https://www.algolia.com/doc/api-reference/api-parameters/offset/ + */ + offset?: number; + /** + * Number of hits to return. + * default: null + * https://www.algolia.com/doc/api-reference/api-parameters/length/ + */ + length?: number; + /** + * The minimum number of characters needed to accept one typo. + * default: 4 + * https://www.algolia.com/doc/api-reference/api-parameters/minWordSizefor1Typo/ + */ + minWordSizefor1Typo?: number; + /** + * The minimum number of characters needed to accept two typo. + * fault: 8 + * https://www.algolia.com/doc/api-reference/api-parameters/minWordSizefor2Typos/ + */ + minWordSizefor2Typos?: number; + /** + * This option allows you to control the number of typos allowed in the result set: + * default: true + * 'true' The typo tolerance is enabled and all matching hits are retrieved + * 'false' The typo tolerance is disabled. All results with typos will be hidden. + * 'min' Only keep results with the minimum number of typos + * 'strict' Hits matching with 2 typos are not retrieved if there are some matching without typos. + * https://www.algolia.com/doc/api-reference/api-parameters/typoTolerance/ + */ + typoTolerance?: boolean; + /** + * If set to false, disables typo tolerance on numeric tokens (numbers). + * default: + * https://www.algolia.com/doc/api-reference/api-parameters/allowTyposOnNumericTokens/ + */ + allowTyposOnNumericTokens?: boolean; + /** + * If set to true, plural won't be considered as a typo + * default: false + * https://www.algolia.com/doc/api-reference/api-parameters/ignorePlurals/ + */ + ignorePlurals?: boolean; + /** + * List of attributes on which you want to disable typo tolerance + * default: [] + * https://www.algolia.com/doc/api-reference/api-parameters/disableTypoToleranceOnAttributes/ + */ + disableTypoToleranceOnAttributes?: string[]; + /** + * Search for entries around a given location + * default: "" + * https://www.algolia.com/doc/api-reference/api-parameters/aroundLatLng/ + */ + aroundLatLng?: string; + /** + * Search for entries around a given latitude/longitude automatically computed from user IP address. + * default: "" + * https://www.algolia.com/doc/api-reference/api-parameters/aroundLatLngViaIP/ + */ + aroundLatLngViaIP?: boolean; + /** + * Control the radius associated with a geo search. Defined in meters. + * default: null + * You can specify aroundRadius=all if you want to compute the geo distance without filtering in a geo area + * https://www.algolia.com/doc/api-reference/api-parameters/aroundRadius/ + */ + aroundRadius?: number | 'all'; + /** + * Control the precision of a geo search + * default: null + * https://www.algolia.com/doc/api-reference/api-parameters/aroundPrecision/ + */ + aroundPrecision?: number; + /** + * Define the minimum radius used for a geo search when aroundRadius is not set. + * default: null + * https://www.algolia.com/doc/api-reference/api-parameters/minimumAroundRadius/ + */ + minimumAroundRadius?: number; + /** + * Search entries inside a given area defined by the two extreme points of a rectangle + * default: null + * https://www.algolia.com/doc/api-reference/api-parameters/insideBoundingBox/ + */ + insideBoundingBox?: number[][]; + /** + * Selects how the query words are interpreted + * default: 'prefixLast' + * 'prefixAll' All query words are interpreted as prefixes. This option is not recommended. + * 'prefixLast' Only the last word is interpreted as a prefix (default behavior). + * 'prefixNone' No query word is interpreted as a prefix. This option is not recommended. + * https://www.algolia.com/doc/api-reference/api-parameters/queryType/ + */ + queryType?: 'prefixAll' | 'prefixLast' | 'prefixNone'; + /** + * Search entries inside a given area defined by a set of points + * defauly: '' + * https://www.algolia.com/doc/api-reference/api-parameters/insidePolygon/ + */ + insidePolygon?: number[][]; + /** + * This option is used to select a strategy in order to avoid having an empty result page + * default: 'none' + * 'lastWords' When a query does not return any results, the last word will be added as optional + * 'firstWords' When a query does not return any results, the first word will be added as optional + * 'allOptional' When a query does not return any results, a second trial will be made with all words as optional + * 'none' No specific processing is done when a query does not return any results + * https://www.algolia.com/doc/api-reference/api-parameters/removeWordsIfNoResults/ + */ + removeWordsIfNoResults?: + | 'none' + | 'lastWords' + | 'firstWords' + | 'allOptional'; + /** + * Enables the advanced query syntax + * default: false + * https://www.algolia.com/doc/api-reference/api-parameters/advancedSyntax/ + */ + advancedSyntax?: boolean; + /** + * A string that contains the comma separated list of words that should be considered as optional when found in the query + * default: [] + * https://www.algolia.com/doc/api-reference/api-parameters/optionalWords/ + */ + optionalWords?: string[]; + /** + * Remove stop words from the query before executing it + * default: false + * true|false: enable or disable stop words for all 41 supported languages; or + * a list of language ISO codes (as a comma-separated string) for which stop words should be enable + * https://www.algolia.com/doc/api-reference/api-parameters/removeStopWords/ + */ + removeStopWords?: boolean | string[]; + /** + * List of attributes on which you want to disable the computation of exact criteria + * default: [] + * https://www.algolia.com/doc/api-reference/api-parameters/disableExactOnAttributes/ + */ + disableExactOnAttributes?: string[]; + /** + * This parameter control how the exact ranking criterion is computed when the query contains one word + * default: attribute + * 'none': no exact on single word query + * 'word': exact set to 1 if the query word is found in the record + * 'attribute': exact set to 1 if there is an attribute containing a string equals to the query + * https://www.algolia.com/doc/api-reference/api-parameters/exactOnSingleWordQuery/ + */ + exactOnSingleWordQuery?: 'attribute' | 'none' | 'word'; + /** + * Specify the list of approximation that should be considered as an exact match in the ranking formula + * default: ['ignorePlurals', 'singleWordSynonym'] + * 'ignorePlurals': alternative words added by the ignorePlurals feature + * 'singleWordSynonym': single-word synonym (For example "NY" = "NYC") + * 'multiWordsSynonym': multiple-words synonym + * https://www.algolia.com/doc/api-reference/api-parameters/alternativesAsExact/ + */ + alternativesAsExact?: Array< + 'ignorePlurals' | 'singleWordSynonym' | 'multiWordsSynonym' + >; + /** + * If set to 1, enables the distinct feature, disabled by default, if the attributeForDistinct index setting is set. + * https://www.algolia.com/doc/api-reference/api-parameters/distinct/ + */ + distinct?: number | boolean; + /** + * If set to true, the result hits will contain ranking information in the _rankingInfo attribute. + * default: false + * https://www.algolia.com/doc/api-reference/api-parameters/getRankingInfo/ + */ + getRankingInfo?: boolean; + /** + * @deprecated Use `numericAttributesForFiltering` instead + * All numerical attributes are automatically indexed as numerical filters + * default: '' + * https://www.algolia.com/doc/api-reference/api-parameters/numericAttributesForFiltering/ + */ + numericAttributesToIndex?: string[]; + /** + * All numerical attributes are automatically indexed as numerical filters + * default: '' + * https://www.algolia.com/doc/api-reference/api-parameters/numericAttributesForFiltering/ + */ + numericAttributesForFiltering?: string[]; + /** + * @deprecated please use filters instead + * A string that contains the comma separated list of numeric filters you want to apply. + * https://www.algolia.com/doc/api-reference/api-parameters/numericFilters/ + */ + numericFilters?: string[]; + /** + * @deprecated + * + * Filter the query by a set of tags. + * Default: [] + * https://www.algolia.com/doc/api-reference/api-parameters/tagFilters/ + */ + tagFilters?: string[]; + /** + * Filter the query by a set of facets. + * Default: [] + * https://www.algolia.com/doc/api-reference/api-parameters/facetFilters/ + */ + facetFilters?: string[] | string[][]; + /** + * If set to false, this query will not be taken into account in the analytics feature. + * default true + * https://www.algolia.com/doc/api-reference/api-parameters/analytics/ + */ + analytics?: boolean; + /** + * If set to true, enables the Click Analytics feature + * default false + * https://www.algolia.com/doc/api-reference/api-parameters/clickAnalytics/ + */ + clickAnalytics?: boolean; + /** + * If set, tag your query with the specified identifiers + * default: [] + * https://www.algolia.com/doc/api-reference/api-parameters/analyticsTags/ + */ + analyticsTags?: string[]; + /** + * If set to false, the search will not use the synonyms defined for the targeted index. + * default: true + * https://www.algolia.com/doc/api-reference/api-parameters/synonyms/ + */ + synonyms?: boolean; + /** + * If set to false, words matched via synonym expansion will not be replaced by the matched synonym in the highlighted result. + * default: true + * https://www.algolia.com/doc/api-reference/api-parameters/replaceSynonymsInHighlight/ + */ + replaceSynonymsInHighlight?: boolean; + /** + * Configure the precision of the proximity ranking criterion + * default: 1 + * https://www.algolia.com/doc/api-reference/api-parameters/minProximity/ + */ + minProximity?: number; + + nbShards?: number; + userData?: string | object; + + /** + * https://www.algolia.com/doc/api-reference/api-parameters/sortFacetValuesBy/ + */ + sortFacetValuesBy?: 'count' | 'alpha'; + + /* end implementation of algoliasearch.QueryParameters */ + } + + namespace SearchParameters { + type FacetList = string[]; + + type HierarchicalFacet = { + name: string; + attributes: string[]; + separator: string; + }; + + type OperatorList = { + [k in Operator]?: Array; + }; + + type Operator = '=' | '>' | '>=' | '<' | '<=' | '!='; + } + + export class SearchResults + implements Omit, 'facets' | 'params'> { + /** + * query used to generate the results + */ + query: string; + /** + * The query as parsed by the engine given all the rules. + */ + parsedQuery: string; + /** + * all the records that match the search parameters. Each record is + * augmented with a new attribute `_highlightResult` + * which is an object keyed by attribute and with the following properties: + * - `value` : the value of the facet highlighted (html) + * - `matchLevel`: full, partial or none depending on how the query terms match + */ + hits: T[]; + /** + * index where the results come from + */ + index: string; + /** + * number of hits per page requested + */ + hitsPerPage: number; + /** + * total number of hits of this query on the index + */ + nbHits: number; + /** + * total number of pages with respect to the number of hits per page and the total number of hits + */ + nbPages: number; + /** + * current page + */ + page: number; + /** + * sum of the processing time of all the queries + */ + processingTimeMS: number; + /** + * The position if the position was guessed by IP. + * @example "48.8637,2.3615", + */ + aroundLatLng: string; + /** + * The radius computed by Algolia. + * @example "126792922", + */ + automaticRadius: string; + /** + * String identifying the server used to serve this request. + * @example "c7-use-2.algolia.net", + */ + serverUsed: string; + /** + * Boolean that indicates if the computation of the counts did time out. + * @deprecated + */ + timeoutCounts: boolean; + /** + * Boolean that indicates if the computation of the hits did time out. + * @deprecated + */ + timeoutHits: boolean; + + /** + * True if the counts of the facets is exhaustive + */ + exhaustiveFacetsCount: boolean; + + /** + * True if the number of hits is exhaustive + */ + exhaustiveNbHits: boolean; + + /** + * Contains the userData if they are set by a [query rule](https://www.algolia.com/doc/guides/query-rules/query-rules-overview/). + */ + userData: any[]; + + /** + * queryID is the unique identifier of the query used to generate the current search results. + * This value is only available if the `clickAnalytics` search parameter is set to `true`. + */ + queryID: string; + + /** + * disjunctive facets results + */ + disjunctiveFacets: SearchResults.Facet[]; + /** + * disjunctive facets results + */ + hierarchicalFacets: SearchResults.HierarchicalFacet[]; + + /** + * other facets results + */ + facets: SearchResults.Facet[]; + + _rawResults: algoliasearch.Response[]; + _state: SearchParameters; + + constructor(state: SearchParameters, results: algoliasearch.Response[]); + + /** + * Get a facet object with its name + * @deprecated + * @param name name of the faceted attribute + * @return the facet object + */ + getFacetByName(name: string): SearchResults.Facet; + + /** + * Get a the list of values for a given facet attribute. Those values are sorted + * refinement first, descending count (bigger value on top), and name ascending + * (alphabetical order). The sort formula can overridden using either string based + * predicates or a function. + * + * This method will return all the values returned by the Algolia engine plus all + * the values already refined. This means that it can happen that the + * `maxValuesPerFacet` [configuration](https://www.algolia.com/doc/rest-api/search#param-maxValuesPerFacet) + * might not be respected if you have facet values that are already refined. + * @param attribute attribute name + * @param opts configuration options. + * @param opts.sortBy + * When using strings, it consists of + * the name of the [FacetValue](#SearchResults.FacetValue) or the + * [HierarchicalFacet](#SearchResults.HierarchicalFacet) attributes with the + * order (`asc` or `desc`). For example to order the value by count, the + * argument would be `['count:asc']`. + * + * If only the attribute name is specified, the ordering defaults to the one + * specified in the default value for this attribute. + * + * When not specified, the order is + * ascending. This parameter can also be a function which takes two facet + * values and should return a number, 0 if equal, 1 if the first argument is + * bigger or -1 otherwise. + * + * The default value for this attribute `['isRefined:desc', 'count:desc', 'name:asc']` + * @return depending on the type of facet of + * the attribute requested (hierarchical, disjunctive or conjunctive) + * @example + * helper.on('results', function(content){ + * //get values ordered only by name ascending using the string predicate + * content.getFacetValues('city', {sortBy: ['name:asc']}); + * //get values ordered only by count ascending using a function + * content.getFacetValues('city', { + * // this is equivalent to ['count:asc'] + * sortBy: function(a, b) { + * if (a.count === b.count) return 0; + * if (a.count > b.count) return 1; + * if (b.count > a.count) return -1; + * } + * }); + * }); + */ + getFacetValues( + attribute: string, + opts: any + ): SearchResults.FacetValue[] | SearchResults.HierarchicalFacet; + + /** + * Returns the facet stats if attribute is defined and the facet contains some. + * Otherwise returns undefined. + * @param attribute name of the faceted attribute + * @return The stats of the facet + */ + getFacetStats(attribute: string): any; + + /** + * Returns all refinements for all filters + tags. It also provides + * additional information: count and exhausistivity for each filter. + * + * See the [refinement type](#Refinement) for an exhaustive view of the available + * data. + * + * @return all the refinements + */ + getRefinements(): SearchResults.Refinement[]; + } + + namespace SearchResults { + interface Facet { + name: string; + data: object; + stats: object; + } + + interface HierarchicalFacet { + name: string; + count: number; + path: string; + isRefined: boolean; + data: HierarchicalFacet[]; + } + + interface FacetValue { + name: string; + count: number; + isRefined: boolean; + isExcluded: boolean; + } + + interface Refinement { + type: 'numeric' | 'facet' | 'exclude' | 'disjunctive' | 'hierarchical'; + attributeName: string; + name: string; + numericValue: number; + operator: string; + count: number; + exhaustive: boolean; + } + } +} + +export = algoliasearchHelper; diff --git a/package.json b/package.json index e90a19a0c..fd0f70bd9 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "2.28.0", "description": "Helper for implementing advanced search features with algolia", "main": "index.js", + "types": "index.d.ts", "homepage": "https://community.algolia.com/algoliasearch-helper-js/", "scripts": { "watch": "watchify index.js -v -s algoliasearchHelper -o dist/algoliasearch.helper.js", @@ -36,6 +37,7 @@ "index.js" ], "devDependencies": { + "@types/algoliasearch": "^3.30.12", "algolia-frontend-components": "0.0.35", "algoliasearch": "3.32.0", "babel-core": "6.26.3", diff --git a/yarn.lock b/yarn.lock index 3360f8c2d..c7fab9895 100644 --- a/yarn.lock +++ b/yarn.lock @@ -283,6 +283,11 @@ "@types/istanbul-lib-coverage" "^2.0.0" "@types/yargs" "^12.0.9" +"@types/algoliasearch@^3.30.12": + version "3.30.12" + resolved "https://registry.yarnpkg.com/@types/algoliasearch/-/algoliasearch-3.30.12.tgz#3270ba642107f00cd743c29b8cae30c92a043dba" + integrity sha512-IiJ4/GP3NEFWZkZhF5/cPxIZNzAitLdZnMpo5KlWLcNL567LHDHG2NOZLwXzRrTuxNa1zmqZJKEDWHnw8kp3Ng== + "@types/babel-types@*", "@types/babel-types@^7.0.0": version "7.0.4" resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-7.0.4.tgz#bfd5b0d0d1ba13e351dff65b6e52783b816826c8"